Questa potrebbe non essere la soluzione migliore. Per favore, spiega perché prima di non votare questo.
Ho utilizzato GcmTaskService
per rilevare la modifica dello stato della rete utilizzando il seguente codice. Era per un'app meteo che sto sviluppando.
public class ServiceUpdateWeather extends GcmTaskService {
private static final String TAG = ServiceUpdateWeather.class.getSimpleName();
public static final String GCM_TAG_REPEAT_CONNECTIVITY_CHANGE = "UPDATE_WEATHER_CONNECTIVITY_CHANGE";
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onInitializeTasks() {
//called when app is updated to a new version, reinstalled etc.
//you have to schedule your repeating tasks again
super.onInitializeTasks();
if (Utilities.checkIsNougat()) {
ServiceUpdateWeather.cancelConnectivityChange(getApplicationContext());
ServiceUpdateWeather.scheduleConnectivityChange(getApplicationContext());
}
}
@Override
public int onRunTask(TaskParams taskParams) {
Handler h = new Handler(getMainLooper());
if(taskParams.getTag().equals(GCM_TAG_REPEAT_CONNECTIVITY_CHANGE)) {
Log.i(TAG, "Connectivity changed task fired");
h.post(new Runnable() {
@Override
public void run() {
Toast.makeText(ServiceUpdateWeather.this, "Updating weather", Toast.LENGTH_SHORT).show();
}
});
WeatherHelper.runNetworkConnectedUpdater(ServiceUpdateWeather.this);
}
return GcmNetworkManager.RESULT_SUCCESS;
}
public static void scheduleConnectivityChange(Context context) {
try {
PeriodicTask connectivityChange = new PeriodicTask.Builder()
//specify target service - must extend GcmTaskService
.setService(ServiceUpdateWeather.class)
//repeat every 30 seconds
.setPeriod(30)
//specify how much earlier the task can be executed (in seconds)
.setFlex(10)
//tag that is unique to this task (can be used to cancel task)
.setTag(GCM_TAG_REPEAT_CONNECTIVITY_CHANGE)
//whether the task persists after device reboot
.setPersisted(true)
//if another task with same tag is already scheduled, replace it with this task
.setUpdateCurrent(true)
//set required network state, this line is optional
.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
//request that charging must be connected, this line is optional
.setRequiresCharging(false)
.build();
GcmNetworkManager.getInstance(context).schedule(connectivityChange);
Log.i(TAG, "Connectivity change task scheduled");
} catch (Exception e) {
Log.e(TAG, "Connectivity change task failed to schedule");
e.printStackTrace();
}
}
public static void cancelConnectivityChange(Context context) {
GcmNetworkManager.getInstance(context).cancelTask(GCM_TAG_REPEAT_CONNECTIVITY_CHANGE, ServiceUpdateWeather.class);
Log.v(TAG, "Connectivity change task cancelled");
}
}
Questo sembra funzionare bene per me. Non rileva immediatamente il cambiamento di connettività come fa il ricevitore broadcast. Ma funziona ogni 30 secondi se è disponibile una connessione di rete. Assicurati di chiamare
if (Utilities.checkIsNougat()) {
ServiceUpdateWeather.cancelConnectivityChange(getApplicationContext());
ServiceUpdateWeather.scheduleConnectivityChange(getApplicationContext());
}
nel metodo principale attività onCreate
durante il primo lancio di app per pianificare questa attività per la prima volta.
fonte
2017-06-11 12:37:41
AFAIK, l'idea non è quella di rilevare il cambiamento di stato, ma piuttosto utilizzare 'JobScheduler' per organizzare un lavoro di background specifico quando ci si trova su una connessione non misurata, piuttosto che tentare di modellarlo usando le trasmissioni di' CONNECTIVITY_CHANGE'. – CommonsWare
@CommonsWare Desidero ricevere una notifica quando il tipo di connessione di rete viene cambiato da 'wifi' a' cellulare 'e viceversa. Per usarlo con il targeting Android 'oreo' sono bloccato a trovare una soluzione. Hai qualche suggerimento? – Merka
@Merka: No, mi dispiace. – CommonsWare