如何不使用su(超级用户)实现设备重启?
我需要重启Android设备,目前已经通过root权限使用以下代码实现了该操作:
public static void rebootDevice() { try { Process process = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(process.getOutputStream()); os.writeBytes("reboot \n"); } catch (Throwable t) { t.printStackTrace(); } }但上级要求尝试不使用su(超级用户)实现重启,请问该如何操作?
针对你的问题,我来梳理下不用su实现Android设备重启的可行方案——不过先提前说明:Android的安全机制对重启这类敏感操作限制很严,普通第三方应用几乎没有无权限的重启途径,下面的方法都有各自的前提条件:
方法1:使用系统级API(需应用拥有系统签名)
Android官方提供了PowerManager类的重启接口,但这个接口需要**REBOOT权限**,而这个权限属于signature|privileged级别——意味着你的应用要么和系统使用相同的签名,要么被安装在/system/priv-app目录下(只有系统应用或定制ROM内置应用能满足这个条件)。
代码实现
import android.content.Context; import android.os.PowerManager; import android.os.Build; public static void rebootWithSystemPrivilege(Context context) { PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (powerManager == null) { return; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Android 8.0及以上推荐使用这个方法 powerManager.reboot(null); } else { // 低版本可使用已废弃的restart方法,仍能正常工作 powerManager.restart("initiated by app"); } }
权限配置
需要在AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.REBOOT" />
方法2:利用设备管理员权限(兼容性有限)
部分Android设备允许已授权的设备管理员应用触发重启,但这个功能不是所有厂商都支持(很多定制ROM会移除这个权限),而且需要用户手动授权设备管理员权限给你的应用。
步骤1:创建设备管理员接收器
public class MyDeviceAdminReceiver extends android.app.admin.DeviceAdminReceiver { // 可选:实现onEnabled等回调,处理授权状态变化 }
步骤2:在Manifest中注册接收器
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" /> <receiver android:name=".MyDeviceAdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN"> <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin_config" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver>
步骤3:创建设备管理员配置文件
在res/xml目录下新建device_admin_config.xml:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android"> <uses-policies> <force-lock /> <!-- 声明需要重启权限,部分设备会识别这个配置 --> <reboot /> </uses-policies> </device-admin>
步骤4:请求授权并尝试重启
import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; public static void rebootWithDeviceAdmin(Context context) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName adminComponent = new ComponentName(context, MyDeviceAdminReceiver.class); if (dpm.isAdminActive(adminComponent)) { try { dpm.reboot(adminComponent); } catch (SecurityException e) { e.printStackTrace(); // 遇到异常说明当前设备不支持设备管理员重启 } } else { // 引导用户授权设备管理员 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminComponent); intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "需要设备管理员权限来完成重启操作"); context.startActivity(intent); } }
方法3:定制ROM/特定设备的隐藏接口(不推荐)
有些定制ROM可能会开放非标准的重启接口,但这些接口没有官方文档支持,兼容性极差,系统更新后可能直接失效,所以不建议在正式项目中使用。
总结
如果你的应用是普通第三方应用,没有办法绕过root或系统权限实现重启——Android的安全模型就是为了防止普通应用随意执行这类影响系统稳定性的操作。只有系统应用、拥有系统签名的应用,或者少数支持设备管理员重启的设备才能满足无root重启的需求。
内容的提问来源于stack exchange,提问作者Gajanand Swamy

