談到如何實現程序的開機自啟動,我想大多數朋友都會認為小菜一碟,不就是注冊一個BOOT_COMPLETED消息嘛!
在AndroidManifest.xml裡面加入一個receiver,就像這樣:
<SPAN style="FONT-SIZE: 18px"> <receiver android:name="BootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="com.android.settings.MAIL_SENT"/> </intent-filter> </receiver></SPAN>
但是很不幸,這個只在android 2.3及更老的版本中有效,在新版本的android系統中,這種方法是無法保證開機自動啟的。
首先看看google的官方文檔:
<SPAN style="FONT-SIZE: 18px">Launch controls on stopped applications Starting from Android 3.1, the system's package manager keeps track of applications that are in a stopped state and provides a means of controlling their launch from background processes and other applications. Note that an application's stopped state is not the same as an Activity's stopped state. The system manages those two stopped states separately. The platform defines two new intent flags that let a sender specify whether the Intent should be allowed to activate components in stopped application. FLAG_INCLUDE_STOPPED_PACKAGES — Include intent filters of stopped applications in the list of potential targets to resolve against. FLAG_EXCLUDE_STOPPED_PACKAGES — Exclude intent filters of stopped applications from the list of potential targets. When neither or both of these flags is defined in an intent, the default behavior is to include filters of stopped applications in the list of potential targets. Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents. It does this to prevent broadcasts from background services from inadvertently or unnecessarily launching components of stoppped applications. A background service or application can override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES flag to broadcast intents that should be allowed to activate stopped applications. Applications are in a stopped state when they are first installed but are not yet launched and when they are manually stopped by the user (in Manage Applications).</SPAN>
上面的文檔主要講了一下幾點:
1、android 3.1中有一類package 叫做stopped package, 它們就是那種安裝了但是從來沒有啟動過的apk,或者被用戶在程序管理裡面force stop了的apk
2、intent中新加了一組flag(FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES),帶有FLAG_INCLUDE_STOPPED_PACKAGES的 intent對stopped package是不起作用的。
3、系統對所有的廣播intent都加了flag:FLAG_EXCLUDE_STOPPED_PACKAGES,當然boot complete廣播也不例外。
看完這3點,大家應該知道為什麼我在前面說:注冊靜態receiver無法保證app開機自動啟。
原因很簡單,如果我的apk安裝到手機後,一直都沒有被用戶啟動過(或者被force stop過),那麼它就是一個stopped package,boot_complete廣播是無法將其拉起的。
這裡需要注意一點: /system/app下面的apk都是非 stopped package。所以如果你的手機root了,那就另當別論了,你可以把apk push到system/app,但是這個安裝方式不是正常安裝方式了。
所以朋友們如果碰到apk無法開機自動啟,請不必苦惱,先看看你的android 版本吧。
android為什麼要加入這一機制呢?
很明顯是出於安全考慮,因為開機自啟動是病毒程序的慣用方式,這個機制可以在一定程度上防止病毒程序的開機自啟動。