有段時間做系統(tǒng)hook時需要用到系統(tǒng)重啟,找了幾種重啟的方法,還有幾種關(guān)機的方法,總結(jié)一下。
一,發(fā)送廣播
Broadcast,
Intent.ACTION_REQUEST_SHUTDOWN
關(guān)機廣播
Intent.ACTION_REBOOT
重啟廣播
ACTION_REQUEST和ACTION_REBOOT是Intent.java是聲明的兩個字符串常量,系統(tǒng)接收到這兩個廣播后就會響應(yīng)關(guān)機或重啟的操作。
源碼中的實現(xiàn)如下:
聲明代碼路徑:/frameworks/base/core/java/android/content/Intent.java
public static final String ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN"
public static final String ACTION_REBOOT = "android.intent.action.REBOOT"
實現(xiàn)代碼示例:
廣播關(guān)機
廣播重啟
權(quán)限:
- AndroidMenifest.xml中添加代碼
android:sharedUserId="android.uid.system"
提升至系統(tǒng)權(quán)限
<uses-permission android:name="android.permission.SHUTDOWN" />
添加關(guān)機權(quán)限 - 需要在源碼中編譯項目,所以需要在項目根目錄下添加Android.mk文件:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := PowerActionDemo
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
二,通過init.rc啟動系統(tǒng)服務(wù)來運行sh文件
Android文件系統(tǒng)啟動后首先調(diào)用/init,init文件會解析init.rc和init.xxx.rc然后執(zhí)行,init.rc會在系統(tǒng)初始化過程中做一些簡單的初始化操作,可以利用init過程解析自己加進去的關(guān)機或重啟腳本。
- 編寫關(guān)機或重啟腳本sh文件
#!/system/bin/sh
reboot
#!/system/bin/sh
reboot -p #或者shutdown
- 編寫mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PREBUILT_EXECUTABLES := system_shutdown.sh system_reboot.sh
LOCAL_MODULE_TAGS := optional
include $(BUILD_MULTI_PREBUILT)
- 修改init.rc文件,在文件最后添加如下:
service system_shutdown /system/bin/system_shutdown.sh #第一步中的sh文件名
oneshot #只啟動一次
disabled #禁用服務(wù),不會開機自啟動,但是可以在應(yīng)用程序中手動啟動
service system_reboot /system/bin/system_reboot.sh
oneshot
disabled
- 新建目錄,將上面的mk文件和兩個sh腳本放到目錄下,然后將文件夾副指導(dǎo)系統(tǒng)路徑中,然后編譯源碼。
- 即可在代碼中調(diào)用系統(tǒng)服務(wù)重啟或關(guān)機
SystemProperties.set("ctl.start", "system_shutdown"); //system_shutdown是sh腳本的文件名
SystemProperties.set("ctl.start", "system_reboot");
三,通過init.rc啟動系統(tǒng)服務(wù)來運行sh文件(也是最常用的方法)
//Runtime執(zhí)行l(wèi)inux-shell
case R.id.shutdown_btn3:
try{
Log.v(TAG, "root Runtime->shutdown");
//Process proc =Runtime.getRuntime().exec(new String[]{"su","-c","shutdown"}); //關(guān)機
Process proc =Runtime.getRuntime().exec(new String[]{"su","-c","reboot -p"}); //關(guān)機
proc.waitFor();
}catch(Exception e){
e.printStackTrace();
}
break;
case R.id.reboot_btn3:
try {
Log.v(TAG, "root Runtime->reboot");
Process proc =Runtime.getRuntime().exec(new String[]{"su","-c","reboot "}); //關(guān)機
proc.waitFor();
}catch (Exception ex){
ex.printStackTrace();
}
break;
前提是android系統(tǒng)system/bin 目錄下存在reboot和shutdown文件,大多數(shù)型號的設(shè)備都是有的。
設(shè)備需要獲取root權(quán)限。
四,PowerManager提供了reboot接口
PowerManager pManager=(PowerManager) getSystemService(Context.POWER_SERVICE);
pManager.reboot(null);//重啟