|
|
@@ -1,8 +1,11 @@
|
|
|
package com.izouma.mobilecybergames;
|
|
|
|
|
|
import android.app.Activity;
|
|
|
+import android.content.BroadcastReceiver;
|
|
|
import android.content.Context;
|
|
|
import android.content.Intent;
|
|
|
+import android.content.IntentFilter;
|
|
|
+import android.graphics.Color;
|
|
|
import android.graphics.PixelFormat;
|
|
|
import android.media.projection.MediaProjectionManager;
|
|
|
import android.net.Uri;
|
|
|
@@ -11,8 +14,10 @@ import android.provider.Settings;
|
|
|
import android.text.TextUtils;
|
|
|
import android.util.Log;
|
|
|
import android.view.Gravity;
|
|
|
+import android.view.MotionEvent;
|
|
|
import android.view.View;
|
|
|
import android.view.WindowManager;
|
|
|
+import android.widget.Button;
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
import com.alivc.live.pusher.AlivcAudioAACProfileEnum;
|
|
|
@@ -36,7 +41,8 @@ import static android.content.Context.WINDOW_SERVICE;
|
|
|
|
|
|
public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, PluginRegistry.ActivityResultListener {
|
|
|
private static final String TAG = "ScreenStreamPlugin";
|
|
|
- public static final int CAPTURE_PERMISSION_REQUEST_CODE = 0x1123;
|
|
|
+ private static final int CAPTURE_PERMISSION_REQUEST_CODE = 0x1123;
|
|
|
+ private static final int FLOATING_WINDOW_REQUEST_CODE = 0x1124;
|
|
|
|
|
|
private final PluginRegistry.Registrar registrar;
|
|
|
|
|
|
@@ -46,6 +52,10 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
|
|
|
private String url;
|
|
|
private MethodChannel.Result result;
|
|
|
|
|
|
+ private WindowManager windowManager;
|
|
|
+ private WindowManager.LayoutParams layoutParams;
|
|
|
+ private Button floatButton;
|
|
|
+
|
|
|
public static void registerWith(PluginRegistry.Registrar registrar) {
|
|
|
final MethodChannel channel = new MethodChannel(registrar.messenger(), "screen_stream");
|
|
|
MethodChannel.MethodCallHandler methodCallHandler = new ScreenStreamPlugin(registrar);
|
|
|
@@ -55,6 +65,20 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
|
|
|
|
|
|
public ScreenStreamPlugin(PluginRegistry.Registrar registrar) {
|
|
|
this.registrar = registrar;
|
|
|
+ this.registrar.context().registerReceiver(new BroadcastReceiver() {
|
|
|
+ @Override
|
|
|
+ public void onReceive(Context context, Intent intent) {
|
|
|
+ if ("onResume".equals(intent.getStringExtra("event"))) {
|
|
|
+ if (floatButton != null) {
|
|
|
+ floatButton.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ } else if ("onPause".equals(intent.getStringExtra("event"))) {
|
|
|
+ if (floatButton != null) {
|
|
|
+ floatButton.setVisibility(View.VISIBLE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, new IntentFilter(MainActivity.APP_LIFECYCLE_ACTION));
|
|
|
AlivcLivePushConfig.setMediaProjectionPermissionResultData(null);
|
|
|
mAlivcLivePushConfig = new AlivcLivePushConfig();//初始化推流配置类
|
|
|
mAlivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_720P);//分辨率540P,最大支持720P
|
|
|
@@ -63,6 +87,21 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
|
|
|
mAlivcLivePushConfig.setPreviewOrientation(AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_RIGHT); // 默认为竖屏,可设置home键向左或向右横屏。
|
|
|
mAlivcLivePushConfig.setAudioProfile(AlivcAudioAACProfileEnum.AAC_LC);//设置音频编码模式
|
|
|
mAlivcLivePushConfig.setEnableBitrateControl(true);// 打开码率自适应,默认为true
|
|
|
+
|
|
|
+ windowManager = (WindowManager) this.registrar.context().getSystemService(WINDOW_SERVICE);
|
|
|
+ layoutParams = new WindowManager.LayoutParams();
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
+ layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
|
|
+ } else {
|
|
|
+ layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
|
|
|
+ }
|
|
|
+ layoutParams.format = PixelFormat.RGBA_8888;
|
|
|
+ layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
|
|
|
+ layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
|
|
+ layoutParams.width = 200;
|
|
|
+ layoutParams.height = 100;
|
|
|
+ layoutParams.x = 300;
|
|
|
+ layoutParams.y = 300;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -82,6 +121,14 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
|
|
|
} else if ("stop".equals(methodCall.method)) {
|
|
|
stop();
|
|
|
result.success("success");
|
|
|
+ } else if ("checkPermission".equals(methodCall.method)) {
|
|
|
+ if (checkPermission()) {
|
|
|
+ result.success(true);
|
|
|
+ } else {
|
|
|
+ result.success(false);
|
|
|
+ }
|
|
|
+ } else if ("requestPermission".equals(methodCall.method)) {
|
|
|
+ requestPermission();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -99,22 +146,44 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- private void checkPermission() {
|
|
|
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//判断系统版本
|
|
|
+ private boolean checkPermission() {
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ return Settings.canDrawOverlays(registrar.context());
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void requestPermission() {
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
if (!Settings.canDrawOverlays(registrar.context())) {
|
|
|
- Toast.makeText(registrar.activity(), "当前无权限,请授权", Toast.LENGTH_SHORT).show();
|
|
|
- registrar.activity().startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + registrar.context().getPackageName())), 0);
|
|
|
- } else {
|
|
|
- showFloatWindow();
|
|
|
+ registrar.activity().startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + registrar.context().getPackageName())), FLOATING_WINDOW_REQUEST_CODE);
|
|
|
+ return;
|
|
|
}
|
|
|
- } else {
|
|
|
- showFloatWindow();
|
|
|
}
|
|
|
+ result.success(true);
|
|
|
}
|
|
|
|
|
|
private void showFloatWindow() {
|
|
|
- Intent intent = new Intent(registrar.context(), ScreenStreamService.class);
|
|
|
- registrar.context().startService(intent);
|
|
|
+ if (floatButton != null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//判断系统版本
|
|
|
+ if (Settings.canDrawOverlays(registrar.context())) {
|
|
|
+ floatButton = new Button(registrar.context().getApplicationContext());
|
|
|
+ floatButton.setText("CLICK ME!");
|
|
|
+ floatButton.setBackgroundColor(Color.LTGRAY);
|
|
|
+ floatButton.setVisibility(View.GONE);
|
|
|
+ windowManager.addView(floatButton, layoutParams);
|
|
|
+ floatButton.setOnTouchListener(new FloatingOnTouchListener());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ floatButton = new Button(registrar.context().getApplicationContext());
|
|
|
+ floatButton.setText("CLICK ME!");
|
|
|
+ floatButton.setBackgroundColor(Color.LTGRAY);
|
|
|
+ floatButton.setVisibility(View.GONE);
|
|
|
+ windowManager.addView(floatButton, layoutParams);
|
|
|
+ floatButton.setOnTouchListener(new FloatingOnTouchListener());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private boolean stop() {
|
|
|
@@ -125,6 +194,7 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
|
|
|
}
|
|
|
|
|
|
private void startPushWithoutSurface() {
|
|
|
+ showFloatWindow();
|
|
|
mAlivcLivePusher = new AlivcLivePusher();
|
|
|
try {
|
|
|
mAlivcLivePusher.init(registrar.context(), mAlivcLivePushConfig);
|
|
|
@@ -294,8 +364,60 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
|
|
|
result.error("needs permission", "permission not granted", null);
|
|
|
}
|
|
|
}
|
|
|
+ case FLOATING_WINDOW_REQUEST_CODE: {
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ if (!Settings.canDrawOverlays(registrar.context())) {
|
|
|
+ if (result != null) {
|
|
|
+ result.success(false);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (result != null) {
|
|
|
+ result.success(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ private class FloatingOnTouchListener implements View.OnTouchListener {
|
|
|
+ private int x;
|
|
|
+ private int y;
|
|
|
+ private long ts;
|
|
|
+ boolean moved = false;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean onTouch(View view, MotionEvent event) {
|
|
|
+ switch (event.getAction()) {
|
|
|
+ case MotionEvent.ACTION_DOWN:
|
|
|
+ x = (int) event.getRawX();
|
|
|
+ y = (int) event.getRawY();
|
|
|
+ ts = System.currentTimeMillis();
|
|
|
+ moved = false;
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_MOVE:
|
|
|
+ int nowX = (int) event.getRawX();
|
|
|
+ int nowY = (int) event.getRawY();
|
|
|
+ int movedX = nowX - x;
|
|
|
+ int movedY = nowY - y;
|
|
|
+ x = nowX;
|
|
|
+ y = nowY;
|
|
|
+ layoutParams.x = layoutParams.x + movedX;
|
|
|
+ layoutParams.y = layoutParams.y + movedY;
|
|
|
+ windowManager.updateViewLayout(view, layoutParams);
|
|
|
+ moved = true;
|
|
|
+ break;
|
|
|
+ case MotionEvent.ACTION_UP:
|
|
|
+ if (System.currentTimeMillis() - ts < 300) {
|
|
|
+ registrar.context().startActivity(new Intent(registrar.context(), MainActivity.class));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|