Android 的数据保护程序关闭时获取 "BLOCKED" 网络状态
Getting "BLOCKED" network state when Android's data saver is off
我正在开发要在特定平板电脑上使用的应用程序 运行ning Android 7.0。我正在使用 Service
定期发送 DatagramPacket
。 我只能使用移动网络。我使用 ConnectivityManager
、NetworkInfo
和 DetailedState
检查连接状态。我使用此代码获取网络状态:
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
DetailedState networkState = activeNetwork.getDetailedState();
我的平板电脑中的流量节省程序已关闭。为了以防万一,我有运行测试来验证在屏幕关闭时没有限制,cm.getRestrictBackgroundStatus()
总是returns 1,即RESTRICT_BACKGROUND_STATUS_DISABLED,即使网络是已屏蔽。
那么,为什么网络被封锁了?我的应用程序需要特殊权限吗?我的平板电脑需要特殊配置吗?
这是正常行为。当您的屏幕被锁定时,它会使用打瞌睡模式。打瞌睡模式会关闭互联网通信和所有后台服务。您需要唤醒您的设备,然后才能通过互联网进行所有操作。 Documentations
为了给出完整的解决方案,我将回答我的问题。
why is the network blocked?
正如 Stanislav Kireev 提供的文档所指出的,这种 BLOCKED 网络状态的发生是因为设备处于打瞌睡状态。此设备状态不允许从 Android 6.0(API 级别 23)开始访问互联网。
但是文档还说“系统提供了一个可配置的应用程序白名单,这些应用程序可以部分免除 Doze 和 App Standby 优化”。有关更详细的说明,您可以阅读 Support for other use cases 部分。您可以通过代码或配置系统将您的应用程序添加到白名单。
Do my app need special permissions?
如果您需要通过代码将您的应用添加到白名单,您需要在清单文件中添加权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
并将此代码添加到您的 activity:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}
我从 this answer 得到了这个解决方案。
Do my tablet need special configuration?
如果需要,您可以通过设置 > 电池 > 3 点 > 电池优化 添加您的应用。在选择列表中选择所有应用,select您的应用并选择不优化选项。
我从那里得到了这个解决方案(它有更详细的解释)。
我正在开发要在特定平板电脑上使用的应用程序 运行ning Android 7.0。我正在使用 Service
定期发送 DatagramPacket
。 我只能使用移动网络。我使用 ConnectivityManager
、NetworkInfo
和 DetailedState
检查连接状态。我使用此代码获取网络状态:
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
DetailedState networkState = activeNetwork.getDetailedState();
我的平板电脑中的流量节省程序已关闭。为了以防万一,我有运行测试来验证在屏幕关闭时没有限制,cm.getRestrictBackgroundStatus()
总是returns 1,即RESTRICT_BACKGROUND_STATUS_DISABLED,即使网络是已屏蔽。
那么,为什么网络被封锁了?我的应用程序需要特殊权限吗?我的平板电脑需要特殊配置吗?
这是正常行为。当您的屏幕被锁定时,它会使用打瞌睡模式。打瞌睡模式会关闭互联网通信和所有后台服务。您需要唤醒您的设备,然后才能通过互联网进行所有操作。 Documentations
为了给出完整的解决方案,我将回答我的问题。
why is the network blocked?
正如 Stanislav Kireev 提供的文档所指出的,这种 BLOCKED 网络状态的发生是因为设备处于打瞌睡状态。此设备状态不允许从 Android 6.0(API 级别 23)开始访问互联网。
但是文档还说“系统提供了一个可配置的应用程序白名单,这些应用程序可以部分免除 Doze 和 App Standby 优化”。有关更详细的说明,您可以阅读 Support for other use cases 部分。您可以通过代码或配置系统将您的应用程序添加到白名单。
Do my app need special permissions?
如果您需要通过代码将您的应用添加到白名单,您需要在清单文件中添加权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
并将此代码添加到您的 activity:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}
我从 this answer 得到了这个解决方案。
Do my tablet need special configuration?
如果需要,您可以通过设置 > 电池 > 3 点 > 电池优化 添加您的应用。在选择列表中选择所有应用,select您的应用并选择不优化选项。
我从