未启动的应用无法监听到系统广播

首先实现开机自启动:

第一步创建一个广播接收者,如MyBootBroadcastReceiver.java

package com.example;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;public class MyBootBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Intent startServiceIntent = new Intent(context, MyService.class);context.startService(startServiceIntent);}}

第二步给receiver配置对应intent-filter

<receiver android:name="MyBootBroadcastReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter> </receiver>

第三步添加权限,缺少这步则无法在Android 3.0及其之前版本上自启动

:name="android.permission.RECEIVE_BOOT_COMPLETED" />

上面的实现有以下【限制】:

1.由于Android系统在外置SD卡加载前广播ACTION_BOOT_COMPLETED,于是如果应用安装在外置SD卡上,它无法接收到此广播,原文见Broadcast Receivers listening for "boot completed"。

2.从Android 3.1(API level和对应NDK版本)开始,系统的包管理器保持跟踪处于停止状态(stopped state)的应用程序,提供了一种控制其从后台进程和其它应用程序启动的方式。这种停止状态的应用程序指那些安装了但从未启动过的apk,或被用户在程序管理中force stop的apk。Android系统为防止广播无意或不必要开启停止状态的组件,,它给所有广播intent添加了FLAG_EXCLUDE_STOPPED_PACKAGES标志(不设置和同FLAG_INCLUDE_STOPPED_PACKAGES一起设置结果都是此标志),

public boolean isExcludingStopped() {return (mFlags&(FLAG_EXCLUDE_STOPPED_PACKAGES|FLAG_INCLUDE_STOPPED_PACKAGES))== FLAG_EXCLUDE_STOPPED_PACKAGES;}

/*** Returns whether the object associated with the given filter is* "stopped," that is whether it should not be included in the result* if the intent requests to excluded stopped objects.*/protected boolean isFilterStopped(F filter, int userId) {return false;}private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,boolean debug, boolean defaultOnly,String resolvedType, String scheme, F[] src, List<R> dest, int userId) {…final boolean excludingStopped = intent.isExcludingStopped();final int N = src != null ? src.length : 0;boolean hasNonDefaults = false;int i;F filter;for (i=0; i<N && (filter=src[i]) != null; i++) {int match;if (debug) Slog.v(TAG, "Matching against filter " + filter);if (excludingStopped && isFilterStopped(filter, userId)) {if (debug) {Slog.v(TAG, " Filter’s target is stopped; skipping");}continue;}…

此标志指广播intent排除停止状态的应用,原文见Launch controls on stopped applications。用户可以给自己的应用或者后台服务添加FLAG_INCLUDE_STOPPED_PACKAGES标志以唤醒停止状态的应用,但系统自带的广播intent,用户无法修改,只能接受;注意系统级应用都不是停止状态。

中重写IntentResolver

final class ActivityIntentResolverextends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {…@Overrideprotected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {if (!sUserManager.exists(userId)) return true;PackageParser.Package p = filter.activity.owner;if (p != null) {PackageSetting ps = (PackageSetting)p.mExtras;if (ps != null) {(ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0&& ps.getStopped(userId);}}return false;}ServiceIntentResolverextends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {…@Overrideprotected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {if (!sUserManager.exists(userId)) return true;PackageParser.Package p = filter.service.owner;if (p != null) {PackageSetting ps = (PackageSetting)p.mExtras;if (ps != null) {(ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0&& ps.getStopped(userId);}}return false;}

人生没有彩排,只有现场直播,所以每一件事都要努力做得最好

未启动的应用无法监听到系统广播

相关文章:

你感兴趣的文章:

标签云: