权限拒绝:不允许发送广播android.intent.action.AIRPLANE_MODE

4

我正在尝试以编程方式设置飞行模式。

Settings.System.putInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);

Intent aeroPlaneIntent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
aeroPlaneIntent.putExtra("state", true);
context.sendBroadcast(aeroPlaneIntent);

当我尝试设置Global.AIRPLANE_MODE_ON时,操作失败,并且如果我检查状态,则返回0(OFF)。

尝试广播意图会引发以下异常:

03-12 07:01:18.747: E/AndroidRuntime(1579): java.lang.RuntimeException: Unable to start receiver com.example.toggleaeroplanemode.AeroplaneModeReceiver: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.AIRPLANE_MODE from pid=1579, uid=10050
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2431)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.app.ActivityThread.access$1500(ActivityThread.java:141)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1332)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.os.Looper.loop(Looper.java:137)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.app.ActivityThread.main(ActivityThread.java:5103)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at java.lang.reflect.Method.invokeNative(Native Method)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at java.lang.reflect.Method.invoke(Method.java:525)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at dalvik.system.NativeStart.main(Native Method)
03-12 07:01:18.747: E/AndroidRuntime(1579): Caused by: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.AIRPLANE_MODE from pid=1579, uid=10050
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.os.Parcel.readException(Parcel.java:1431)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.os.Parcel.readException(Parcel.java:1385)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2224)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1046)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:344)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:344)
03-12 07:01:18.747: E/AndroidRuntime(1579):     at com.example.toggleaeroplanemode.AeroplaneModeReceiver.onReceive(AeroplaneModeReceiver.java:31) 
03-12 07:01:18.747: E/AndroidRuntime(1579):     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2424)
03-12 07:01:18.747: E/AndroidRuntime(1579):     ... 10 more

有没有一种方法可以设置飞行模式开/关?请帮忙。

3个回答

4

对于一些小提示:

首先使用这个权限...

<uses-permission android:name="android.permission.WRITE_SETTINGS" />

更多信息:只需查看此对话


1
请注意,只有安装在系统分区上的应用程序(例如,由已获取 root 权限的设备用户安装)或由签署固件的签名密钥签署的应用程序才能修改飞行模式的状态。普通的 SDK 应用程序无法修改飞行模式的状态。 - CommonsWare
谢谢你的帮助。很抱歉我有这个权限设置,我应该提到它。但是你指出的那个对话非常有帮助。看起来按照这条路线走将会一无所获,因为Intent.ACTION_AIRPLANE_MODE_CHANGED是受保护的意图。 - Mule
8
在Android 5.0中,当我尝试发送广播(ACTION_AIRPLANE_MODE_CHANGED)时,我遇到了安全异常。我已经添加了所有必需的权限并且我的应用程序是系统应用程序。 - yasinkafadar
1
android.permission.WRITE_SETTINGS 权限不是可更改的权限类型。 - MaxF

1
以下内容在Android API 23和26模拟器上已经测试并验证;
所需的清单权限如下;
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" tools:ignore="ProtectedPermissions"/>

代码如下:
boolean turnOnOffAirplaneMode(boolean isTurnOn) {
    boolean result = true;
    try {
        Settings.Global.putInt(context.getContentResolver(),
                Settings.Global.AIRPLANE_MODE_ON, isTurnOn ? 1 : 0);
        // The below old code is now not necessary @ API Level 23, 26 ...
        //Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        //context.sendBroadcast(intent);
    } catch (Exception e) {
        result = false;
    }
    return result;
}

APK应该使用相关平台密钥进行签名,才能使上述操作生效。在模拟器测试中,APK使用了Google签名密钥进行签名。这些密钥取决于设备的OEM。


0
$ adb shell
$ su
# settings put global airplane_mode_on 0
# am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接