CONNECTIVITY_CHANGE deprecated in target of Androi

2020-07-02 08:06发布

问题:

I am getting warning of deprecated declaration of Broadcast Receiver.

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

WARNING:

Declaring a broadcastreceiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general, apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager.

Is there any other way to use it without deprecated methods?

回答1:

I had the same problem, i did something like that. It worked for me, i hope it helps.

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();
                }
            }
        }
    }
}

Don't add the receiver in the manifest so that it only lives in this activity.



回答2:

Actually, the easiest and right way to resolve this problem is to just register the receiver in your main activity and remove the <receiver/> code in your Manifest file.

Register in Main Activity:

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


回答3:

Official advice from Google is to switch to JobScheduler. Since this one is available only from API level 21 and higher, it is a no-go for older devices.

Luckily, folks from Evernote create a backward compatibility version of that: https://github.com/evernote/android-job



回答4:

we need to handle old and new methods of connectivity manager like this :

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);

    }


回答5:

The warning seems to contain the clue that you need to use the job scheduler. The intent here is that the applications don't communicate the intentions to the system regarding the actions they want to do when the application receives connectivity. Job scheduler obviously avoids these problems and that allows Android to batch the requests, defer them, and so on.

The caveat is that you will have to implement doing the work both ways since the job scheduler is only available since Android 5.0. Maybe you can use the libraries which will switch to the native implementation of the job scheduler, another answer listed one of them.



回答6:

I have created a much easy solution which handles all the OS Version till now. Check Detailed Answer here -> https://stackoverflow.com/a/61082387/8240915

NetworkConnectionLiveData class will return a LiveData so we can use easily