当应用程序处于前台时检测 Android 7.0 Nougat 上的连接变化
Detect connectivity changes on Android 7.0 Nougat when app is in foreground
Nougat 改变了它处理 CONNECTIVITY_CHANGED 意图的方式(基本上忽略它,迫使开发人员使用作业调度程序)所以这让我想知道:
如果我有一个正在检索某些数据的应用程序(我检查了 phone 在我发出请求时是否在线,但用户正在移动并且 phone 连接到不同的 wifi 接入点,例如)但它失败了,我如何检测到连接已恢复并重试获取数据?
所以在这种情况下,我的应用程序在前台,我认为 Chrome(对于 android)具有类似的功能。
我需要自己投票吗?或者当时有什么活动是允许的吗?
运行 的应用如果使用 BroadcastReceiver 请求通知,仍然可以在其主线程上侦听 CONNECTIVITY_CHANGE
。
https://developer.android.com/about/versions/nougat/android-7.0-changes.html
虽然可以使用 Andromeda 的答案,但该解决方案并不是 Google 的预期选择。您的问题是当连接丢失时该怎么办,您需要在网络服务 returns.
时恢复操作
虽然 CONNECTIVITY_CHANGE 在技术上是可行的,但对于这种特定需求来说总是有点破解,一旦您的应用程序进入后台,它就会在 Nougat 中停止工作。您真正应该使用的是作业调度程序 API。 Google 为我们提供了许多具有不同要求和功能的选项。
- JobScheduler
在 Lollipop 中添加了 JobScheduler,并添加了一个可以等待网络连接来安排作业的调度程序。它甚至可以取决于连接的类型,检查不按流量计费或非漫游的连接。此选项没有向后兼容性,但可以在没有 Google Play 服务的情况下使用。
- GCM 网络管理器
GcmNetworkManager 是 JobScheduler 功能到 Lollipop 之前版本的直接端口,但它需要 Google Play 服务。 GcmNetworkManager 大部分已被 Firebase Job Dispatcher 弃用。
- Firebase 作业调度程序
Firebase JobDispatcher 提供了另一种方法来为 Lollipop 之前的版本安排作业,它默认使用 Google Play 服务,但可以配置为不需要此依赖项。
- 工作管理器
我刚刚编辑了这个 post 以添加 Google 用 WorkManager 替换了之前的所有三个作业调度程序,这几乎在所有方面都优于其他调度程序。您可以将作业所需的网络类型设置为 运行。您甚至可以将作业一个接一个地串联起来。
所有这些选项都将以电池友好的方式满足您的需求,即使设备从打盹模式短暂唤醒,您的作业仍会按计划进行。
Google
提供了有关各种选项的更多信息和示例
https://developer.android.com/topic/performance/scheduling.html
https://developer.android.com/topic/performance/background-optimization.html#sched-jobs
就我而言,我已经在服务中使用 CONNECTIVITY_CHANGE
过滤器订阅了广播并且它正在运行。
如何让 Service
活着是另一回事 :)
根据doc:
面向 Android 7.0(API 级别 24)及更高版本的应用如果在清单中声明其广播接收器,则不会收到 CONNECTIVITY_ACTION
广播。如果应用程序向 Context.registerReceiver()
注册了它们的 BroadcastReceiver
并且该上下文仍然有效,则它们仍会收到 CONNECTIVITY_ACTION
广播。
public class ConnectivityReceiver
{
public static boolean getWifiStatus(Context context)
{
// To get System Connectivity status
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (null != activeNetwork)
{
// Check For Wifi Status
if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return true;
else
return false;
}
return false;
}
public class NetworkMgr extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityReceiver cf = new ConnectivityReceiver();
boolean status = cf.getWifiStatus(context);
if(status)
{
Toast.makeText(context,"Wifi Connection is On.", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(context,"Wifi Connection is Off.", Toast.LENGTH_SHORT).show();
}
}
}
Nougat 改变了它处理 CONNECTIVITY_CHANGED 意图的方式(基本上忽略它,迫使开发人员使用作业调度程序)所以这让我想知道:
如果我有一个正在检索某些数据的应用程序(我检查了 phone 在我发出请求时是否在线,但用户正在移动并且 phone 连接到不同的 wifi 接入点,例如)但它失败了,我如何检测到连接已恢复并重试获取数据?
所以在这种情况下,我的应用程序在前台,我认为 Chrome(对于 android)具有类似的功能。
我需要自己投票吗?或者当时有什么活动是允许的吗?
运行 的应用如果使用 BroadcastReceiver 请求通知,仍然可以在其主线程上侦听 CONNECTIVITY_CHANGE
。
https://developer.android.com/about/versions/nougat/android-7.0-changes.html
虽然可以使用 Andromeda 的答案,但该解决方案并不是 Google 的预期选择。您的问题是当连接丢失时该怎么办,您需要在网络服务 returns.
时恢复操作虽然 CONNECTIVITY_CHANGE 在技术上是可行的,但对于这种特定需求来说总是有点破解,一旦您的应用程序进入后台,它就会在 Nougat 中停止工作。您真正应该使用的是作业调度程序 API。 Google 为我们提供了许多具有不同要求和功能的选项。
- JobScheduler
在 Lollipop 中添加了 JobScheduler,并添加了一个可以等待网络连接来安排作业的调度程序。它甚至可以取决于连接的类型,检查不按流量计费或非漫游的连接。此选项没有向后兼容性,但可以在没有 Google Play 服务的情况下使用。
- GCM 网络管理器
GcmNetworkManager 是 JobScheduler 功能到 Lollipop 之前版本的直接端口,但它需要 Google Play 服务。 GcmNetworkManager 大部分已被 Firebase Job Dispatcher 弃用。
- Firebase 作业调度程序
Firebase JobDispatcher 提供了另一种方法来为 Lollipop 之前的版本安排作业,它默认使用 Google Play 服务,但可以配置为不需要此依赖项。
- 工作管理器
我刚刚编辑了这个 post 以添加 Google 用 WorkManager 替换了之前的所有三个作业调度程序,这几乎在所有方面都优于其他调度程序。您可以将作业所需的网络类型设置为 运行。您甚至可以将作业一个接一个地串联起来。
所有这些选项都将以电池友好的方式满足您的需求,即使设备从打盹模式短暂唤醒,您的作业仍会按计划进行。
https://developer.android.com/topic/performance/scheduling.html https://developer.android.com/topic/performance/background-optimization.html#sched-jobs
就我而言,我已经在服务中使用 CONNECTIVITY_CHANGE
过滤器订阅了广播并且它正在运行。
如何让 Service
活着是另一回事 :)
根据doc:
面向 Android 7.0(API 级别 24)及更高版本的应用如果在清单中声明其广播接收器,则不会收到 CONNECTIVITY_ACTION
广播。如果应用程序向 Context.registerReceiver()
注册了它们的 BroadcastReceiver
并且该上下文仍然有效,则它们仍会收到 CONNECTIVITY_ACTION
广播。
public class ConnectivityReceiver
{
public static boolean getWifiStatus(Context context)
{
// To get System Connectivity status
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (null != activeNetwork)
{
// Check For Wifi Status
if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return true;
else
return false;
}
return false;
}
public class NetworkMgr extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityReceiver cf = new ConnectivityReceiver();
boolean status = cf.getWifiStatus(context);
if(status)
{
Toast.makeText(context,"Wifi Connection is On.", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(context,"Wifi Connection is Off.", Toast.LENGTH_SHORT).show();
}
}
}