ConnectivityManager.EXTRA_NO_CONNECTIVITY всегда имеет значение false на Android Lollipop

Я использую этот фрагмент кода для обнаружения изменений состояния подключения к Интернету. Он отлично работает на Android‹5.0, но на API 21 это:

intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY)

всегда ложно. Как заставить этот код работать на Android 5.0?

Мой широковещательный приемник:

public class NetworkStateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, final Intent intent) {
        if(intent.getExtras()!=null) {
            final ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
            final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            if(networkInfo != null && networkInfo.isConnectedOrConnecting()) {
                Log.d("receiver test", "detected on");
            }
        }
        Log.d("receiver test", Boolean.toString(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY)));
        if(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d("receiver test", "detected off");
        }
    }
}

person fragon    schedule 16.04.2015    source источник


Ответы (1)


Вы можете использовать NetworkRequest, добавленный на уровне API 21.

Создайте пользовательское действие намерения:

public static final String CONNECTIVITY_ACTION_LOLLIPOP = "com.example.CONNECTIVITY_ACTION_LOLLIPOP";

Создайте новый метод registerConnectivityActionLollipop:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void registerConnectivityActionLollipop() {

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
        return;

    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder builder = new NetworkRequest.Builder();

    connectivityManager.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(Network network) {
            Intent intent = new Intent(CONNECTIVITY_ACTION_LOLLIPOP);
            intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

            sendBroadcast(intent);
        }

        @Override
        public void onLost(Network network) {
            Intent intent = new Intent(CONNECTIVITY_ACTION_LOLLIPOP);
            intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);

            sendBroadcast(intent);
        }
    });
}

Добавьте новое действие намерения в фильтр намерений и вызовите registerConnectivityActionLollipop:

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction(CONNECTIVITY_ACTION_LOLLIPOP);

registerReceiver(mBroadcastReceiver, intentFilter);
registerConnectivityActionLollipop();

Измените BroadcastReceiver для поддержки нового действия намерения:

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION) ||
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && TextUtils.equals(intent.getAction(), CONNECTIVITY_ACTION_LOLLIPOP)) {

            if (intent.getExtras() != null) {
                final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
                if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {
                    Log.d("receiver test", "detected on");
                }
            }

            Log.d("receiver test", Boolean.toString(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY)));
            if (intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
                Log.d("receiver test", "detected off");
            }
        }
    }
};
person Mattia Maestrini    schedule 19.04.2015
comment
Спасибо. Мне пришлось немного изменить ваше решение, чтобы оно соответствовало моим потребностям, но оно дало мне общее представление о том, как решить проблему с Android 5.0. - person fragon; 20.04.2015
comment
@MattiaMaestrini: Ваш код не перевернут? Разве это не должно быть intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); в onAvailable? - person Jim; 08.02.2016
comment
@ Джим Ты прав. Спасибо, что указали на это, я только что исправил ответ. - person Mattia Maestrini; 08.02.2016
comment
Итак, в основном идея состоит в том, чтобы мы повторно подняли намерение, чтобы код, который нормально работал в предыдущих SDK, мог работать в 21+, верно? Но почему бы просто не обработать это в registerConnectivityActionLollipop? Мы уже проверили бы, для какого SDK мы работаем - person Jim; 08.02.2016
comment
Я пробую ваш код. Вызываются onAvailable и onLost, но когда я проверяю intent.getAction(), это всегда android.net.conn.CONNECTIVITY_CHANGE, а не com.example.CONNECTIVITY_ACTION_LOLLIPOP - person Jim; 08.02.2016
comment
ОМГ, это так утомительно. Я категорически против вставки копий, но с тех пор, как я запустил Android, мне приходится копировать решение для вставки на этом сайте. Жалкий. - person Neon Warge; 14.02.2017