使用Android N,您无法静态注册CONNECTIVITY_CHANGE意图的广播接收器。
来自http://developer.android.com/preview/features/background-optimization.html#connectivity-action Google文档建议使用Job Scheduler执行此任务。
是否可以使用Android中的Job Scheduler检测网络状态变化(LTE到wifi),反之亦然?
答案 0 :(得分:14)
是和否。
JobInfo.Builder.setRequiredNetworkType()
方法允许您安排在满足特定网络条件时运行的作业。
网络类型可以是以下三个值之一:
JobInfo.NETWORK_TYPE_NONE
:无需网络连接。JobInfo.NETWORK_TYPE_UNMETERED
:未计量 WiFi或以太网连接。JobInfo.NETWORK_TYPE_ANY
:任何网络连接(WiFi或手机)。现在,抓住......没有NETWORK_TYPE_CELLUAR。您的应用只有在蜂窝电话上仅时才会被唤醒。 (你为什么要那样做?)
另一个问题...... WiFi连接可以计量或不计量。计量连接通常是移动热点之类的东西,可以自动检测(热点可以发送特殊的DHCP选项),或者用户可以通过WiFi设置在每个网络上手动切换它。
所以,是的,您可以在JobScheduler作业上设置网络类型约束。但是,不,您没有达到您要求的粒度级别。
正如@CommonsWare所提到的,我们的想法是,除非您有充分的理由,否则您通常希望在网络连接未计量时安排与网络相关的作业。 (使用setRequiresCharging(true)
可以使用SUM( CASE WHEN a = b THEN c ELSE d END )
来延迟工作,直到工作推迟工作,这也是一个好主意。)
答案 1 :(得分:3)
这可能不是最好的解决方案。请在投票前解释原因。
我使用GcmTaskService
使用以下代码检测网络状态更改。这是我正在开发的天气应用程序。
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");
}
}
这似乎对我来说很好。它不会像广播接收器那样立即检测到连接性变化。但如果网络连接可用,它每30秒运行一次。请务必致电
if (Utilities.checkIsNougat()) {
ServiceUpdateWeather.cancelConnectivityChange(getApplicationContext());
ServiceUpdateWeather.scheduleConnectivityChange(getApplicationContext());
}
第一次启动应用时,在您的主要活动onCreate
方法中首次安排此任务。