1.1 實現 Android 系統的自啟動
1.1.1.實現自己的廣播接收器,在 onReceive()方法中實現要處理的邏輯
1.1.2. AndroidManifest.xml 中注冊該廣播接收器,申明接收廣播過濾器為Boot_Completed 廣播
1.1.3.申明權限
實現 Android 的自啟動與一般的廣播接收沒有很大區別,但是有一些要注意的地方:
1.在使用 BOOT_COMPLETED 廣播時,必須要 RECEIVE_BOOT_COMPLETED 權限,這是 4.0 後的修改
2.通過指定 priority 屬性可以設置 BOOT_COMPLETED 廣播的優先級,讓該app 早於其他 app 接收到廣播
3.在 4.4 下 BOOT_COMPLETED 廣播是有序廣播,但是不可中斷(指定了FLAG_RECEIVER_NO_ABORT 字段),而在 4.4 以前,BOOT_COMPLETED 廣播
是無序的4.由於 4.0 後增加了 Package stopped 標志,因此處於該狀態下的 app 無法收到 BOOT_COMPLETED 廣播時,該狀態由以下情況產生:
a. 通過反射調用隱藏接口 forceStopPackage 接口停止的應用
b.在 setting?application?detail 中點 disable 按鈕,被停用的應用
c.新安裝完成,從未打開和運行過的應用
1.2 BOOT_COMPLETED 廣播發送的時機
要了解 BOOT_COMPLETED 廣播的發送時機就必須了解 Android 的啟動流程,
簡要了解 Android 的啟動順序:
1 系統啟動,bootloader
2 SystemServer
3 AMS
4 Send systemReady 信號
5 Launcher start
6 Send finishBooting 信號
7 發送 BOOT_COMPLETED 廣播
1.3 禁止自啟動的原理
通過了解 BOOT_COMPLETED 廣播發送的時機和原理,我們大概可以分析出禁止自啟動的幾種方法:
1. 阻止應用收到 BOOT_COMPLETED 廣播,在 4.0 以後,可以通過設置 app 的Package stopped 標志來實現(反射調用隱藏的 forceStopPackage 方法)
2. 通過停用應用的廣播接收器來屏蔽 BOOT_COMPLETED 廣播,即設置組件的android:enable 屬性來停止該接收器的響應
3. 通過 kill 進程來將自啟動的 app 結束掉
1.4 禁止自啟動的方法
1.4.1 forceStopPackage
通過 forceStopPackage 去禁用,不僅會停用 app 的組件,也會停止他的定時器等,同時需要 system 權限和系統簽名。
1.4.2 停用組件方法
Android 文檔中對 Android 的組件有如下描述:
The element has its own enabled attribute that applies to allapplication components, including broadcast receivers.
即我們可以設置一個組件是否啟用。
PackageManager 中提供以下兩個方法:
setApplicationEnabledSetting 可以停用應用中所有的組件。
setComponentEnabledSetting 可以停用指定的組件。
該方法有以下幾個需要注意的地方:
a.與 forceStopPackage 接口相比,該接口不會清空定時器等,只會啟用、停用組件,因此在定時器中發送自定義廣播,並且在廣播中指定FLAG_EXCLUDE_STOPPED_PACKAGES 是可以喚醒組件。
b.使用 setComponentEnabledSetting 接口必須是 system 程序並具有system 簽名
c.需要申明 CHANGE_COMPONENT_ENABLED_STATE 權限
使用方法:
很遺憾,該方法只能對自己的 app 修改,而操作第三方 app 需要 system權限,即使 root 也無法使用,因此,我們需要利用 packagemanager 的cmd 實現,即 PM 命令。
命令需要 root 權限:pm enable/disable package/package.class
1.4.3 Kill 進程方法
最常用的方法是通過 ActivityManager 類中的killBackgroundProcesses 接口來殺死進程,通用代碼如下:
但是該方法清理的進程等級不是太高,killProcess(pid)是一種能 kill更高優先級的方法,但是該方法並不能保證進程被 kill,因為該方法只是發出 kill process 的信號,具體是否要 kill 是由系統決定的,一般來說,可以被殺死的進程如下:
a. 同包下進程
b. 同 uid 進程
c. 由本 app 在運行時生成的進程
1.5 查找開機啟動權限的 apk
查找權限的方法有很多,這裡只提供一種,即通過 packagemnager 來實現:
1.6 總結
綜上,市場上一般的自啟動管理 app,大多是通過獲取 root 權限後使用 pm命令來禁用包含 Boot_Completed 的接收器來實現的,還有一些則是通過監控後台進程,輪詢查找黑名單中的進程來 kill 掉相應的自啟動程序,不僅包括開機自啟動,還可以監控後台自啟動,不過該方法的最大問題就是增加了系統消耗,包括內存消耗和電量消耗。另外還有一些第三方的 ROM 也帶有權限管理工具,例如小米的權限管理系統,是在解析接收器的權限的時候,會將所有接收器的優先級減 1,這樣其他應用的優先級將永遠低於其系統 app 的優先級。
通過調查發現,用戶清理進程,控制開機啟動的習慣是從 windows 開始的,進程清理或者說是控制開機啟動項對於 Android 系統來說並沒有很大意義,如果一個 Android 系統不 root,那麼第三方 app 對系統方面的控制權限基本沒有,使用這些軟件,一方面降低了 Android 系統的安全性,另一方面也會消耗很大的系統資源,造成惡性循環,手機越用越慢。