Приемник Android игнорирует NEW_OUTGOING_CALL
У меня есть с Broadcastreceiver с фильтром намерений, чтобы поймать android.intent.action.NEW_OUTGOING_CALL.
Я прочитал много уроков и отвечу здесь об обработке намерения NEW_OUTGOING_CALL, но я не смог заставить эту вещь работать. Моя цель - записать намерение android.intent.action.NEW_OUTGOING_CALL, полученное моим Broadcastreceiver. Я не могу заставить эту простую вещь работать.
Вот мой код:
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.vannus.broadcasttest">
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".TestReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>
Это код для Broadcastreceiver (TestReceiver.java)
package net.vannus.broadcasttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class TestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
Log.w("###TEST###",intent.getAction());
}
}
Проект также содержит пустой MainActivity без функциональности. При выполнении проекта основным действием является запуск, но при попытке сделать или принять вызовы не пишутся логи. Я тестировал код в эмуляторе (Android 7) и на телефоне Motorola G4 (Android 6.0), но в logcat ничего не было зарегистрировано. Я использую Android Studio 2.3
Что я делаю неправильно?
Спасибо
Vannus
4 ответа
От Android Oreo проблема заключается в том, что для разрешений "опасного" типа (одним из которых является PROCESS_OUTGOING_CALLS") этого недостаточно для декларации в манифесте. Необходимо специально предложить пользователю предоставить это разрешение. Это можно сделать с помощью рамки, как обсуждено здесь:
https://developer.android.com/training/permissions/requesting
В частности, вам нужно в основном вызвать "requestPermissions" с массивом разрешений, которые вам действительно нужны, и он попросит пользователя утвердить их.
Лично я нахожу это довольно раздражающим, но у меня есть объяснение этому.
В моем случае приложение уже имело права, но по какой-то причине, когда я объявил
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter
после android.intent.action.NEW_OUTGOING_CALL получатель начал отправлять новое событие исходящего вызова. поэтому объявление выглядит так:
<receiver android:name=".CallReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
Решение очень простое... на телефоне зайдите в настройки-> приложения, выберите приложение и дайте разрешение телефона. Подсказка появилась при поиске logcat, я нашел эту ошибку
03-05 20:18:57.090 1547-1775/system_process W/BroadcastQueue: Отказ в разрешении: получение намерения { act=android.intent.action.NEW_OUTGOING_CALL flg=0x10000010 (имеет дополнительные функции) } для net.vannus.broadcasttest/.TestReceiver требуется. android.permission.PROCESS_OUTGOING_CALLS из-за отправителя android (uid 1000).
Проверьте время выполнения разрешения
@TargetApi(Build.VERSION_CODES.M)
public static boolean hasSelfPermission(Activity activity, String[] permissions) {
// Below Android M all permissions are granted at install time and are already available.
if (!isMNC()) {
return true;
}
// Verify that all required permissions have been granted
for (String permission : permissions) {
if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
и использовать этот метод, чтобы проверить разрешение
@TargetApi(Build.VERSION_CODES.M)
private boolean isReadStatePermission() {
if (hasSelfPermission((Activity) context, READ_PHONE_STATE)) {
return true;
} else {
if (((Activity) context).shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE)) {
((Activity) context).requestPermissions(READ_PHONE_STATE, REQUEST_WRITE_STORAGE);
} else {
((Activity) context).requestPermissions(READ_PHONE_STATE, REQUEST_WRITE_STORAGE);
}
return false;
}
выполнить любую операцию после проверки разрешения
if (isReadStatePermission()) {
PERFROM YOUR OPERATION
}