首先實現開機自啟動:
第一步創建一個廣播接收者,如MyBootBroadcastReceiver.java
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
View Codepackage 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);//啟動應用//Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);//context.startActivity(intent);} }
第二步給receiver配置對應intent-filter
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
View Code<receiver android:name="MyBootBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
第三步添加權限,缺少這步則無法在Android 3.0及其之前版本上自啟動
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
View Code<uses-permission android: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添加了FL??AG_EXCLUDE_STOPPED_PACKAGES標志(不設置和同FLAG_INCLUDE_STOPPED_PACKAGES一起設置結果都是此標志),
Intent.java
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
View Codepublic boolean isExcludingStopped() {return (mFlags&(FLAG_EXCLUDE_STOPPED_PACKAGES|FLAG_INCLUDE_STOPPED_PACKAGES))== FLAG_EXCLUDE_STOPPED_PACKAGES;}
IntentResolver.java
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
View Code/*** 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,用戶無法修改,只能接受;注意系統級應用都不是停止狀態。
PackageManagerService.java中重寫IntentResolver
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
View Codefinal 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) {// System apps are never considered stopped for purposes of// filtering, because there may be no way for the user to// actually re-launch them.return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0&& ps.getStopped(userId);}}return false;}private final class 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) {// System apps are never considered stopped for purposes of// filtering, because there may be no way for the user to// actually re-launch them.return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0&& ps.getStopped(userId);}}return false;}
于是把apk安裝在root過的手機中的/system/app下面就能實現apk開機自啟動。
最后禁止開機自啟動,參考文章android手機root后的安全問題 (四)。