mobileTofu
mobileTofu

Reputation: 1091

Listen to phone state change in appWidget

My goal is to have an "airplane mode" widget on home screen so that user can toggle on/off airplane mode; the widget displays the current state of the airplane mode (on, off or in transition). In order to do this, I register to listen to phone state change on "onUpdate" callback in my appwidget provider:

mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);

and I update the widget UI by overriding the "mPhoneStateListener.onServiceStateChanged" callback.

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

        switch (serviceState.getState()) {
        case ServiceState.STATE_POWER_OFF:
            currentAirplaneModeState = AIRPLANE_MODE_ON;
            Log.d(APP_ID, "serviceState: "+serviceState.getState()+": STATE_POWER_OFF");
            break;
        case ServiceState.STATE_IN_SERVICE:
            currentAirplaneModeState = AIRPLANE_MODE_OFF;
            Log.d(APP_ID, "serviceState: "+serviceState.getState()+": STATE_IN_SERVICE");
            break;
        case ServiceState.STATE_OUT_OF_SERVICE:
            currentAirplaneModeState = AIRPLANE_MODE_IN_UNDETERMINED;
            Log.d(APP_ID, "serviceState: "+serviceState.getState()+": STATE_OUT_OF_SERVICE");
            break;
        case ServiceState.STATE_EMERGENCY_ONLY:
            currentAirplaneModeState = AIRPLANE_MODE_ON;
            Log.d(APP_ID, "serviceState: "+serviceState.getState()+": STATE_EMERGENCY_ONLY");
            break;
        default:
            Log.d(APP_ID, "serviceState: default: "+serviceState.getState());
            break;
        }
        updateWidget(mContext);
    }

The approach does update the widget but not all the time. It takes several state transitions to toggle airplane mode but my widget is often stuck at the "in transition" mode because once the above code returns, Android seems to assume the listener's work is done and will kill the listener. What is the best approach to keep the phone listener around until a full cycle of transition is complete? Or are there better ways?

Upvotes: 0

Views: 2082

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006944

I register to listen to phone state change on "onUpdate" callback in my appwidget provider

That will never be reliable, and will leak memory before it fails. An AppWidgetProvider, like any manifest-registered BroadcastReceiver, is supposed to live for a few milliseconds, long enough for onReceive() to be processed. Android will terminate your process sometime after that, if there is nothing else keeping the process around and if Android needs the RAM.

Or are there better ways?

Use the ACTION_PHONE_STATE_CHANGED broadcast. Or, use AlarmManager to check on the status after a short period of time.

Upvotes: 1

Related Questions