【问题标题】:Broadcast reciever permission denial广播接收器权限被拒绝
【发布时间】:2019-10-24 14:15:31
【问题描述】:

我正在开发一个应用程序,我必须在电话通话时启动一个小部件。

我已经在清单中注册了广播请求:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
...Other permissions required for screen overlay...

我已经在清单中注册了我的广播接收器:

    <receiver android:name=".phoneReceiver"
        android:exported="true"
        android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE"/>
        </intent-filter>
    </receiver>

注意:当用户按下按钮时,我会在运行时启用接收器。这也是我请求 perms 的时候,因为我的测试系统运行的是 Android 7.0

然后我在运行时通过按下按钮请求权限:

    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_PHONE_STATE)
                    != PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.READ_PHONE_STATE}, 2);
                showToast(getApplicationContext(), "Phone state requested");
            } else{
                enableWidget();    //if permissions are already granted
            }
        }
    });

我这样等待权限请求的结果:

@Override
public void onRequestPermissionsResult(int req, @NonNull String[] perms, @NonNull int[] results){
    switch(req){
        case 2:
            if(results.length > 0 && results[0]==PackageManager.PERMISSION_GRANTED){
                showToast(this, "Phone state granted");
                enableWidget();
            }
            return;
    }
}

enableWidget() 中,我这样启用广播接收器:

private void enableWidget(){
    PackageManager pm = MainActivity.this.getPackageManager();
    ComponentName comp = new ComponentName(getApplicationContext(), phoneReceiver.class);
    pm.setComponentEnabledSetting(comp, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
} 

现在根据我的说法,只要状态发生变化,就应该调用接收器,但这不会发生。相反,我在 logcat 中得到以下信息,这让我认为接收器已启用但仍未被调用。

W/BroadcastQueue: Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to com.example.myapplication/.phoneReceiver requires android.permission.READ_PRIVILEGED_PHONE_STATE due to sender android (uid 1000)

我在这里错过了什么?


PS这是我的接收器的 sn-p 减去不必要的东西:

public class phoneReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            if(ContextCompat.checkSelfPermission(context, Manifest.permission.SYSTEM_ALERT_WINDOW)
                != PackageManager.PERMISSION_GRANTED)
                return;
            if(ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED)
                return;
        }
        if(intent.getStringExtra(TelephonyManager.EXTRA_STATE)
            .equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
            showToast(context, "In call");
            startWidget(context);
        } else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE)
            .equals(TelephonyManager.EXTRA_STATE_IDLE)){
            showToast(context, "Out of call");
            stopWidget(context);
        }
    }
    ...Definitions of showToast, start, stopWidget...
}

PPS我检查了系统设置中的应用权限,并且“电话”设置为开启。


我尝试通过在 Manifest 中将 Receiver 声明为:

android:enabled="true"

并删除在运行时启用小部件的部分。我仍然在运行时请求权限。我仍然遇到同样的错误。

同样的系统,在 API 级别 22 上工作。

【问题讨论】:

    标签: android broadcastreceiver android-permissions


    【解决方案1】:

    清单声明的接收器:如果您的应用以 API 级别 26 或更高级别为目标,您不能使用清单声明隐式广播的接收器(不针对您的应用程序),除了一些不受该限制Exempted List 的隐式广播。在大多数情况下,您可以改用计划作业。

    上下文注册接收器:只要其注册上下文有效,就接收广播。例如,如果您在 Activity 上下文中注册,只要该 Activity 未销毁,您就会收到广播。如果您在应用程序上下文中注册,只要应用程序正在运行,您就会收到广播。

    由于内存改进,请查看official site 了解更多详情。

    【讨论】:

    • 现在,我的应用程序的目标是 API 级别 24。这里的目的只是了解它的工作原理,而不是创建生产应用程序。
    • 简单来说,您已经使用有效上下文注册了您的接收器以接收数据。这个过程与学习和生产应用程序无关。详情请查看链接。
    • 是的,但所有这些都适用于 API 级别 26 及以上,对吗?我在 24 级工作
    【解决方案2】:

    您可以使用 JobScheduler API 来触发事件,我之前在为我的一个 APP 使用 Geofencing API 时遇到了类似的问题

    【讨论】:

    • 我正在寻找使用已有安卓功能的解决方案
    • 好的。我想这应该是你迄今为止所做的正确方法。不知道为什么这对你不起作用。 @ParthK
    • 嘿你能解决这个@ParthK
    猜你喜欢
    • 2018-01-20
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 2011-04-18
    • 2012-11-02
    • 1970-01-01
    相关资源
    最近更新 更多