我的应用程序的一项功能是在单击重新启动按钮时发送重启广播。
getActivity().sendBroadcast(new Intent(Intent.ACTION_REBOOT));
根据Android参考文档,其APK在 / system / priv-app 目录中的应用可以使用 signatureOrSystem 权限 没有 共享平台证书。请参阅AOSP Privileged vs System app
REBOOT权限就是其中之一(frameworks/base/core/res/AndroidManifest.xml)。
<!-- @SystemApi Required to be able to reboot the device.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.REBOOT"
android:label="@string/permlab_reboot"
android:description="@string/permdesc_reboot"
android:protectionLevel="signature|system" />
所以我用我自己的证书签署了我的APK,然后将我的APK推送到 / system / priv-app ,并确保APK文件与目录中的其他APK具有相同的读写访问权限。
但是,它无法发送带有错误的重启广播,
ActivityManager:Permission Denial:不允许从pid = 2801发送广播android.intent.action.REBOOT,uid = 10016
我使用 dumpsys 检查了系统状态,发现为 10016 的用户ID 授予了REBOOT权限
SharedUser [com.example](10b8d16d):
userId = 10016 gids = [1028,1015,1007,3003]
grantedPermissions:
android.permission。的 REBOOT
顺便说一句,我正在使用Android5.1.1的垫进行测试。
答案 0 :(得分:1)
我在Android源代码的ActivityManagerService.java中得到了答案。
int callingAppId = UserHandle.getAppId(callingUid);
if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
|| callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
|| callingAppId == Process.NFC_UID || callingUid == 0) {
// Always okay.
} else if (callerApp == null || !callerApp.persistent) {
try {
if (AppGlobals.getPackageManager().isProtectedBroadcast(
intent.getAction())) {
String msg = "Permission Denial: not allowed to send broadcast "
+ intent.getAction() + " from pid="
+ callingPid + ", uid=" + callingUid;
Slog.w(TAG, msg);
throw new SecurityException(msg);
} else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
...
}
...
}
}
所以, android:persistent NEED 设置为 true 。
<application android:name="MyApp"
android:persistent="true">
答案 1 :(得分:-1)
根据文档,你不能使用它。
广播操作:让设备重启。这只适用于 系统代码。 这是受保护的意图,只能由系统发送。
https://developer.android.com/reference/android/content/Intent.html#ACTION_REBOOT