在appWidget中收听手机状态更改

时间:2011-05-30 17:47:57

标签: android listener android-appwidget

我的目标是在主屏幕上设置一个“飞行模式”小部件,以便用户可以打开/关闭飞行模式;小部件显示飞行模式的当前状态(开,关或转换)。为了做到这一点,我注册听我的appwidget提供程序中的“onUpdate”回调中的手机状态更改:

mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);

我通过覆盖“mPhoneStateListener.onServiceStateChanged”回调来更新小部件UI。

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

该方法确实更新了小部件,但并不是所有时间。它需要几个状态转换来切换飞行模式,但我的小部件经常停留在“转换”模式,因为一旦上面的代码返回,Android似乎认为监听器的工作已完成并将杀死监听器。在整个转换周期完成之前,保持电话听众的最佳方法是什么?或者有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

  

我在appwidget提供商的“onUpdate”回调中注册听电话状态更改

这将永远不可靠,并且会在内存失败之前泄漏内存。与任何清单注册的BroadcastReceiver一样,AppWidgetProvider应该存活几毫秒,足以处理onReceive()。 Android将在此之后的某个时间终止您的流程,如果没有其他任何东西可以保持流程并且Android需要RAM。

  

还是有更好的方法吗?

使用ACTION_PHONE_STATE_CHANGED广播。或者,使用AlarmManager在短时间内检查状态。