Проверка намеренного подключения к интернету
есть ли Android Intent ACTION_XXX
, который уведомляет меня, когда подключение к интернету доступно?
Я хочу создать экземпляр a BroadcastReceiver
это уведомляет мое приложение, когда пользователь включает подключение к Интернету (по Wi-Fi, по GSM и т. д.)
может кто-нибудь помочь мне?
11 ответов:
<receiver android:name=".YOURRECEIVER"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
принятый ответ правильный. Я только добавляю код приемника для завершения:
public class NetworkStateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Log.d("app","Network connectivity change"); if(intent.getExtras()!=null) { NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO); if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) { Log.i("app","Network "+ni.getTypeName()+" connected"); } else if(intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) { Log.d("app","There's no network connectivity"); } } }
обновление до @lujop ответ:
public class NetworkStateReceiver extends BroadcastReceiver { private static final String TAG = "NetworkStateReceiver"; @Override public void onReceive(final Context context, final Intent intent) { Log.d(TAG, "Network connectivity change"); if (intent.getExtras() != null) { final ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo ni = connectivityManager.getActiveNetworkInfo(); if (ni != null && ni.isConnectedOrConnecting()) { Log.i(TAG, "Network " + ni.getTypeName() + " connected"); } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) { Log.d(TAG, "There's no network connectivity"); } } } }
MyReceiver.java
public class MyReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if(isConnected(context)) Toast.makeText(context, "Connected.", Toast.LENGTH_LONG).show(); else Toast.makeText(context, "Lost connect.", Toast.LENGTH_LONG).show(); } public boolean isConnected(Context context) { ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); boolean isConnected = activeNetwork != null && activeNetwork.isConnected(); return isConnected; } }
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application .............. <receiver android:name="com.example.broadcastreceiversample.MyReceiver" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> </application>
недостающая часть всех ответов-это напоминание о регистрации для этого действия:
IntentFilter filter = new IntentFilter(); filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); registerReceiver(your_receiver, filter);
я использую широковещание, чтобы проверить соединение каждый раз. Создайте класс для информации о соединении.
import android.content.Context; import android.content.ContextWrapper; import android.net.ConnectivityManager; import android.net.NetworkInfo; public class ConnectivityStatus extends ContextWrapper{ public ConnectivityStatus(Context base) { super(base); } public static boolean isConnected(Context context){ ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo connection = manager.getActiveNetworkInfo(); if (connection != null && connection.isConnectedOrConnecting()){ return true; } return false; } }
применить код в вашей деятельности:
private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if(!ConnectivityStatus.isConnected(getContext())){ // no connection }else { // connected } } };
Регистрация трансляции в вашей деятельности
onCreate()
способ:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout); your_activity_context.registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); .. ... .... }
не забудьте зарегистрироваться на цикл активности:
@Override protected void onResume() { super.onResume(); your_activity_context.registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } @Override protected void onPause() { super.onPause(); your_activity_context.unregisterReceiver(receiver); }
продолжая мяукать ответ МВО
вы можете включить/выключить приемник:
включить
ComponentName receiver = new ComponentName(MainActivity.this, MyReceiver.class); PackageManager pm = this.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); Toast.makeText(this, "Disabled broadcst receiver", Toast.LENGTH_SHORT).show(); }
отключить
ComponentName receiver = new ComponentName(MainActivity.this, MyReceiver.class); PackageManager pm = this.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); Toast.makeText(this, "Enabled broadcast receiver", Toast.LENGTH_SHORT).show(); }
где то же самое можно вызвать в Intent или в onCreate
этот код будет работать (во всех версиях) поскольку регистрация манифеста не будет работать для 7+(по API 25 и выше) устройства видят этот ссылке.
private void foo(){ registerReceiver(connectionBroadcastReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } private BroadcastReceiver connectionBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent == null || intent.getExtras() == null) return; ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.getState() == NetworkInfo.State.CONNECTED) { // connected } } };
NetworkInfo.isConnected()
ненадежный метод для проверки состояния интернета, он вернет true, когда есть сетевое подключение, даже если он может не иметь доступа в интернет (ex. wifi без интернета). Более надежным подходом было бы использоватьping
СCONNECTIVITY_ACTION
BroadcastReceiver
:private void registerInternetReceiver() { if (this.internetReceiver != null) return; this.internetReceiver = new BroadcastReceiver() { @Override public void onReceive (Context context, Intent intent) { if (isInternetAvailable()) Log.i ("Tag", "internet status online"); else Log.i ("Tag", "internet status offline"); } }; IntentFilter filter = new IntentFilter(); filter.addAction (ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver (internetReceiver, filter); } private boolean isInternetAvailable() { try { return (Runtime.getRuntime().exec ("ping -c 1 google.com").waitFor() == 0); } catch (Exception ex) { ex.printStackTrace(); } return false; }
Я бы прочитал документы, обновленные для nougat +, потому что намерение устарело из-за # устройств, одной сетевой информации недостаточно. Я бы использовал команды connectivity manager (connectivity action, add variables there) и vars там, потому что большинство из них изменилось только за последний год, и для тестирования включите данные ячейки всегда активные, подробные журналы и агрессивную передачу обслуживания, используйте фильтр wlan, если это необходимо:
https://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION
из Android 7++, ответ @fedj не будет работать, но вы можете зарегистрировать широковещательный приемник программно.
приложения для Android 7.0 (уровень API 24) и выше не получают Connectivity_action передает, если они объявляют широковещательный приемник в их манифесте. Приложения по-прежнему будут получать CONNECTIVITY_ACTION трансляции, если они регистрируют свой BroadcastReceiver с помощью Контекст.registerReceiver () и этот контекст все еще действителен.
Comments