在清单中注册 Broadcastreceiver

Register Broadcastreceiver in manifest

我有以下 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>

监听器接收数据,而主activity是运行。然而,当 main activity 被杀死时,接收器停止输出信息。

接收者是一个例子class:

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;
            }
        }
    }
}

据我了解 android 原则,当一个接收器在清单中注册时,即使它的应用程序被杀死,它也应该接收数据,如果是这样,我做错了什么?

将以下内容添加到清单中的 <receiver>

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

此外 according to this thread,似乎您必须在广播接收器开始工作之前手动启动您的活动之一,即在任何广播接收器工作之前,应用程序必须至少启动一次。

另外在<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 Studio 的新版本及其构建工具。

非常感谢 REG1 的耐心和愿意提供想法。

此致

将这些行添加到 android 工作室清单文件中... 你只是没有注册广播class

<receiver android:name=".PhoneStateBroadcastReceiver"
        android:exported="true"
        android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE"/>
    </intent-filter>
</receiver>