Слушатель, зарегистрированный в IntentService, получает уведомление только один раз. - PullRequest
0 голосов
/ 26 декабря 2011

Я пишу простое приложение, чтобы отслеживать периоды, когда мой телефон имеет слабую силу сигнала. Я делаю это, используя IntentService, который прослушивает PhoneStateListener.LISTEN_SIGNAL_STRENGTHS следующим образом:

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

Однако я вижу, что после получения первого уведомления об изменении уровня сигнала вызывается onDestroy() (предположительно, IntentService вызывает stopSelf()).

Эта проблема не ограничивается PhoneStateListener. У меня есть еще одно простое приложение, которое использует датчик приближения таким образом:

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

В этом случае также было сообщено только о первом изменении близости, после чего Service остановился.

Итак, каков шаблон для регистрации таких слушателей в Service?

1 Ответ

2 голосов
/ 28 декабря 2011

Хорошо, я нашел решение.Виноват.Я должен использовать Service вместо IntentService, так как последний вызывает stopSelf() после обработки намерений, которые он получает в onHandleIntent().

Вот рабочий код, который расширяет 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();
    }
}
...