【发布时间】:2015-12-24 21:08:02
【问题描述】:
对于关于广播接收器和移动数据连接主题的许多线程、博客、示例和教程,我没有看到有人提出或回答过这个问题。
我相信,基于对我的一个应用程序的试验,这个问题的答案是一个明显的否定,即当启用 WiFi 时,监听移动数据 CONNECTIVITY_CHANGE 的广播接收器在该事件发生时不会收到广播通知.如果我错了并且遗漏了什么,请告诉我。
我的 App 是一个主屏幕 Widget,有两个类,ActiveMobileData 是 AppWidgetProvider,ConnectivityChangeReceiver 是 BroadcastReceiver。 AppWidgetProvider 类是我今年早些时候编写的第一个应用程序,主要来自一本书、StackOverflow 和各种博客等中广泛使用的代码。没有应用程序,只有主屏幕小部件。它只是在红色和绿色之间切换主屏幕图标,以指示当前的移动数据状态。它已经在大约 100 名用户中完美运行了几个月。
我决定添加广播接收器以从设置中获取点击。这段代码也很简单——它确定移动数据的当前状态,并使用 AppWidgetProvider 设置的全局布尔变量来确定主屏幕图标是红色还是绿色。然后它只是确保图标颜色与移动数据状态匹配。
一切正常,除非启用 WiFi 时不会收到通知。如果有办法绕过这个限制,我会很高兴听到它。
以下是小部件的代码,然后是接收器的代码。我省略了一些细节以保持简短。 iconEnabled 是共享的全局布尔变量...
public class ActiveMobileData extends AppWidgetProvider {
static boolean iconEnabled;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null)
super.onReceive(context, intent);
else {
context.startService(new Intent(context, ToggleService.class));
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[]appWidgetIds) {
context.startService(new Intent(context, ToggleService.class));
}
public static class ToggleService extends IntentService {
public ToggleService() {
super("ActiveMobileData$ToggleService");
}
@Override
protected void onHandleIntent(Intent intent) {
ComponentName cn = new ComponentName(this, ActiveMobileData.class);
AppWidgetManager mgr = AppWidgetManager.getInstance(this);
mgr.updateAppWidget(cn, buildUpdate(this));
}
private RemoteViews buildUpdate(Context context) {
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
if (!isMobileDataEnabled(getApplicationContext())) {
updateViews.setImageViewResource(R.id.mobileDataState, R.mipmap.ic_launcher_g);
enableMobileData(getApplicationContext(), true);
iconEnabled = true;
} else {
updateViews.setImageViewResource(R.id.mobileDataState, R.mipmap.ic_launcher_r);
enableMobileData(getApplicationContext(), false);
iconEnabled = false;
}
Intent i = new Intent(this, ActiveMobileData.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
updateViews.setOnClickPendingIntent(R.id.mobileDataState, pi);
return updateViews;
}
public boolean isMobileDataEnabled(Context context) {
// ... the code here is the one that uses Java reflection
}
private void enableMobileData(Context context, boolean enabled) {
// ... the code here is the one that uses Java reflection
}
} // public static class ToggleService
} // public class ActiveMobileData
以下是广播接收器的代码...
public class ConnectivityChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive (Context context, Intent intent) {
handleIntent(context);
}
protected void handleIntent(Context context) {
ComponentName cn = new ComponentName(context, ActiveMobileData.class);
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
mgr.updateAppWidget(cn, buildUpdate(context));
}
private RemoteViews buildUpdate(Context context) {
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
if (!ActiveMobileData.iconEnabled && isMobileDataEnabled(context)) {
ActiveMobileData.iconEnabled = true;
updateViews.setImageViewResource(R.id.mobileDataState, R.mipmap.ic_launcher_g);
Intent i = new Intent(context, ActiveMobileData.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
updateViews.setOnClickPendingIntent(R.id.mobileDataState, pi);
} else
if (ActiveMobileData.iconEnabled && !isMobileDataEnabled(context)) {
ActiveMobileData.iconEnabled = false;
updateViews.setImageViewResource(R.id.mobileDataState, R.mipmap.ic_launcher_r);
Intent i = new Intent(context, ActiveMobileData.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
updateViews.setOnClickPendingIntent(R.id.mobileDataState, pi);
}
return updateViews;
}
private boolean isMobileDataEnabled(Context context) {
// ... Identical code to that in the AppWidgetProvider
}
} // class ConnectivityChangeReceiver
【问题讨论】:
标签: java android widget broadcast connectivity