Android 7.0 监听网络变化


声明:本文转载自https://my.oschina.net/android520/blog/1648542,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

插播一条广告→2021 ByteDance字节跳动内推←各城市、各方向的岗位都有,大量招人!


Android7.0前,Android系统前网络切换时,会发广播,业务只要监听广播即可。

public class NetChangeReceiver extends BroadcastReceiver {      private static final String ANDROID_NET_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";      @Override     public void onReceive(Context context, Intent intent) {         if(intent.getAction().equalsIgnoreCase(ANDROID_NET_CHANGE_ACTION)){             Toast.makeText(context, "Net Changed", Toast.LENGTH_SHORT).show();         }     } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="com.outman.example.androidtest">      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>      <application         android:allowBackup="true"         android:icon="@mipmap/ic_launcher"         android:label="@string/app_name"         android:roundIcon="@mipmap/ic_launcher_round"         android:supportsRtl="true">          <activity android:name=".MainActivity">             <intent-filter>                 <action android:name="android.intent.action.MAIN" />                 <category android:name="android.intent.category.LAUNCHER" />             </intent-filter>         </activity>          <receiver android:name=".NetChangeReceiver">             <intent-filter >                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>             </intent-filter>         </receiver>     </application>  </manifest>

上面代码,在Android7.0设备前,当网络切换时,能收到消息。而在Android7.0及以上设备,则无法收到。

Android7.0 行为变更上明确说明

Android 7.0 移除了三项隐式广播,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用。删除这些广播可以显著提升设备性能和用户体验。  为缓解这些问题,Android 7.0 应用了以下优化措施:  面向 Android 7.0 开发的应用不会收到 CONNECTIVITY_ACTION 广播,即使它们已有清单条目来请求接受这些事件的通知。在前台运行的应用如果使用 BroadcastReceiver 请求接收通知,则仍可以在主线程中侦听 CONNECTIVITY_CHANGE。 应用无法发送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 广播。此项优化会影响所有应用,而不仅仅是面向 Android 7.0 的应用。

解决办法

1. 大家都知道,注册广播有两种方式,一种是在AndroidManifest.xml中,另一种通过register方法。

Android文档中描述,通过在AndroidManifest.xml中注册方式,App在前后台都无法接收到广播。而通过register的方式,当App在运行时,是可以接收到广播的。

Note: A BroadcastReceiver registered with Context.registerReceiver() continues to receive these broadcasts while the app is running. 
public class MainActivity extends Activity {      private NetChangeReceiver netChangeReceiver;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          netChangeReceiver = new NetChangeReceiver();         registerReceiver(netChangeReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));     }      @Override     protected void onDestroy() {         super.onDestroy();         unregisterReceiver(netChangeReceiver);     } } 

2. 提供了一种更稳定的方式

Monitoring Network Connectivity While the App is Running Apps that are running can still listen for CONNECTIVITY_CHANGE with a registered BroadcastReceiver. However, the ConnectivityManager API provides a more robust method to request a callback only when specified network conditions are met.  NetworkRequest objects define the parameters of the network callback in terms of NetworkCapabilities. You create NetworkRequest objects with the NetworkRequest.Builder class. registerNetworkCallback() then passes the NetworkRequest object to the system. When the network conditions are met, the app receives a callback to execute the onAvailable() method defined in its ConnectivityManager.NetworkCallback class.  The app continues to receive callbacks until either the app exits or it calls unregisterNetworkCallback(). 
public class MainActivity extends Activity {      private ConnectivityManager.NetworkCallback networkCallback;     private ConnectivityManager connectivityManager;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          networkCallback = new NetworkCallbackImpl();         NetworkRequest.Builder builder = new NetworkRequest.Builder();         NetworkRequest request = builder.build();         connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);         connectivityManager.registerNetworkCallback(request, networkCallback);     }      @Override     protected void onDestroy() {         super.onDestroy();         connectivityManager.unregisterNetworkCallback(networkCallback);     }      private class NetworkCallbackImpl extends ConnectivityManager.NetworkCallback {         @Override         public void onAvailable(Network network) {             super.onAvailable(network);             Toast.makeText(getBaseContext(), "onAvailable", Toast.LENGTH_SHORT).show();         }          @Override         public void onLosing(Network network, int maxMsToLive) {             super.onLosing(network, maxMsToLive);             Toast.makeText(getBaseContext(), "onLosing", Toast.LENGTH_SHORT).show();         }          @Override         public void onLost(Network network) {             super.onLost(network);             Toast.makeText(getBaseContext(), "onLost", Toast.LENGTH_SHORT).show();         }          @Override         public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {             super.onCapabilitiesChanged(network, networkCapabilities);             Toast.makeText(getBaseContext(), "onCapabilitiesChanged", Toast.LENGTH_SHORT).show();         }          @Override         public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {             super.onLinkPropertiesChanged(network, linkProperties);             Toast.makeText(getBaseContext(), "onLinkPropertiesChanged", Toast.LENGTH_SHORT).show();         }     } } 

 

本文发表于2018年03月21日 22:38
(c)注:本文转载自https://my.oschina.net/android520/blog/1648542,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1097 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1