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。

// flutter
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”,移除该项配置,结果并没有用。

	<receiver
            android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
            android:enabled="true"
            android:exported="false" >
        </receiver>

        <service
            android:name="com.google.android.gms.measurement.AppMeasurementService"
            android:enabled="true"
            android:exported="false" />
        <service
            android:name="com.google.android.gms.measurement.AppMeasurementJobService"
            android:enabled="true"
            android:exported="false"
            android:permission="android.permission.BIND_JOB_SERVICE" />
        <service
            android:name="com.google.android.gms.auth.api.signin.RevocationBoundService"
            android:permission="com.google.android.gms.auth.api.signin.permission.REVOCATION_NOTIFICATION"
            android:exported="true" />
        <activity
            android:theme="@ref/0x01030010"
            android:name="com.google.android.gms.common.api.GoogleApiActivity"
            android:exported="false" />

尝试方案二

既然与gms,查看堆栈,找到对应的库,发现是play-services-measurement-impl中触发的,那就想办法移除这个库。
在这里插入图片描述

在app的gradle中,移除com.google.android.gms相关的库,我发现两个都有触发的可能性,所以都移除了。

configurations {
                all {
//                  // 重点是这个
                    exclude group: "com.google.android.gms", module: "play-services-measurement-sdk"
                    exclude group: "com.google.android.gms", module: "play-services-measurement-impl"
                }
            }

再次运行后,发现不会再出现由这两个库引起调用getInstallerPackageName方法了。
但在继续debug调试的过程,其他的gms库依然存在违规获取应用列表问题。如下图
在这里插入图片描述
我也play-services-measurement-basement库给移除掉,但移除后发现,app跑不起来。
继续debug调试的过程,又又又发现其他gms库也存在问题,在移除 play-services-measurement-sdk-api或play-services-measurement-api时,会白屏,并且提示错误,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@@20.0.0:1)

从这个错误,发现一点问题,好像与FirebaseAnalytics.getInstance的初始化有关,又去搜了一下google。android.gms.internal.measurement这个包有啥用,firebase官方文档还有真有这个类的介绍。
在这里插入图片描述

包含配置 Firebase Analytics 核心服务

顺着FirebaseAnalytics.getInstance去找问题,找到该方法的位置。
在这里插入图片描述
发现FirebaseAnalytics类是在com.google.android.gms:play-services-measurement-api库中引入,那也证实了FirebaseAnalytics与gms某些库有关联。

解决问题

找到FirebaseAnalytics.getInstance调用时机。
在这里插入图片描述
问题发生在FirebaseAnalytics初始化,FirebaseAnalytics.getInstance(context);
经过排查,发现在Flutter的插件FlutterFirebaseAnalyticsPlugin类中,在FlutterFirebaseAnalyticsPlugin被Flutter加载后,就执行了FirebaseAnalytics初始化方法,然后导致gms服务被加载,然后违规获取应用列表的行为。

只要修改firebase_analytics插件,等到用户同意后再执行。
github下载源码 基于v9.1.0分支

public class FlutterFirebaseAnalyticsPlugin
    implements FlutterFirebasePlugin, MethodCallHandler, FlutterPlugin {
  private FirebaseAnalytics analytics;
  private MethodChannel channel;
  private Context context;

  private void initInstance(BinaryMessenger messenger, Context context) {
  // 第1步:注释掉这个位置
//    analytics = FirebaseAnalytics.getInstance(context);
    this.context = context;
    String channelName = "plugins.flutter.io/firebase_analytics";
    channel = new MethodChannel(messenger, channelName);
    channel.setMethodCallHandler(this);
    FlutterFirebasePluginRegistry.registerPlugin(channelName, this);
  }

  /**
   * 第2步
   * 20220913自己加入一个方法,初始化
   */
  private void initFirebaseAnalytics(){
    if(this.context != null && this.analytics == null){
      Log.i("zzb", "初始化initFirebaseAnalytics");
      analytics = FirebaseAnalytics.getInstance(this.context);
    }
  }
  
  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    Task<?> methodCallTask;

    switch (call.method) {
      // 第3步,加入初始化方法,给flutter调用
      case "Analytics#initFirebaseAnalytics":
        initFirebaseAnalytics();
        return;
    }
  }
  
  private Task<Void> handleSetAnalyticsCollectionEnabled(final Map<String, Object> arguments) {
    return Tasks.call(
        cachedThreadPool,
        () -> {
          // 第4步,我偷懒,在handleSetAnalyticsCollectionEnabled方法进行初始化
          initFirebaseAnalytics();
          final Boolean enabled =
              (Boolean) Objects.requireNonNull(arguments.get(Constants.ENABLED));
          if(analytics != null){
            Log.i("zzb", "执行analytics handleSetAnalyticsCollectionEnabled");
            analytics.setAnalyticsCollectionEnabled(enabled);
          }
          return null;
        });
  }
}

由于Flutter与原生进行通信使用firebase_analytics_platform_interface库,如果还要修改firebase_analytics_platform_interface库,就要维护两个库,firebase_analytics和firebase_analytics_platform_interface,不想修改这个库的内容。

所以偷懒的方式,把初始化方法,放在了现有的方法FlutterFirebaseAnalyticsPlugin.java的handleSetAnalyticsCollectionEnabled()中。
Flutter层需要调用一次FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true)来初始化analytics。

最后

Firebase实在太恶心了,在国内强烈不建议使用!!!firebase生态库相互唤起,出问题了很难定位。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Firebase应用内消息传递可以让你的Android应用实现实时通信和消息推送功能。下面是一些步骤来帮助你在Android应用上使用Firebase应用内消息传递: 1. 首先,在Firebase控制台中创建一个新的Firebase项目,并在项目设置中启用Firebase Cloud Messaging服务。 2. 在你的Android应用中,添加Firebase Core和Firebase Cloud Messaging依赖项。你可以通过Gradle文件来添加这些依赖项,例如: ``` implementation 'com.google.firebase:firebase-core:17.2.1' implementation 'com.google.firebase:firebase-messaging:20.0.0' ``` 3. 在你的AndroidManifest.xml文件中添加以下代码以注册Firebase Cloud Messaging服务: ``` <service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> ``` 4. 创建一个MyFirebaseMessagingService类并继承FirebaseMessagingService。在这个类中,你可以处理接收到的消息并执行相应的操作,例如: ``` public class MyFirebaseMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { // 处理接收到的消息 String message = remoteMessage.getData().get("message"); // 执行相应的操作 } } ``` 5. 最后,在你的应用中发送消息,你可以使用Firebase Cloud Messaging API来发送消息,例如: ``` FirebaseMessaging.getInstance().send(new RemoteMessage.Builder("SENDER_ID" + "@gcm.googleapis.com") .setMessageId(Integer.toString(msgId.incrementAndGet())) .addData("message", "这是一条测试消息") .build()); ``` 以上是在Android应用上使用Firebase应用内消息传递的一些基本步骤,你可以根据你的需求进行相关的配置和定制化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值