问题描述
|
我的目标是在主屏幕上显示一个“飞机模式”小部件,以便用户可以切换飞机模式的开/关;小部件会显示飞行模式的当前状态(开启,关闭或转换)。为此,我注册了我的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似乎会假设侦听器的工作已经完成,并且会杀死侦听器。在整个过渡周期完成之前,让电话听众保持不动的最佳方法是什么?还是有更好的方法?
解决方法
我注册以在我的appwidget提供程序中的\“ onUpdate \”回调上侦听电话状态更改
那将永远是不可靠的,并且会在失败之前泄漏内存。像任何清单注册的BroadcastReceiver一样,AppWidgetProvider应该生存几毫秒,足够长的时间才能处理onReceive()。在此之后,如果没有其他事情可以使进程继续运行,并且Android需要RAM,那么Android将在某个时候终止您的进程。
还是有更好的方法?
使用
ACTION_PHONE_STATE_CHANGED
广播。或者,短时间后使用AlarmManager
检查状态。