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在运行时,是可以接收到广播的。
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. 提供了一种更稳定的方式
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(); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。