x1ongzhu 6 éve
szülő
commit
499d7028d3

+ 26 - 16
android/app/src/main/AndroidManifest.xml

@@ -1,42 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.izouma.mobilecybergames">
     package="com.izouma.mobilecybergames">
 
 
-    <!-- The INTERNET permission is required for development. Specifically,
+    <!--
+     The INTERNET permission is required for development. Specifically,
          flutter needs it to communicate with the running application
          flutter needs it to communicate with the running application
          to allow setting breakpoints, to provide hot reload, etc.
          to allow setting breakpoints, to provide hot reload, etc.
     -->
     -->
-    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.CAMERA" />
-    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
-         calls FlutterMain.startInitialization(this); in its onCreate method.
-         In most cases you can leave this as-is, but you if you want to provide
-         additional functionality it is fine to subclass or reimplement
-         FlutterApplication and put your custom class here. -->
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
     <application
     <application
         android:name="io.flutter.app.FlutterApplication"
         android:name="io.flutter.app.FlutterApplication"
-        android:label="全民电竞"
-        android:icon="@mipmap/ic_launcher">
+        android:icon="@mipmap/ic_launcher"
+        android:label="全民电竞">
+        <service
+            android:name=".ScreenStreamService"
+            android:enabled="true"
+            android:exported="true"></service>
+
         <activity
         <activity
             android:name=".MainActivity"
             android:name=".MainActivity"
-            android:launchMode="singleTop"
-            android:theme="@style/LaunchTheme"
             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
             android:hardwareAccelerated="true"
             android:hardwareAccelerated="true"
+            android:launchMode="singleTop"
+            android:theme="@style/LaunchTheme"
             android:windowSoftInputMode="adjustResize">
             android:windowSoftInputMode="adjustResize">
-            <!-- This keeps the window background of the activity showing
+
+            <!--
+                 This keeps the window background of the activity showing
                  until Flutter renders its first frame. It can be removed if
                  until Flutter renders its first frame. It can be removed if
                  there is no splash screen (such as the default splash screen
                  there is no splash screen (such as the default splash screen
-                 defined in @style/LaunchTheme). -->
+                 defined in @style/LaunchTheme).
+            -->
             <meta-data
             <meta-data
                 android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                 android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                 android:value="true" />
                 android:value="true" />
+
             <intent-filter>
             <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
             </intent-filter>
         </activity>
         </activity>
     </application>
     </application>
-</manifest>
+
+</manifest>

+ 94 - 1
android/app/src/main/java/com/izouma/mobilecybergames/FloatWindowService.java

@@ -1,4 +1,97 @@
 package com.izouma.mobilecybergames;
 package com.izouma.mobilecybergames;
 
 
-public class FloatWindowService {
+import android.app.Service;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.os.Build;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.support.annotation.Nullable;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+
+public class FloatWindowService extends Service {
+    private WindowManager              windowManager;
+    private WindowManager.LayoutParams layoutParams;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        windowManager = (WindowManager) 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 = 500;
+        layoutParams.height = 100;
+        layoutParams.x = 300;
+        layoutParams.y = 300;
+    }
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//判断系统版本
+            if (Settings.canDrawOverlays(this)) {
+                Button button = new Button(getApplicationContext());
+                button.setText("我是个button窗口");
+                button.setBackgroundColor(Color.BLUE);
+                windowManager.addView(button, layoutParams);
+
+                button.setOnTouchListener(new FloatingOnTouchListener());
+            }
+        } else {
+            Button button = new Button(getApplicationContext());
+            button.setText("我是个button窗口");
+            button.setBackgroundColor(Color.BLUE);
+            windowManager.addView(button, layoutParams);
+
+            button.setOnTouchListener(new FloatingOnTouchListener());
+        }
+
+        return super.onStartCommand(intent, flags, startId);
+    }
+
+    private class FloatingOnTouchListener implements View.OnTouchListener {
+        private int x;
+        private int y;
+
+        @Override
+        public boolean onTouch(View view, MotionEvent event) {
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    x = (int) event.getRawX();
+                    y = (int) event.getRawY();
+                    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);
+                    break;
+                default:
+                    break;
+            }
+            return false;
+        }
+    }
 }
 }

+ 29 - 3
android/app/src/main/java/com/izouma/mobilecybergames/ScreenStreamPlugin.java

@@ -3,10 +3,16 @@ package com.izouma.mobilecybergames;
 import android.app.Activity;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Context;
 import android.content.Intent;
 import android.content.Intent;
+import android.graphics.PixelFormat;
 import android.media.projection.MediaProjectionManager;
 import android.media.projection.MediaProjectionManager;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Log;
+import android.view.Gravity;
 import android.view.View;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.Toast;
 import android.widget.Toast;
 
 
 import com.alivc.live.pusher.AlivcAudioAACProfileEnum;
 import com.alivc.live.pusher.AlivcAudioAACProfileEnum;
@@ -26,6 +32,8 @@ import io.flutter.plugin.common.MethodCall;
 import io.flutter.plugin.common.MethodChannel;
 import io.flutter.plugin.common.MethodChannel;
 import io.flutter.plugin.common.PluginRegistry;
 import io.flutter.plugin.common.PluginRegistry;
 
 
+import static android.content.Context.WINDOW_SERVICE;
+
 public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, PluginRegistry.ActivityResultListener {
 public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, PluginRegistry.ActivityResultListener {
     private static final String TAG                             = "ScreenStreamPlugin";
     private static final String TAG                             = "ScreenStreamPlugin";
     public static final  int    CAPTURE_PERMISSION_REQUEST_CODE = 0x1123;
     public static final  int    CAPTURE_PERMISSION_REQUEST_CODE = 0x1123;
@@ -77,7 +85,7 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
         }
         }
     }
     }
 
 
-    public boolean start() {
+    private boolean start() {
         if (started) {
         if (started) {
             mAlivcLivePusher.stopPush();
             mAlivcLivePusher.stopPush();
             return true;
             return true;
@@ -91,14 +99,32 @@ public class ScreenStreamPlugin implements MethodChannel.MethodCallHandler, Plug
         return false;
         return false;
     }
     }
 
 
-    public boolean stop() {
+    private void checkPermission() {
+        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();
+            }
+        } else {
+            showFloatWindow();
+        }
+    }
+
+    private void showFloatWindow() {
+        Intent intent = new Intent(registrar.context(), ScreenStreamService.class);
+        registrar.context().startService(intent);
+    }
+
+    private boolean stop() {
         if (mAlivcLivePusher != null && mAlivcLivePusher.isPushing()) {
         if (mAlivcLivePusher != null && mAlivcLivePusher.isPushing()) {
             mAlivcLivePusher.stopPush();
             mAlivcLivePusher.stopPush();
         }
         }
         return true;
         return true;
     }
     }
 
 
-    public void startPushWithoutSurface() {
+    private void startPushWithoutSurface() {
         mAlivcLivePusher = new AlivcLivePusher();
         mAlivcLivePusher = new AlivcLivePusher();
         try {
         try {
             mAlivcLivePusher.init(registrar.context(), mAlivcLivePushConfig);
             mAlivcLivePusher.init(registrar.context(), mAlivcLivePushConfig);

+ 14 - 2
android/app/src/main/java/com/izouma/mobilecybergames/ScreenStreamService.java

@@ -3,14 +3,26 @@ package com.izouma.mobilecybergames;
 import android.app.Service;
 import android.app.Service;
 import android.content.Intent;
 import android.content.Intent;
 import android.os.IBinder;
 import android.os.IBinder;
+import android.support.annotation.Nullable;
 
 
 public class ScreenStreamService extends Service {
 public class ScreenStreamService extends Service {
     public ScreenStreamService() {
     public ScreenStreamService() {
     }
     }
 
 
+    @Nullable
     @Override
     @Override
     public IBinder onBind(Intent intent) {
     public IBinder onBind(Intent intent) {
-        // TODO: Return the communication channel to the service.
-        throw new UnsupportedOperationException("Not yet implemented");
+        return null;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        return super.onStartCommand(intent, flags, startId);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
     }
     }
 }
 }