Network Changed Broadcast Receiver does not execute in One Plus Phones

后端 未结 5 803
不知归路
不知归路 2021-01-21 06:47

I have a BroadcastReciever name NetworkReciver.java that executes when Internet is Connected or Disconnected. And it is working well.

But when

5条回答
  •  北恋
    北恋 (楼主)
    2021-01-21 07:13

    In Android Nougat, Android does not broadcast for network changes to manifest registered BroadcastReceiver.

    From the Android Nogout Changes & Also mentioned in ConnectivityManager

    Monitor for changes in connectivity

    Apps targeting Android 7.0 (API level 24) and higher do not receive CONNECTIVITY_ACTION broadcasts if they declare the broadcast receiver in their manifest. Apps will still receive CONNECTIVITY_ACTION broadcasts if they register their BroadcastReceiver with Context.registerReceiver() and that context is still valid.

    Solution

    NetworkReciever does not execute when app is closed from recent apps

    I don't know why you want to get network changes after the app is closed. But in this case you have to make some periodic task with WorkManager or JobScheduler. I suggest you use WorkManager because it will work for all devices. whether JobScheduler is available only for devices >= 21 version. Here is a good example for WorkManager (It is quite easy).

    Background solution (execute when only you need)

    public class MyWorker extends Worker {
        @Override
        public Worker.Result doWork() {
    
            // get online status
    
             boolean isOnline =  isOnline(getApplicationContext());
    
            // Indicate success or failure with your return value:
            return Result.SUCCESS;
    
            // (Returning RETRY tells WorkManager to try this task again
            // later; FAILURE says not to try again.)
        }
    
        public boolean isOnline(Context context) {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            //should check null because in airplane mode it will be null
            return (netInfo != null && netInfo.isConnected());
        }
    }
    

    and schedule this Work at app start.

    public static void scheduleWork() {
    
        int TIME_INTERVAL_IN_SECONDS = 15;
        PeriodicWorkRequest.Builder photoCheckBuilder = new PeriodicWorkRequest.Builder(MyWorker .class, TIME_INTERVAL_IN_SECONDS, TimeUnit.SECONDS);
        PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();
        WorkManager instance = WorkManager.getInstance();
        if (instance != null) {
            instance.enqueueUniquePeriodicWork("TAG", ExistingPeriodicWorkPolicy.KEEP, photoCheckWork);
        }
    }
    

    Foreground solution (recommended)

    Or if you just want to receive network changes when you app is live. You can below solution.

    • Register this receiver in your BaseActivity. or create one if you don't have yet any BaseActivity.
    • Register on onStart() and unregister on onStop(). Because you may not want to invoke your UI after onStop().

    Here is BaseActivity.java

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    
    /**
     * Created by KHEMRAJ on 9/5/2018.
     */
    public class BaseActivity extends AppCompatActivity {
        NetworkReceiver receiver;
        public boolean isOnline;
    
        @Override
        protected void onStart() {
            super.onStart();
            isOnline = isOnline(this);
            // register network change receiver
            receiver = new NetworkReceiver();
            registerReceiver(receiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            // unregister network change receiver
            unregisterReceiver(receiver);
            receiver = null;
        }
    
        public class NetworkReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                isOnline = isOnline(context);
                Log.i("TAG", "Network REceiver Executed");
            }
        }
    
        public boolean isOnline(Context context) {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            //should check null because in airplane mode it will be null
            return (netInfo != null && netInfo.isConnected());
        }
    }
    

    I suggested you WorkManger only, because I created a sample earlier days with JobScheduler, EvernoteJobs, AlarmManager, [JobService][7], and WorkManager. In which I started periodic task of 15 minutes with each of these. and wrote logs of each in separate file when invoked.

    Conclusion of this test was that. WorkManager and EvernoteJobs were most efficient to do jobs. Now because EvernoteJobs will use WorkManager from next version. So I came up with WorkManager.

提交回复
热议问题