Зарегистрировать Broadcastreceiver в манифесте

У меня есть следующий manifest.xml:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <receiver android:name=".PhoneStateBroadcastReceiver"
        android:permission="android.permission.READ_PHONE_STATE">
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver>

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

</application>

Слушатель получает данные во время выполнения основного действия. Однако, когда основное действие прекращается, получатель прекращает выводить информацию.

Получатель является примером класса:

public class PhoneStateBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "PhoneReceiver";
    Context mContext;
    String incoming_number;
    private int prev_state;

    @Override
    public void onReceive(Context context, Intent intent) {
        TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
        CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
        telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager

        Bundle bundle = intent.getExtras();
        String phoneNr = bundle.getString("incoming_number");
        Log.v(TAG, phoneNr);
        Log.d( TAG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
        mContext = context;
    }

    /* Custom PhoneStateListener */
    public class CustomPhoneStateListener extends PhoneStateListener {

        private static final String TAG = "CustomStateListener";

        @Override
        public void onCallStateChanged(int state, String incomingNumber){

            if( incomingNumber != null && incomingNumber.length() > 0 )
                incoming_number = incomingNumber;

            switch(state){
                case TelephonyManager.CALL_STATE_RINGING:
                    Log.d(TAG, "CALL_STATE_RINGING");
                    prev_state=state;
                    break;

                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Log.d(TAG, "CALL_STATE_OFFHOOK");
                    prev_state=state;
                    break;

                case TelephonyManager.CALL_STATE_IDLE:

                    Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_number);

                    if((prev_state == TelephonyManager.CALL_STATE_OFFHOOK)){
                        prev_state=state;
                        //Answered Call which is ended
                    }
                    if((prev_state == TelephonyManager.CALL_STATE_RINGING)){
                        prev_state=state;
                        //Rejected or Missed call
                    }
                    break;
            }
        }
    }
}

Насколько я понял принципы андроида, когда получатель зарегистрирован в манифесте, то он должен получать данные, даже если его приложение убито, если так, что я делаю не так?

3 ответа

Решение

ХОРОШО. После того, как я ударился головой о стену более недели, я решил создать новый проект с минимальной функциональностью, и он сработал с первой попытки. Я не знаю, было ли это вызвано чем-то в моем старом коде, в чем я сомневаюсь, так как я скопировал метод методом в новый проект, и он все еще работает, или в более новых версиях Android Studio и их инструментах для сборки.

Огромное спасибо REG1 за терпение и желание давать идеи.

С уважением

Добавьте следующее к вашему <receiver> в манифесте:

 android:enabled="true"
 android:exported="true">

Кроме того, согласно этой теме, кажется, что вы должны вручную запустить одно из ваших действий, прежде чем широковещательный приемник начнет работать, то есть приложение должно быть запущено хотя бы один раз, прежде чем любой широковещательный приемник заработает.

Дополнительно объявите разрешение за пределами <application> тег. Таким образом, вы должны иметь что-то вроде этого:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.app.myapp" >
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <application ...
...
</manifest>

Конечно, это означает, что вы должны удалить параметр полномочий в вашем receiver,

Добавьте эти строки в файл манифеста студии android... Вы просто не регистрируете класс трансляции

<receiver android:name=".PhoneStateBroadcastReceiver"
        android:exported="true"
        android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE"/>
    </intent-filter>
</receiver>
Другие вопросы по тегам