关闭带有系统签名应用程序的Android设备

关闭带有系统签名应用程序的Android设备,android,Android,我正在开发一个Android应用程序,在某些情况下我们需要关闭设备电源 我在很多地方读到,你需要一个植根电话,以便这样做。然后,您可以使用Java的API发出“reboot”命令: try { Process proc = Runtime.getRuntime() .exec(new String[]{ "su", "-c", "reboot -p" }); proc.waitFor(); } catch (Exception ex) {

我正在开发一个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一样)。但是,即使我将我的应用程序安装为使用制造商证书签名的系统应用程序,上述代码也不起作用:

  • 如果我离开命令的“su”部分,将显示“超级用户请求”屏幕,但这是我们试图避免的

  • 如果我删除了“su”部分(只留下“reboot-p”),该命令将被默默地忽略

因此,我们无法使用我们的系统应用程序关闭设备的电源,该应用程序由制造商证书签署。所以我的问题是,我该怎么做

已编辑


顺便说一句,以防有人对此不确定:应用程序已正确签名并作为系统应用程序安装,因为我们实际上可以访问一些受限制的API,如PowerManager.goToSleep()

如果您希望设备重新启动(关机和开机),请尝试
PowerManager.reboot()

:

:

好吧,我错了

当我执行一些测试时,我没有意识到我已经从清单中删除了“android:sharedUserId=“android.uid.system”

一旦包含sharedUserId,以下代码将在不提示用户确认根用户访问的情况下工作:

try {
    Process proc = Runtime.getRuntime()
            .exec(new String[]{ "su", "-c", "reboot -p" });
    proc.waitFor();
} catch (Exception ex) {
    ex.printStackTrace();
}

我试图删除“su”(因为系统可能不提供这样的命令),但在这种情况下它无法工作。令人惊讶的是,文件系统是以只读模式重新安装的,因此我必须使用写权限再次重新安装它。

这对我来说工作正常:

startActivity(new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN"));
您需要此权限(取决于是否为系统应用):


资料来源:

我特别说了“关机”,而不是重新启动。是的,我注意到了。但是由于您一直在尝试使用
su reboot
,如问题正文所示,我认为
PowerManager.reboot()
会很有帮助。无论如何,请查看带有“关机”的更新。不,不是SDK的一部分。但可用于“应用程序”[that]作为系统应用程序正确签名和安装“好的,很公平。即使您的解决方案和我的解决方案都不是”标准“,因为它们都依赖于设备制造商提供的特定内部API,所以您的API更干净,并且可能会得到长期支持。此外,当使用IPowerManager时,系统会很好地关闭,但当使用“poweroff”命令时,系统会突然关闭,我想这可能是个问题。谢谢!顺便说一句,我不认为你所说的“系统应用程序”可用性一定是正确的。API的这一部分是私有的,因此谷歌可能会在未来的版本中删除它。我的意思是,这在以前的Android版本中甚至不可用。如果这完全回答了你的问题,请接受你的答案,给谷歌人一些建议;)我不能!告诉我需要等待两天才能接受y的答案:李更喜欢“鞋鼠”的答案,这显示了一个更优雅的解决方案。摆弄超级用户不是一个好的解决方案。。。
IPowerManager powerManager = IPowerManager.Stub.asInterface(
        ServiceManager.getService(Context.POWER_SERVICE));
try {
    powerManager.shutdown(false, false);
} catch (RemoteException e) {
}
/**
 * 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);
    }
}
try {
    Process proc = Runtime.getRuntime()
            .exec(new String[]{ "su", "-c", "reboot -p" });
    proc.waitFor();
} catch (Exception ex) {
    ex.printStackTrace();
}
startActivity(new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN"));
 <uses-permission android:name="android.permission.SHUTDOWN"/>