【发布时间】: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