【问题标题】:How to use implicit broadcast PACKAGE_ADDED in Oreo (8.0)?如何在 Oreo (8.0) 中使用隐式广播 PACKAGE_ADDED?
【发布时间】:2018-03-19 12:09:57
【问题描述】:

我必须接收系统发送的隐式广播 (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 明确我的接收者。我怎样才能做到这一点?示例代码将不胜感激。

【问题讨论】:

  • Oreo 8.0 版已弃用此功能。
  • 看看this
  • 第 1 步:创建前景 Service。步骤#2:在该服务的onCreate() 中,调用registerReceiver(),传入BroadcastReceiver 的一个实例。步骤#3:安排在适当的时候启动该服务。但是,除非您可以证明用户始终保持服务运行是合理的,否则使用我在 the answer that Hemant linked to 的评论中提到的轮询方法是一种更可持续的解决方案。
  • @CommonsWare,如果我要在我的应用程序运行时使用这个接收器,我如何以编程方式注册ACTION_PACKAGE_ADDED?无需经常收听此事件。
  • 致电registerReceiver() 联系Context。我不知道“当我的应用程序运行时”究竟是什么意思。如果您的意思是“当我的进程碰巧因其他原因运行时”,您可以创建一个自定义的Application 子类,让它在其onCreate() 中调用registerReceiver(),并通过android:name 注册Application在清单中的 &lt;application&gt; 元素上。

标签: java android broadcastreceiver


【解决方案1】:

我决定创建一个简单的服务来监听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>

【讨论】:

  • 请注意,这仅在您的应用程序处于前台时才有效。 > 当应用程序处于空闲状态时,它对后台服务的使用会受到限制。 > 当一个应用程序进入后台时,它有一个几分钟的窗口,在这个窗口中仍然允许它创建和使用服务。在该窗口结束时,应用程序被认为是空闲的。这时,系统会停止应用程序的后台服务,就像应用程序调用了服务的 Service.stopSelf() 方法一样。参考:developer.android.com/about/versions/oreo/background
  • @avelyne,如果我让我的服务不朽呢?如果它要被销毁,它会重新创建自己。
  • 我不确定你是如何实现在服务被销毁时重新创建服务的逻辑。但是,如果该重新启动逻辑不被视为“前台”,那么您的应用程序将崩溃,并出现一些异常,表明您不允许从后台启动服务。要检查组件是否被视为“前景”,请参阅:developer.android.com/about/versions/oreo/background#services
  • @avelyne 我有相反的问题。 ForegroundService 可防止待机并耗尽电池电量。由于应用程序不会在待机状态下安装,因此该服务应该允许它发生并在手机从待机状态恢复时恢复为活动状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多