Android-событие для изменения состояния интернет-соединения
Я делаю приложение, в котором пользователь загружает информацию и файлы на мой сервер довольно часто. Это делается в новых темах через специальный сервис загрузки.
Я знаю из этой ветки
Определите, есть ли доступное интернет-соединение на Android
что вы можете проверить, есть ли подключение к интернету относительно легко. Вы также можете получить socketTimeoutExceptions для обнаружения проблем с подключением к Интернету. Все это хорошо, и позволяет мне достаточно легко кэшировать свои загрузки, когда по какой-либо причине соединение не работает.
Мой вопрос, однако, как я знаю, когда повторить попытку загрузки? При восстановлении соединения происходит событие? Или я застрял в создании нового потока, который спит, а затем проверяет подключение к Интернету каждые 30 секунд или что-то?
Любые идеи были бы хорошы!
5 ответов
Есть приемник вещания для изменений подключения. Смотрите здесь
Очень старая запись, но я хотел бы поделиться своим получателем
не нужно прикладывать руки к манифесту или другим скучным ресурсам:)
ИСПОЛЬЗОВАНИЕ
ВАША ДЕЯТЕЛЬНОСТЬ:
/*
* You need to implement NetworkStateReceiverListener.
* This interface is described inside the NewtworkStateReceiver class
*/
public class MyActivity implements NetworkStateReceiverListener {
/* ... */
private NetworkStateReceiver networkStateReceiver;
}
В ВАШЕЙ ДЕЯТЕЛЬНОСТИ: УСТАНАВЛИВАЙТЕ ПРИЕМНИК
public void onCreate(Bundle savedInstanceState) {
/* ... */
networkStateReceiver = new NetworkStateReceiver();
networkStateReceiver.addListener(this);
this.registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}
public void onDestroy() {
super.onDestroy();
networkStateReceiver.removeListener(this);
this.unregisterReceiver(networkStateReceiver);
}
В ВАШЕЙ ДЕЯТЕЛЬНОСТИ: РЕАЛИЗУЕТ ТРЕБУЕМЫЕ МЕТОДЫ
@Override
public void networkAvailable() {
Log.d("tommydevall", "I'm in, baby!");
/* TODO: Your connection-oriented stuff here */
}
@Override
public void networkUnavailable() {
Log.d("tommydevall", "I'm dancing with myself");
/* TODO: Your disconnection-oriented stuff here */
}
ПОЛУЧАТЕЛЬ
просто скопируйте и вставьте в свой проект как NetworkStateReceiver.java
public class NetworkStateReceiver extends BroadcastReceiver {
protected Set<NetworkStateReceiverListener> listeners;
protected Boolean connected;
public NetworkStateReceiver() {
listeners = new HashSet<NetworkStateReceiverListener>();
connected = null;
}
public void onReceive(Context context, Intent intent) {
if(intent == null || intent.getExtras() == null)
return;
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = manager.getActiveNetworkInfo();
if(ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
connected = true;
} else if(intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
connected = false;
}
notifyStateToAll();
}
private void notifyStateToAll() {
for(NetworkStateReceiverListener listener : listeners)
notifyState(listener);
}
private void notifyState(NetworkStateReceiverListener listener) {
if(connected == null || listener == null)
return;
if(connected == true)
listener.networkAvailable();
else
listener.networkUnavailable();
}
public void addListener(NetworkStateReceiverListener l) {
listeners.add(l);
notifyState(l);
}
public void removeListener(NetworkStateReceiverListener l) {
listeners.remove(l);
}
public interface NetworkStateReceiverListener {
public void networkAvailable();
public void networkUnavailable();
}
}
НАСЛАЖДАТЬСЯ;)
Если вы просто хотите сделать что-то простое при изменении подключения, есть гораздо более простое решение.
В своей деятельности создайте Broadcast Receiver:
private BroadcastReceiver networkStateReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = manager.getActiveNetworkInfo();
doSomethingOnNetworkChange(ni);
}
};
Затем в onResume
а также onPause
сделать регистрацию:
@Override
public void onResume() {
super.onResume();
registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}
@Override
public void onPause() {
unregisterReceiver(networkStateReceiver);
super.onPause();
}
Не совсем уверен, что происходит в приемнике вещания Томмазо, но он не работает для меня, вот моя реализация. Он только уведомляет об изменении между доступностью / недоступностью подключения.
Также я регистрирую это в onResume()
и отменить регистрацию в onPause()
, В противном случае это так же, как указано выше.
public class NetworkStateReceiver extends BroadcastReceiver {
private ConnectivityManager mManager;
private List<NetworkStateReceiverListener> mListeners;
private boolean mConnected;
public NetworkStateReceiver(Context context) {
mListeners = new ArrayList<NetworkStateReceiverListener>();
mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
checkStateChanged();
}
public void onReceive(Context context, Intent intent) {
if (intent == null || intent.getExtras() == null)
return;
if (checkStateChanged()) notifyStateToAll();
}
private boolean checkStateChanged() {
boolean prev = mConnected;
NetworkInfo activeNetwork = mManager.getActiveNetworkInfo();
mConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
return prev != mConnected;
}
private void notifyStateToAll() {
for (NetworkStateReceiverListener listener : mListeners) {
notifyState(listener);
}
}
private void notifyState(NetworkStateReceiverListener listener) {
if (listener != null) {
if (mConnected) listener.onNetworkAvailable();
else listener.onNetworkUnavailable();
}
}
public void addListener(NetworkStateReceiverListener l) {
mListeners.add(l);
notifyState(l);
}
public void removeListener(NetworkStateReceiverListener l) {
mListeners.remove(l);
}
public interface NetworkStateReceiverListener {
public void onNetworkAvailable();
public void onNetworkUnavailable();
}
}
Android Nougat & O (API 24+) - состояние сети
Внесены изменения в ответ @darnmason (конструктор), чтобы он работал на API 24+.
public NetworkStateReceiver(Context context) {
mListeners = new ArrayList<>();
mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(NetworkStateReceiver.this, intentFilter);
checkStateChanged();
}