Во многих темах, блогах, примерах и учебных пособиях по теме широковещательных приемников и подключения к мобильным данным я не видел, чтобы этот вопрос задавался или отвечал на него.
Я считаю, основываясь на экспериментах с одним из моих приложений, что ответом на этот вопрос является отчетливое НЕТ, что, хотя Wi-Fi включен, приемник широковещательной передачи, прослушивающий мобильные данные CONNECTIVITY_CHANGE, не получает широковещательное уведомление, когда это событие происходит. Если я ошибаюсь и что-то упустил, пожалуйста, дайте мне знать.
Мое приложение — это виджет домашнего экрана с двумя классами: ActiveMobileData — это AppWidgetProvider, а ConnectivityChangeReceiver — это BroadcastReceiver. Класс AppWidgetProvider — это мое первое приложение, которое я собрал в начале этого года, в основном из кода, широко доступного в книге, на StackOverflow, в различных блогах и т. д. Нет никакого приложения, только виджет на главном экране. Он просто переключает значок на главном экране между красным и зеленым, чтобы указать текущее состояние мобильных данных. Он отлично работал в течение нескольких месяцев с примерно 100 пользователями.
Я решил добавить BroadcastReceiver для сбора кликов из настроек. Этот код также прост — он определяет текущее состояние мобильных данных и использует глобальную логическую переменную, установленную 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
Ниже приведен код для BroadcastReceiver...
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