使用系统签名的应用程序closuresAndroid设备

我正在开发一个Android应用程序,我们需要在某些情况下closures设备。

我曾经在很多地方读过,为了达到目的,你需要一根扎根的电话。 然后,您可以使用Java的API发出“rebo​​ot”命令:

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

我实际上已经在Cyanogenmod 10设备(Samsung Galaxy S3)中尝试了这一点,并且工作正常。 但是,我们不希望根植设备能够closures它,因为最终用户将能够做出我们公司不允许的意外事情。

另一方面,我们的应用程序是由制造商的证书,在这种情况下,氰诺的。 我已经读过,通过使用制造商的证书签署你的应用程序,你应该能够发出特权命令(就像root一样)。 但是,即使我将我的应用程序安装为使用制造商证书签名的系统应用程序,上面的代码也不起作用:

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

  • 如果我删除了“su”部分(只留下“rebo​​ot -p”),命令将被忽略。

因此,我们无法使用我们的系统应用程序(已通过制造商证书签名)closures设备。 所以我的问题是,我该怎么做?

EDITED

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

Solutions Collecting From Web of "使用系统签名的应用程序closuresAndroid设备"

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

 PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE); powerManager.reboot(null); 

android.os.PowerManager :

 /** * 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 (eg, "recovery") to * request special boot modes, or null. */ public void reboot(String reason) { try { mService.reboot(false, reason, true); } catch (RemoteException e) { } } 

UPDATE

如果您希望设备完全closures,请使用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"/> 

来源: https : //github.com/sas101/shutdown-android-app/wiki

好的,我的错误

当我执行一些testing时,我没有意识到我已经从清单中移除了“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(); } 

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