ACTION_PHONE_STATE_CHANGED not called on network c

2019-07-24 15:36发布

问题:

I am trying to make my broadcast receiver fire when the phone goes in and out of reception areas. The issue is the receiver never gets called when the cell reception changes. The BroadcastReceiver works fine for getting phone call states (call idle, started ect...), and also for getting the airplane mode switched on and off because the broadcast receiver handles both.

I added the permissions and intent filter to the receiver in the manifest and they are working fine.

Here is what I have for my BroadcastReceiver and PhoneStateListener.

public class PhoneStateReceiver extends BroadcastReceiver {

private PhoneStateListener mListener = new ServiceStateListener();
private TelephonyManager mTelephonyManager;
private Context mContext;
/**
 * TODO add some sort of call back interface to allow for different uses of this phone state receiver
 */

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    mContext = context;
    if (action.intern().equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
        boolean isAirplaneModeOn = intent.getBooleanExtra("state", false);
        if (!isAirplaneModeOn) {
            SmsRetryManager.getInstance().retryAllSms(context);
        }
    } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
        mTelephonyManager = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        Toast.makeText(mContext, "Receiver registered!", Toast.LENGTH_LONG).show();
        mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
        mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    }
}


public void onDestroy() {
    mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
}

private class ServiceStateListener extends PhoneStateListener {

    @Override
    public void onServiceStateChanged (ServiceState serviceState) {
        super.onServiceStateChanged(serviceState);
        boolean connected = (serviceState.getState() == ServiceState.STATE_IN_SERVICE);
        if (connected) {
            Toast.makeText(mContext, "Connection Gained!", Toast.LENGTH_LONG).show();
            //todo retry sms here
            SmsRetryManager.getInstance().retryAllSms(mContext);

        } else {
            Toast.makeText(mContext, "Connection Lost!", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        super.onSignalStrengthsChanged(signalStrength);
        Toast.makeText(mContext, "Signal changed - cdma : " + signalStrength.getCdmaDbm() + " gsm : " + signalStrength.getGsmSignalStrength(), Toast.LENGTH_LONG).show();
    }
}

Any insight would be awesome. I have been banging my head on this one for a while.

Thanks!

回答1:

I assume you are listening the broadcast android.intent.action.SERVICE_STATE

If so, try using:

if (TelephonyManager.getnetworkOperator.length()==0) connected=false;

on your OnReceive method, to know if the phone is not connected. It works fine for me.

If this solution doesn't work, please show how you register the receiver: is it statically registered at manifest.xml? or dynamically with PackageManager.setComponentEnabledSetting? Note: With static registration you'll find the receiver is not triggered after reinstalling the app, needing to add to the receiver tag

<intent-filter> <action android:name= "android.intent.action.MY_PACKAGE_REPLACED"/></intent-filter>

You can also look at the values that return the ServiceState. See here http://developer.android.com/reference/android/telephony/ServiceState.html

And check which of these values is returned:

int STATE_EMERGENCY_ONLY = The phone is registered and locked. Only emergency numbers are allowed.

int STATE_IN_SERVICE = Normal operation condition, the phone is registered with an operator either in home network or in roaming.

int STATE_OUT_OF_SERVICE = Phone is not registered with any operator, the phone can be currently searching a new operator to register to, or not searching to registration at all, or registration is denied, or radio signal is not available.

int STATE_POWER_OFF = Radio of telephony is explicitly powered off.