我正在开发Android应用程序,我们需要在某些情况下关闭设备。
我在很多地方都读到你需要一部扎根手机才能这样做。然后,您可以使用Java的API发出“reboot”命令:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
我实际上已经在Cyanogenmod 10设备(三星Galaxy S3)中尝试了这个,它可以工作。但是,我们不希望使用root设备来关闭设备,因为最终用户将能够执行我们公司不允许的非预期操作。
另一方面,我们的申请是由制造商的证书签署的,在这种情况下是Cyanogen的。我已经读过,通过使用制造商的证书签署您的应用程序,您应该能够发出特权命令(就像root一样)。但是,即使我将我的应用程序安装为使用制造商证书签名的系统应用程序,上述代码也不起作用:
如果我离开命令的“su”部分,则会显示“超级用户请求”屏幕,但这是我们要避免的。
如果我删除“su”部分(只是离开“reboot -p”),则会默默忽略该命令。
因此,我们无法使用我们的系统应用程序关闭我们的设备,该系统应用程序使用了显示器的证书。所以我的问题是,我该怎么做呢?
EDITED
顺便说一下,万一有人不确定它:应用程序已正确签名并作为系统应用程序安装,因为我们实际上可以访问一些受限制的API,例如PowerManager.goToSleep()
答案 0 :(得分:8)
如果您希望设备重新启动(关机再打开),请尝试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) {
}
}
<强>更新强>
如果您希望设备完全关闭,请使用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);
}
}
答案 1 :(得分:3)
这对我来说很好:
startActivity(new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN"));
您需要此权限(取决于系统应用):
<uses-permission android:name="android.permission.SHUTDOWN"/>
答案 2 :(得分:0)
好的,我的错误。
当我进行一些测试时,我没有意识到我从清单中删除了“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”(因为系统可能没有提供这样的命令),但在这种情况下它不起作用。令人惊讶的是,文件系统以只读模式重新装入,因此我必须使用写入权限重新安装它。