如何在Oreo(8.0)中使用隐式广播PACKAGE_ADDED?

9

我需要接收系统发送的隐式广播(ACTION_PACKAGE_ADDED),以便检测应用程序的安装并执行一些代码。我使用了以下代码:

public class Receiver extends BroadcastReceiver{
   @Override
   public void onReceive(Context context, Intent intent) {
     // It will trigger when any app is installed           
        Uri data = intent.getData();
        String packageAdv = data.getEncodedSchemeSpecificPart();
     //some code...
   }
}

在我的 Manifest 文件中,我声明了我的接收器:
<receiver android:name="com.myapp.Receiver">
        <intent-filter>                    
           <action android:name="android.intent.action.PACKAGE_ADDED" />                        
           <data android:scheme="package"/> 
        </intent-filter>
</receiver> 

在8.0 Oreo版本之前,一切都正常运作。现在,我必须通过使用registerReceiver显式地注册我的接收器。我该怎么做?如果有示例代码将不胜感激。

版本8.0 Oreo已弃用此函数。 - KuLdip PaTel
1
请查看此链接:https://dev59.com/bKTja4cB1Zd3GeqPHtLT#45996525 - Hemant Parmar
步骤#1:创建前台“服务”。 步骤#2:在该服务的“onCreate()”中,调用“registerReceiver()”,并传入您的“BroadcastReceiver”的实例。 步骤#3:安排在适当时启动该服务。 但是,除非您可以向用户证明始终保持运行服务的合理性,否则使用我在Hemant链接的答案评论中提到的轮询方法是更可持续的解决方案。 - CommonsWare
@CommonsWare,像这样:Receiver r = new Receiver(); //继承自BroadcastReceiver类 IntentFilter i = new IntentFilter("android.intent.action.PACKAGE_ADDED"); i.addDataScheme("package"); ctx.registerReceiver(r, i); - Nolesh
@CommonsWare,好的。谢谢。我稍后会尝试一下。不幸的是,我没有奥利奥设备来检查它。但是我可以通过从“清单”中删除隐式接收器来在Lolipop上检查它。 - Nolesh
显示剩余3条评论
1个回答

3

我决定创建一个简单的服务,用于监听PACKAGE_ADDED事件。

public class MyService extends Service {
  private BroadcastReceiver receiver;

  public MyService() { }

  @Override
  public void onCreate() {
    IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
    intentFilter.addDataScheme("package");
    receiver = new Receiver();
    registerReceiver(receiver, intentFilter);
  }

  //ensure that we unregister the receiver once it's done.
  @Override
  public void onDestroy() {
    unregisterReceiver(receiver);
  }

  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }

}

此外,我需要在manifest文件中声明我的服务:
<service
    android:name="com.nolesh.myapp.MyService"
    android:enabled="true">
</service>

1
请注意,此功能仅在应用程序在前台运行时才有效。当应用程序处于空闲状态时,其使用后台服务的限制是有限的。 当应用程序进入后台时,它有几分钟的窗口期,在此期间仍被允许创建和使用服务。在该窗口期结束时,应用程序被视为处于空闲状态。此时,系统会停止应用程序的后台服务,就像应用程序调用了服务的 Service.stopSelf() 方法一样。参考:https://developer.android.com/about/versions/oreo/background - avelyne
@avelyne,如果我让我的服务不朽呢?如果它被销毁了,它会重新创建自己。 - Nolesh
1
我不确定你是如何实现重新创建服务逻辑的。但如果重启逻辑不被视为"前台",那么你的应用程序将崩溃,并出现一些异常,指出你不能从后台启动服务。要检查一个组件是否被视为"前台",请参考:https://developer.android.com/about/versions/oreo/background#services - avelyne
@avelyne 我有相反的问题。ForegroundService 防止待机并耗尽电池。由于应用程序不会在待机时安装,因此服务应允许其发生并在手机从待机状态返回时恢复活动状态。 - Giszmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接