Listener registered within an IntentService receives notification only once

杀马特。学长 韩版系。学妹 提交于 2019-12-11 16:16:45

问题


I am writing a simple app to keep track of the periods when my phone has poor signal strength. I do this using an IntentService, which listens for PhoneStateListener.LISTEN_SIGNAL_STRENGTHS as follows:

public class PoorSignalIntentService extends IntentService {

    private TelephonyManager mTelephonyManager;
    private PhoneStateListener mPhoneStateListener;
    public PoorSignalIntentService() {
        super("PoorSignalIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        mPhoneStateListener = new PhoneStateListener(){
            @Override
            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                doSomething(signalStrength);
                super.onSignalStrengthsChanged(signalStrength);
            }

            @Override
            public void onServiceStateChanged(ServiceState serviceState) {
                doSomething(serviceState);
                super.onServiceStateChanged(serviceState);
            }
        };

        mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS|PhoneStateListener.LISTEN_SERVICE_STATE);

    }

    private void doSomething(SignalStrength signalStrength){
        Log.d(TAG, "Signal Strength changed! New strength = "+signalStrength.getGsmSignalStrength());
    }

    private void doSomething(ServiceState serviceState){
        Log.d(TAG, "Service State changed! New state = "+serviceState.getState());
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "Shutting down the IntentService");
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        super.onDestroy();
    }
}

However, I see that after the first signal strength changed notification is received, the onDestroy() is called (presumably, the IntentService calls stopSelf()).

This problem is not limited to PhoneStateListener. I have another simple app which uses the Proximity Sensor thus:

@Override
    protected void onHandleIntent(Intent intent){
        mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
    }

In this case too, only the first proximity change was notified, after which the Service stopped itself.

So, what is the pattern for registering listeners like these in a Service?


回答1:


Ok, I found the solution. My bad. I should be using a Service rather than IntentService, since the latter calls stopSelf() after processing the intents it receives in onHandleIntent().

Here's the working code which extends Service:

public class PoorSignalService extends Service {

    private TelephonyManager mTelephonyManager;
    private PhoneStateListener mPhoneStateListener;


    @Override
    public IBinder onBind(Intent intent) {
        // We don't want to bind; return null.
        return null;
    }


    @Override
    public void onCreate() {
        mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        mPhoneStateListener = new PhoneStateListener(){
            @Override
            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                doSomething(signalStrength);
                super.onSignalStrengthsChanged(signalStrength);
            }

            @Override
            public void onServiceStateChanged(ServiceState serviceState) {
                doSomething(serviceState);
                super.onServiceStateChanged(serviceState);
            }
        };
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //Register the listener here.
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS|PhoneStateListener.LISTEN_SERVICE_STATE);
        return super.onStartCommand(intent, flags, startId);
    }


    private void doSomething(SignalStrength signalStrength){
        Log.d(TAG, "Signal Strength changed! New strength = "+signalStrength.getGsmSignalStrength());
    }

    private void doSomething(ServiceState serviceState){
        Log.d(TAG, "Service State changed! New state = "+serviceState.getState());
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "Shutting down the Service");
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        super.onDestroy();
    }
}


来源:https://stackoverflow.com/questions/8633756/listener-registered-within-an-intentservice-receives-notification-only-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!