【问题标题】:Permission Denial of android.intent.action.REBOOT for APP in /system/priv-app/system/priv-app 中 APP 的 android.intent.action.REBOOT 权限拒绝
【发布时间】:2017-05-22 07:40:33
【问题描述】:

我的应用程序的一项功能旨在在单击重启按钮时发送重启广播。

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: not allowed to send broadcast android.intent.action.REBOOT from pid=2801, uid=10016

我用dumpsys检查了系统状态,发现10016user-id被授予了REBOOT权限em>。

SharedUser [com.example] (10b8d16d):

userId=10016 gids=[1028, 1015, 1007, 3003]

授予权限:

android.permission.重启

顺便说一句,我正在使用Android5.1.1的pad进行测试。

【问题讨论】:

    标签: android permissions


    【解决方案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 需要 设置为 true

    <application android:name="MyApp" 
      android:persistent="true">
    

    【讨论】:

    • 谢谢你...我一直在寻找这个解决方案好几个小时了!
    【解决方案2】:

    根据文档,你不能使用它。

    广播操作:让设备重新启动。这仅供使用 系统代码。 这是一个受保护的意图,只能由系统发送。

    https://developer.android.com/reference/android/content/Intent.html#ACTION_REBOOT

    【讨论】:

    • /system/priv-app 中的 APK 会自动获得系统权限。
    • 看起来这个权限只会被授予系统应用程序,也许你也应该有root权限(只是一个hypotetis)。
    • 没有,我用dumpsys检查的时候给APP授予了权限。
    猜你喜欢
    • 2021-04-12
    • 2018-10-08
    • 2021-01-07
    • 2021-08-10
    • 2018-11-24
    • 1970-01-01
    • 2021-12-23
    • 2021-07-15
    • 1970-01-01
    相关资源
    最近更新 更多