Приемник 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
    }
Другие вопросы по тегам