【问题标题】:Android application using BroadcastReceiver right way正确使用 BroadcastReceiver 的 Android 应用程序
【发布时间】:2018-05-16 12:11:47
【问题描述】:

我想在我的 Android 应用程序中实现呼叫注册功能。为此,我以这种方式实现了 BroadcastReceiver:

public class IncomingCall extends BroadcastReceiver {
    //private AppPhoneStateListener phoneStateListener;
    private TelephonyManager telephonyManager;
    private HashMap<String, AppPhoneStateListener> appPhoneStateListenerHashMap = new HashMap<>();
@Override
public void onReceive(Context context, Intent intent) {
    try {
        // Create manager for listener registration
        AppPhoneStateListener phoneStateListener = new AppPhoneStateListener();

        telephonyManager = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);

        // Register listener for LISTEN_CALL_STATE
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);

    } catch (Exception e) {
        Crashlytics.logException(e);
    }
}


private class AppPhoneStateListener extends PhoneStateListener {
    private CallMonitoring callMonitoring = new CallMonitoring();

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        // Service only for child device
        Role role = User.getRole();
        if (role == Role.parent) return;

        Log.d("MyPhoneListener","state [" + state + "]");

        if (state == TelephonyManager.CALL_STATE_RINGING) {
            callMonitoring.registerChangeState(state);
            if (!appPhoneStateListenerHashMap.containsKey(incomingNumber)) {
                appPhoneStateListenerHashMap.put(incomingNumber, this);
            } else {
                telephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
            }
            //Log.d("MyPhoneListener","saved call states [" + callMonitoring.showCallStates() + "]");
        }
        if (appPhoneStateListenerHashMap.containsKey(incomingNumber)) {
            if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                callMonitoring.registerChangeState(state);
                //Log.d("MyPhoneListener","saved call states [" + callMonitoring.showCallStates() + "]");
            }
            if (state == TelephonyManager.CALL_STATE_IDLE) {
                //Log.d("MyPhoneListener","saved call states [" + callMonitoring.showCallStates() + "]");
                // There was incoming call then we have call attachCall api method
                if (callMonitoring.wasIncomingCall()) {
                    long duration = callMonitoring.getLastActionDuration();
                    CallType callType = callMonitoring.getCallType();
                    CallStatus callStatus = callMonitoring.getCallStatus();
                    // Logging to debug
                    Log.d("MyPhoneListener","api params: phone [" + incomingNumber + "]; duration [" + duration + "]; callType [" + callType.getCallType() + "]; callStatus [" + callStatus.getCallStatus() + "]");
                    // Call api

                    // Unregister listener for LISTEN_CALL_STATE
                    unsubscribeCallListener(incomingNumber);
                }
                // Return call monitoring call to initial state
                callMonitoring.clearState();
            }
        }
    }

    private void unsubscribeCallListener(String incomingNumber) {
        appPhoneStateListenerHashMap.remove(incomingNumber);
        telephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
    }
}

}

如您所见,在接收事件中,我正在注册 PhoneStateListener,它开始监控不断变化的呼叫状态。

重启应用程序正常工作后首次拨打电话。我可以按预期看到事件:

TelephonyManager.CALL_STATE_RINGING

然后

TelephonyManager.CALL_STATE_IDLE如果没有摘机事件。

但在第二次通话后,我可以看到事件增加了一倍。我可以看到TelephonyManager.CALL_STATE_IDLE 的两倍和三倍事件。而且似乎这些事件是在独立线程中处理的,因为callMonitoring.clearState() 不会阻止第二个字符串Log.d("MyPhoneListener","api params: phone [" + incomingNumber + "]; duration [" + duration + "]; callType [" + callType.getCallType() + "]; callStatus [" + callStatus.getCallStatus() + "]");.

如何“重置”我的 BroadcastReceiver 的状态?

或者我错过了一些重要的事情?

【问题讨论】:

    标签: android broadcastreceiver


    【解决方案1】:

    你混淆了两件事。 1. PhoneStateListener API,正在运行的应用程序可以利用它来监控各种电话状态项。 2.phone state broadcast,可以被正在运行或非运行的应用程序用来通知手机状态的变化。

    您不应该以这种方式在 BroadcastReceiver 中注册 PhoneStateListener。看看 ACTION_PHONE_STATE_CHANGED 广播是如何工作的;这应该足以实现您的目标。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多