2 Commits 08c8eaaf89 ... 0869c4eeea

Author SHA1 Message Date
  gjh 0869c4eeea 在android原生代码里hook掉Flutter读取剪切板的方法,尝试解决隐私问题 1 week ago
  gjh 31488ff397 app启动时不再打印设备信息,因为会读取设备序列号,有隐私问题 1 week ago

+ 79 - 0
android/app/src/main/java/com/eitchsyh/instrument/eitc_erm_dental_flutter/HookFlutterClipBordUtil.java

@@ -0,0 +1,79 @@
1
+package com.eitchsyh.instrument.eitc_erm_dental_flutter;
2
+
3
+import java.lang.reflect.Field;
4
+import java.lang.reflect.InvocationHandler;
5
+import java.lang.reflect.Method;
6
+import java.lang.reflect.Proxy;
7
+
8
+import io.flutter.Log;
9
+import io.flutter.embedding.engine.FlutterEngine;
10
+import io.flutter.embedding.engine.systemchannels.PlatformChannel;
11
+
12
+/**
13
+ * File description.
14
+ * hook flutter输入框 自动调用getClipboardData 引起的合规问题
15
+ *
16
+ * @author lihongjun
17
+ * @date 10/13/21
18
+ */
19
+public class HookFlutterClipBordUtil
20
+{
21
+    /**
22
+     * 代理剪切板功能
23
+     *
24
+     * @param flutterEngine
25
+     */
26
+    public static void hookClipBoard(FlutterEngine flutterEngine)
27
+    {
28
+        Class IPlatformMessageHandler;
29
+        Field platformMessageHandlerField;
30
+        try
31
+        {
32
+            IPlatformMessageHandler = Class.forName(
33
+                    PlatformChannel.PlatformMessageHandler.class.getName());
34
+            platformMessageHandlerField = PlatformChannel.class.getDeclaredField(
35
+                    "platformMessageHandler");
36
+            platformMessageHandlerField.setAccessible(true);
37
+
38
+            // 拿到真实正常的实例,给不需要被hook的方法使用
39
+            PlatformChannel channel = flutterEngine.getPlatformChannel();
40
+            Object real = platformMessageHandlerField.get(channel);
41
+            // 代理PlatformMessageHandler的方法
42
+            platformMessageHandlerField.set(channel, Proxy.newProxyInstance(
43
+                    IPlatformMessageHandler.getClassLoader(), new Class[]{IPlatformMessageHandler},
44
+                    new IClipboardInvocationHandler(real)));
45
+
46
+        }
47
+        catch (Exception e)
48
+        {
49
+            Log.e("HookFlutterClipBordUtil", "hook异常", e);
50
+        }
51
+    }
52
+
53
+    public static class IClipboardInvocationHandler implements InvocationHandler
54
+    {
55
+        // 真是的调用方,如果不是获取剪切板 正常调用功能
56
+        private Object real;
57
+
58
+        public IClipboardInvocationHandler(Object real)
59
+        {
60
+            this.real = real;
61
+        }
62
+
63
+        @Override
64
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
65
+        {
66
+            //Log.d("test=====",method.getName());
67
+            // flutter输入框会调用获取剪切板 合规问题屏蔽掉
68
+            if ("clipboardHasStrings".equals(method.getName()))
69
+            {
70
+                return false;
71
+            }
72
+            else if ("getClipboardData".equals(method.getName()))
73
+            {
74
+                return "";
75
+            }
76
+            return method.invoke(real, args);
77
+        }
78
+    }
79
+}

+ 1 - 0
android/app/src/main/java/com/eitchsyh/instrument/eitc_erm_dental_flutter/MainActivity.java

@@ -23,6 +23,7 @@ public class MainActivity extends FlutterActivity implements
23 23
         super.configureFlutterEngine(flutterEngine);
24 24
         this.videoController = new VideoController(this.getApplicationContext(), flutterEngine);
25 25
         this.fileController = new FileController(this.getApplicationContext(), flutterEngine, this);
26
+        HookFlutterClipBordUtil.hookClipBoard(flutterEngine);
26 27
     }
27 28
 
28 29
     @Override

+ 0 - 10
lib/main.dart

@@ -1,7 +1,4 @@
1
-import 'dart:io';
2
-
3 1
 import 'package:bot_toast/bot_toast.dart';
4
-import 'package:device_info_plus/device_info_plus.dart';
5 2
 import 'package:eitc_erm_dental_flutter/db_util.dart';
6 3
 import 'package:eitc_erm_dental_flutter/funcs.dart';
7 4
 import 'package:eitc_erm_dental_flutter/sp_util.dart';
@@ -45,12 +42,6 @@ Future _initSettings() async {
45 42
   await initLog();
46 43
 
47 44
   PackageInfo packageInfo = await PackageInfo.fromPlatform();
48
-  BaseDeviceInfo? deviceInfo;
49
-  if (Platform.isAndroid) {
50
-    deviceInfo = await DeviceInfoPlugin().androidInfo;
51
-  } else if (Platform.isIOS) {
52
-    deviceInfo = await DeviceInfoPlugin().iosInfo;
53
-  }
54 45
   logd("""
55 46
     ====================app启动====================
56 47
     appName=${packageInfo.appName}
@@ -58,7 +49,6 @@ Future _initSettings() async {
58 49
     packageName=${packageInfo.packageName}
59 50
     version=${packageInfo.version}
60 51
     buildNumber=${packageInfo.buildNumber}
61
-    deviceInfo=${deviceInfo?.data ?? "none"}
62 52
     ==============================================
63 53
    """);
64 54