Я работаю над приложением, в котором мне нужно запустить виджет, когда телефон находится в состоянии вызова.
Я зарегистрировался для запроса широковещательной передачи в манифесте следующим образом:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
...Other permissions required for screen overlay...
Iзарегистрировал мой широковещательный приемник в манифесте следующим образом:
<receiver android:name=".phoneReceiver"
android:exported="true"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
Примечание. Я включаю приемник во время выполнения, когда пользователь нажимает кнопку.Это также время, когда я запрашиваю перми, поскольку моя тестовая система работает под управлением 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 Вот фрагмент моего Приемника за вычетом ненужных вещей:
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 Я проверил разрешения приложения в системных настройках и включил "телефон".
Я попытался оставить Receiver включенным по умолчанию, объявив его вМанифест как:
android:enabled="true"
и удаление раздела для включения виджета во время выполнения.Я все еще спрашиваю разрешения во время выполнения.Тем не менее, я получаю ту же ошибку.
Та же система, работающая на уровне API 22.