作者:晨曦--雨荷 | 来源:互联网 | 2023-07-15 18:03
文章目录系列文章背景依赖环境解决方案堆栈信息分析问题尝试方案一尝试方案二解决问题最后系列文章android使用ContentProvider初始化sdk,初始化时机
文章目录
- 系列文章
- 背景
- 依赖环境
- 解决方案
- 堆栈信息
- 分析问题
- 解决问题
- 最后
系列文章
- android使用ContentProvider初始化sdk,初始化时机
- Android ContentProvider初始化流程简化分析
- Android-Firebase快速解决合规问题第1篇,汇总篇,一步解决问题
- Android-Firebase快速解决合规问题第2篇,解决FirebasePerformance库获取软件安装列表的行为
- Android-Firebase快速解决合规问题第3篇,解决FirebaseCrashlytics库违规网络请求、获取AndroidId问题
- Android-Firebase快速解决合规问题第4篇,解决FirebaseAnalytics库违规获取应用列表问题
背景
2022年9月,小米应用商店上架审核,提示存在违规行为。
违规行为:未经许可读取个人信息 | 获取应用列表
依赖环境
demo的环境如下,只是为了演示firebase出现的问题,本篇文章基于Flutter作为开发语言,实现了demo演示问题,原生库、RN库同理可以解决问题。
android版本:
build.gradle
compileSdkVersion 31
minSdkVersion 21
targetSdkVersion 31
futter版本:Flutter 2.10.5
pubspec.yaml
firebase_core: 1.10.0
firebase_messaging: 10.0.0
firebase_crashlytics: 2.2.0
firebase_analytics: 9.1.0
firebase_performance: 0.7.0+3
dio_firebase_performance: ^0.3.0
解决方案
修改firebase_analytics插件,
修改的源码,分支firebase_analytics-v9.1.0-20220913。
等到用户同意后再执行,flutter调用以下方法,就会初始化FirebaseAnalytics。
FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true)
堆栈信息
callstack:android.app.ApplicationPackageManager.getInstallerPackageName:2044;
com.google.android.gms.measurement.internal.e3.k:8;
com.google.android.gms.measurement.internal.c4.i:2;
com.google.android.gms.measurement.internal.y4.c:13;
com.google.android.gms.measurement.internal.x4.run:1;
java.util.concurrent.Executors$RunnableAdapter.call:458;
java.util.concurrent.FutureTask.run:266;
com.google.android.gms.measurement.internal.u4.run:6;
官方反馈的堆栈信息,看得莫名其妙。只好根据之前的定位问题的方式,找到栈顶方法,进行debug调试。
分析问题
从堆栈信息和debug断点模式来看,应用启动后就会执行到这,是gms(谷歌移动服务)发生的问题。那现在就要找到什么地方调用起来。
尝试方案一
根据之前的猜测可能是引入了gms相关的provider,自动初始化了。找到debug包中的AndroidManifest文件,查看有关的gms配置,我给每一项都加入tools:node=“remove”,移除该项配置,结果并没有用。
<receiverandroid:name&#61;"com.google.android.gms.measurement.AppMeasurementReceiver"android:enabled&#61;"true"android:exported&#61;"false" ></receiver><serviceandroid:name&#61;"com.google.android.gms.measurement.AppMeasurementService"android:enabled&#61;"true"android:exported&#61;"false" /><serviceandroid:name&#61;"com.google.android.gms.measurement.AppMeasurementJobService"android:enabled&#61;"true"android:exported&#61;"false"android:permission&#61;"android.permission.BIND_JOB_SERVICE" /><serviceandroid:name&#61;"com.google.android.gms.auth.api.signin.RevocationBoundService"android:permission&#61;"com.google.android.gms.auth.api.signin.permission.REVOCATION_NOTIFICATION"android:exported&#61;"true" /><activityandroid:theme&#61;"&#64;ref/0x01030010"android:name&#61;"com.google.android.gms.common.api.GoogleApiActivity"android:exported&#61;"false" />
尝试方案二
既然与gms&#xff0c;查看堆栈&#xff0c;找到对应的库&#xff0c;发现是play-services-measurement-impl中触发的&#xff0c;那就想办法移除这个库。
在app的gradle中&#xff0c;移除com.google.android.gms相关的库&#xff0c;我发现两个都有触发的可能性&#xff0c;所以都移除了。
configurations {all {
exclude group: "com.google.android.gms", module: "play-services-measurement-sdk"exclude group: "com.google.android.gms", module: "play-services-measurement-impl"}}
再次运行后&#xff0c;发现不会再出现由这两个库引起调用getInstallerPackageName方法了。
但在继续debug调试的过程&#xff0c;其他的gms库依然存在违规获取应用列表问题。如下图
我也play-services-measurement-basement库给移除掉&#xff0c;但移除后发现&#xff0c;app跑不起来。
继续debug调试的过程&#xff0c;又又又发现其他gms库也存在问题&#xff0c;在移除 play-services-measurement-sdk-api或play-services-measurement-api时&#xff0c;会白屏&#xff0c;并且提示错误,FirebaseAnalytics.getInstance初始化失败。实在无力吐槽了。
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/internal/measurement/zzee;at com.google.firebase.analytics.FirebaseAnalytics.getInstance(com.google.android.gms:play-services-measurement-api&#64;&#64;20.0.0:1)
从这个错误&#xff0c;发现一点问题&#xff0c;好像与FirebaseAnalytics.getInstance的初始化有关&#xff0c;又去搜了一下google。android.gms.internal.measurement这个包有啥用&#xff0c;firebase官方文档还有真有这个类的介绍。
包含配置 Firebase Analytics 核心服务
顺着FirebaseAnalytics.getInstance去找问题&#xff0c;找到该方法的位置。
发现FirebaseAnalytics类是在com.google.android.gms:play-services-measurement-api库中引入&#xff0c;那也证实了FirebaseAnalytics与gms某些库有关联。
解决问题
找到FirebaseAnalytics.getInstance调用时机。
问题发生在FirebaseAnalytics初始化&#xff0c;FirebaseAnalytics.getInstance(context);
经过排查&#xff0c;发现在Flutter的插件FlutterFirebaseAnalyticsPlugin类中&#xff0c;在FlutterFirebaseAnalyticsPlugin被Flutter加载后&#xff0c;就执行了FirebaseAnalytics初始化方法&#xff0c;然后导致gms服务被加载&#xff0c;然后违规获取应用列表的行为。
只要修改firebase_analytics插件&#xff0c;等到用户同意后再执行。
github下载源码 基于v9.1.0分支
public class FlutterFirebaseAnalyticsPluginimplements FlutterFirebasePlugin, MethodCallHandler, FlutterPlugin {private FirebaseAnalytics analytics;private MethodChannel channel;private Context context;private void initInstance(BinaryMessenger messenger, Context context) {
this.context &#61; context;String channelName &#61; "plugins.flutter.io/firebase_analytics";channel &#61; new MethodChannel(messenger, channelName);channel.setMethodCallHandler(this);FlutterFirebasePluginRegistry.registerPlugin(channelName, this);}private void initFirebaseAnalytics(){if(this.context !&#61; null && this.analytics &#61;&#61; null){Log.i("zzb", "初始化initFirebaseAnalytics");analytics &#61; FirebaseAnalytics.getInstance(this.context);}}&#64;Overridepublic void onMethodCall(&#64;NonNull MethodCall call, &#64;NonNull Result result) {Task<?> methodCallTask;switch (call.method) {case "Analytics#initFirebaseAnalytics":initFirebaseAnalytics();return;}}private Task<Void> handleSetAnalyticsCollectionEnabled(final Map<String, Object> arguments) {return Tasks.call(cachedThreadPool,() -> {initFirebaseAnalytics();final Boolean enabled &#61;(Boolean) Objects.requireNonNull(arguments.get(Constants.ENABLED));if(analytics !&#61; null){Log.i("zzb", "执行analytics handleSetAnalyticsCollectionEnabled");analytics.setAnalyticsCollectionEnabled(enabled);}return null;});}
}
由于Flutter与原生进行通信使用firebase_analytics_platform_interface库&#xff0c;如果还要修改firebase_analytics_platform_interface库&#xff0c;就要维护两个库&#xff0c;firebase_analytics和firebase_analytics_platform_interface&#xff0c;不想修改这个库的内容。
所以偷懒的方式&#xff0c;把初始化方法&#xff0c;放在了现有的方法FlutterFirebaseAnalyticsPlugin.java的handleSetAnalyticsCollectionEnabled()中。
Flutter层需要调用一次FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true)来初始化analytics。
最后
Firebase实在太恶心了&#xff0c;在国内强烈不建议使用&#xff01;&#xff01;&#xff01;firebase生态库相互唤起&#xff0c;出问题了很难定位。