【问题标题】:CONNECTIVITY_CHANGE deprecated in target of Android N [duplicate]在 Android N 的目标中不推荐使用 CONNECTIVITY_CHANGE [重复]
【发布时间】:2016-11-11 09:56:13
【问题描述】:

我收到广播接收器已弃用声明的警告。

<!-- NETWORK RECEIVER... -->
<receiver android:name=".utils.NetworkUtils" >
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

警告:

为 android.net.conn.CONNECTIVITY_CHANGE 声明一个广播接收器 不推荐用于以 N 及更高版本为目标的应用程序。一般来说,应用程序应该 不依赖此广播,而是使用 JobScheduler 或 GCMNetworkManager。

有没有其他方法可以在不使用过时方法的情况下使用它?

【问题讨论】:

    标签: android broadcastreceiver deprecated intentfilter android-networking


    【解决方案1】:

    我有同样的问题,我做了类似的事情。它对我有用,我希望它有所帮助。

    public class NewActivity extends AppCompatActivity {
        final static String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
        IntentFilter intentFilter;
        MyReceiver receiver;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_new);
    
            intentFilter = new IntentFilter();
            intentFilter.addAction(CONNECTIVITY_ACTION);
            receiver = new MyReceiver();
    
            if(checkForInternet()){
                loadData();
            }else{
                updateUI();
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            registerReceiver(receiver, intentFilter);
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            unregisterReceiver(receiver);
        }
    
        // Self explanatory method
        public boolean checkForInternet() {
            ConnectivityManager cm =
                    (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null &&
                    activeNetwork.isConnectedOrConnecting();
        }
    
        void loadData(){
            // do sth
        }
    
        void updateUI(){
            // No internet connection, update the ui and warn the user
        }
    
    
        private class MyReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
    
                String actionOfIntent = intent.getAction();
                boolean isConnected = checkForInternet();
                if(actionOfIntent.equals(CONNECTIVITY_ACTION)){
                    if(isConnected){
                        loadData();
                    }else{
                        updateUI();
                    }
                }
            }
        }
    }
    

    不要在清单中添加接收器,以便它只存在于此活动中。

    【讨论】:

    • 谢谢。 final static String CONNECTIVITY_ACTION 已存在于 android.net.ConnectivityManager 类中。在onCreate() 中也可以不写if(checkForInternet()){ loadData(); ...,因为它会立即从BroadcastReceiver 调用。
    • 最好使用ConnectivityManager.CONNECTIVITY_ACTION而不是自定义字符串"android.net.conn.CONNECTIVITY_CHANGE"
    【解决方案2】:

    实际上,解决此问题的最简单且正确的方法是在您的主要活动中注册接收器并删除您的清单文件中的&lt;receiver/&gt;代码。

    在主要活动中注册:

    IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
    this.registerReceiver(new YourConnectionReceiverClass(), intentFilter);
    

    【讨论】:

    • 这个实现应该在前台工作或者直到活动没有被破坏并且如果不会取消注册接收器那么应该是接收器泄漏......
    【解决方案3】:

    我们需要像这样处理连接管理器的新旧方法:

    if (SDK_INT >= LOLLIPOP) {
    
            NetworkRequest.Builder builder = new NetworkRequest.Builder();
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
            builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
            builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
            builder.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
    
            ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
    
                @Override
                public void onAvailable(Network network) {
                    super.onAvailable(network);
                    publishSubject.onNext(isOnline());
                }
    
                @Override
                public void onLost(Network network) {
                    super.onLost(network);
                    publishSubject.onNext(isOnline());
                }
    
            };
            connectivityManager.registerNetworkCallback(builder.build(), callback);
    
        } else {
    
            IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            BroadcastReceiver receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    publishSubject.onNext(isOnline());
                }
            };
            application.registerReceiver(receiver, filter);
    
        }
    

    【讨论】:

      【解决方案4】:

      Google 的官方建议是切换到JobScheduler。由于此功能仅适用于 API 级别 21 及更高级别,因此不适用于旧设备。

      幸运的是,Evernote 开发了一个向后兼容的版本:https://github.com/evernote/android-job

      【讨论】:

        【解决方案5】:

        警告似乎包含您需要使用作业调度程序的线索。这里的意图是当应用程序接收到连接时,应用程序不会将有关他们想要执行的操作的意图传达给系统。作业调度器显然避免了这些问题,并允许 Android 批量处理请求、推迟它们等等。

        需要注意的是,由于作业调度程序仅在 Android 5.0 之后才可用,因此您必须以两种方式完成工作。也许您可以使用将切换到作业调度程序的本机实现的库,another answer 列出了其中之一。

        【讨论】:

          【解决方案6】:

          到目前为止,我已经创建了一个非常简单的解决方案,可以处理所有操作系统版本。在此处查看详细答案-> https://stackoverflow.com/a/61082387/8240915

          NetworkConnectionLiveData 类将返回一个LiveData,以便我们可以轻松使用

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-10-20
            • 1970-01-01
            • 2012-11-14
            • 2016-11-20
            • 2015-07-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多