[英]Power off Android device with system signed application
我正在開發一個 Android 應用程序,我們需要在某些情況下關閉設備電源。
我在很多地方都讀到過,您需要有根電話才能這樣做。 然后,您可以使用 Java 的 API 發出“重啟”命令:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
我實際上已經在 Cyanogenmod 10 設備(Samsung Galaxy S3)中嘗試過這個,並且它有效。 但是,我們不希望通過獲得 root 權限的設備將其關閉,因為最終用戶隨后將能夠執行我們公司不允許的意外操作。
另一方面,我們的應用程序由制造商的證書簽署,在本例中為 Cyanogen 的證書。 我讀過,通過使用制造商的證書簽署您的應用程序,您應該能夠發出特權命令(就像 root 用戶一樣)。 但是,即使我將我的應用程序安裝為使用制造商證書簽名的系統應用程序,上述代碼也不起作用:
如果我離開命令的“su”部分,則會顯示“超級用戶請求”屏幕,但這是我們試圖避免的事情。
如果我刪除“su”部分(只留下“reboot -p”),該命令將被靜默忽略。
因此,我們無法使用使用制造商證書簽名的系統應用程序關閉設備。 所以我的問題是,我該怎么做?
已編輯
順便說一句,以防萬一有人不確定:應用程序已正確簽名並安裝為系統應用程序,因為我們實際上可以訪問一些受限的 API,例如 PowerManager.goToSleep()
如果您希望設備重啟(關閉和打開電源),請嘗試使用PowerManager.reboot()
PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
powerManager.reboot(null);
/**
* Reboot the device. Will not return if the reboot is successful.
* <p>
* Requires the {@link android.Manifest.permission#REBOOT} permission.
* </p>
*
* @param reason code to pass to the kernel (e.g., "recovery") to
* request special boot modes, or null.
*/
public void reboot(String reason) {
try {
mService.reboot(false, reason, true);
} catch (RemoteException e) {
}
}
UPDATE
如果您希望設備完全關閉,請使用PowerManagerService.shutdown()
:
IPowerManager powerManager = IPowerManager.Stub.asInterface(
ServiceManager.getService(Context.POWER_SERVICE));
try {
powerManager.shutdown(false, false);
} catch (RemoteException e) {
}
com.android.server.power.PowerManagerService :
/**
* Shuts down the device.
*
* @param confirm If true, shows a shutdown confirmation dialog.
* @param wait If true, this call waits for the shutdown to complete and does not return.
*/
@Override // Binder call
public void shutdown(boolean confirm, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
final long ident = Binder.clearCallingIdentity();
try {
shutdownOrRebootInternal(true, confirm, null, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
這對我來說很好:
startActivity(new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN"));
你需要這個權限(取決於是系統應用程序):
<uses-permission android:name="android.permission.SHUTDOWN"/>
好的,我的錯誤。
當我執行一些測試時,我沒有意識到我從清單中刪除了“android:sharedUserId =”android.uid.system“。
包含sharedUserId后,以下代碼可以在不提示用戶確認root訪問權限的情況下運行:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
我試圖刪除“su”(因為系統可能不提供這樣的命令),但在這種情況下它不起作用。 令人驚訝的是,文件系統以只讀模式重新裝入,因此我必須使用寫入權限重新安裝它。
這是kotlin
(requireContext().getSystemService(Context.POWER_SERVICE) as PowerManager)
.reboot("reason")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.