Широковещательный приемник для проверки подключения к интернету в Android приложение
Я разрабатываю Android широковещательный приемник для проверки подключения к интернету.
проблема в том, что мой широковещательный приемник вызывается два раза. Я хочу, чтобы он вызывался только тогда, когда сеть доступна. Если он недоступен, я не хочу получать уведомления.
Это широковещательный приемник
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable() || mobile.isAvailable()) {
// Do something
Log.d("Network Available ", "Flag No 1");
}
}
}
это манифест.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastreceiverforinternetconnection"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
</application>
</manifest>
15 ответов:
ответ на ваш первый вопрос: ваш широковещательный приемник вызывается два раза, потому что
вы добавили два
<intent-filter>
изменение сетевого подключения:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />изменение состояния WiFi:
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />просто:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />.он будет реагировать только на одно действие вместо двух. Смотрите здесь дополнительные информация.
ответ на ваш второй вопрос (вы хотите, чтобы приемник звонил только один раз, если доступно подключение к интернету):
ваш код совершенен; вы уведомляете только тогда, когда интернет доступен.
обновление
вы можете использовать этот метод для проверки подключения, если вы хотите просто проверить, подключен ли мобильный телефон к интернету или нет.
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()); }
public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { if(checkInternet(context)) { Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show(); } } boolean checkInternet(Context context) { ServiceManager serviceManager = new ServiceManager(context); if (serviceManager.isNetworkAvailable()) { return true; } else { return false; } } }ServiceManager.java
public class ServiceManager { Context context; public ServiceManager(Context base) { context = base; } public boolean isNetworkAvailable() { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } }permissions:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
Проверьте Intenert каждый раз, используя широковещательный приемник, как и Youtube перейти к онлайн,оффлайн
https://drive.google.com/open?id=0BzBKpZ4nzNzUYjhZamFIZTh6VTQ
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <receiver android:name=".receivers.NetworkChangeReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>BroadcastReciever
package com.keshav.networkchangereceiverexample.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.util.Log; import static com.keshav.networkchangereceiverexample.MainActivity.dialog; public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { try { if (isOnline(context)) { dialog(true); Log.e("keshav", "Online Connect Intenet "); } else { dialog(false); Log.e("keshav", "Conectivity Failure !!! "); } } catch (NullPointerException e) { e.printStackTrace(); } } private boolean isOnline(Context context) { try { 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()); } catch (NullPointerException e) { e.printStackTrace(); return false; } } } ================================================================= package com.keshav.networkchangereceiverexample; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.net.ConnectivityManager; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.TextView; import com.keshav.networkchangereceiverexample.receivers.NetworkChangeReceiver; public class MainActivity extends AppCompatActivity { private BroadcastReceiver mNetworkReceiver; static TextView tv_check_connection; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_check_connection=(TextView) findViewById(R.id.tv_check_connection); mNetworkReceiver = new NetworkChangeReceiver(); registerNetworkBroadcastForNougat(); } public static void dialog(boolean value){ if(value){ tv_check_connection.setText("We are back !!!"); tv_check_connection.setBackgroundColor(Color.GREEN); tv_check_connection.setTextColor(Color.WHITE); Handler handler = new Handler(); Runnable delayrunnable = new Runnable() { @Override public void run() { tv_check_connection.setVisibility(View.GONE); } }; handler.postDelayed(delayrunnable, 3000); }else { tv_check_connection.setVisibility(View.VISIBLE); tv_check_connection.setText("Could not Connect to internet"); tv_check_connection.setBackgroundColor(Color.RED); tv_check_connection.setTextColor(Color.WHITE); } } private void registerNetworkBroadcastForNougat() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } } protected void unregisterNetworkChanges() { try { unregisterReceiver(mNetworkReceiver); } catch (IllegalArgumentException e) { e.printStackTrace(); } } @Override public void onDestroy() { super.onDestroy(); unregisterNetworkChanges(); } } ============================================================== activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.keshav.networkchangereceiverexample.MainActivity"> <TextView android:id="@+id/tv_check_connection" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Connection establised !" android:padding="25dp" app:layout_constraintBottom_toBottomOf="parent" android:gravity="center" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </LinearLayout>
используйте этот метод для проверки состояния сети:
private void checkInternetConnection() { if (br == null) { br = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); NetworkInfo info = (NetworkInfo) extras .getParcelable("networkInfo"); State state = info.getState(); Log.d("TEST Internet", info.toString() + " " + state.toString()); if (state == State.CONNECTED) { Toast.makeText(getApplicationContext(), "Internet connection is on", Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "Internet connection is Off", Toast.LENGTH_LONG).show(); } } }; final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver((BroadcastReceiver) br, intentFilter); } }Не забудьте отменить регистрацию службы в onDestroy.
Ура!!
public static boolean isNetworkAvailable(Context context) { boolean isMobile = false, isWifi = false; NetworkInfo[] infoAvailableNetworks = getConnectivityManagerInstance( context).getAllNetworkInfo(); if (infoAvailableNetworks != null) { for (NetworkInfo network : infoAvailableNetworks) { if (network.getType() == ConnectivityManager.TYPE_WIFI) { if (network.isConnected() && network.isAvailable()) isWifi = true; } if (network.getType() == ConnectivityManager.TYPE_MOBILE) { if (network.isConnected() && network.isAvailable()) isMobile = true; } } } return isMobile || isWifi; } /* You can write such method somewhere in utility class and call it NetworkChangeReceiver like below */ public class NetworkChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (isNetworkAvailable(context)) { Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show(); } } }этот выше широковещательный приемник будет вызываться только при изменении состояния сети на подключенный, а не на отключенный.
попробуйте это
public class ConnectionBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (<Check internet connection available >) { Toast.makeText(context, "connect to the internet", Toast.LENGTH_LONG).show(); /*upload background upload service*/ Intent serviceIntent = new Intent(context,<your service class>); context.startService(serviceIntent); }else{ Toast.makeText(context, "Connection faild", Toast.LENGTH_LONG).show(); } } }Это широковещательный приемник. как только подключение к интернету триггер это будет загружен
Я знаю, что этот поток старый и полностью ответил, но я чувствую, что следующее может помочь некоторым людям.
код в теле вопроса содержит ошибку, к которой здесь никто не обращался. @Nikhil проверяет, доступен ли Wi-Fi/мобильный телефон, а не подключен ли он.
исправление здесь:
@Override public void onReceive(final Context context, final Intent intent) { final ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); final android.net.NetworkInfo wifi = connMgr .getNetworkInfo(ConnectivityManager.TYPE_WIFI); final android.net.NetworkInfo mobile = connMgr .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); if (wifi.isConnected() || mobile.isConnected()) { // do stuff } }
манифест:
<receiver android:name=".your.namepackage.here.ConnectivityReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver>класс для приемника:
public class ConnectivityReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); switch (action) { case ConnectivityManager.CONNECTIVITY_ACTION: DebugUtils.logDebug("BROADCAST", "network change"); if(NetworkUtils.isConnect()){ //do action here } break; } } }и классы utils, как пример:
public class NetworkUtils { public static boolean isConnect() { ConnectivityManager connectivityManager = (ConnectivityManager) Application.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Network[] netArray = connectivityManager.getAllNetworks(); NetworkInfo netInfo; for (Network net : netArray) { netInfo = connectivityManager.getNetworkInfo(net); if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) { //if (netInfo.getState().equals(NetworkInfo.State.CONNECTED)) { Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName()); return true; } } } else { if (connectivityManager != null) { @SuppressWarnings("deprecation") NetworkInfo[] netInfoArray = connectivityManager.getAllNetworkInfo(); if (netInfoArray != null) { for (NetworkInfo netInfo : netInfoArray) { if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) { //if (netInfo.getState() == NetworkInfo.State.CONNECTED) { Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName()); return true; } } } } } return false; } }
приложения, ориентированные на Android 7.0 (уровень API 24) и выше, не получают эту трансляцию, если они объявляют широковещательный приемник в своем манифесте. Приложения по-прежнему будут получать трансляции, если они зарегистрируют свой BroadcastReceiver с контекстом.registerReceiver () и этот контекст все еще действителен.
только для тех, кто хочет зарегистрировать трансляцию динамично:
BroadcastReceiver mWifiReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (checkWifiConnect()) { Log.d(TAG, "wifi has connected"); // TODO } } }; private void registerWifiReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(mWifiReceiver, filter); } private void unregisterWifiReceiver() { mContext.unregisterReceiver(mWifiReceiver); } private boolean checkWifiConnect() { ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = manager.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected()) { return true; } return false; }
public class AsyncCheckInternet extends AsyncTask<String, Void, Boolean> { public static final int TIME_OUT = 10 * 1000; private OnCallBack listener; public interface OnCallBack { public void onBack(Boolean value); } public AsyncCheckInternet(OnCallBack listener) { this.listener = listener; } @Override protected void onPreExecute() { } @Override protected Boolean doInBackground(String... params) { ConnectivityManager connectivityManager = (ConnectivityManager) General.context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if ((networkInfo != null && networkInfo.isConnected()) && ((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) || (networkInfo .getType() == ConnectivityManager.TYPE_MOBILE))) { HttpURLConnection urlc; try { urlc = (HttpURLConnection) (new URL("http://www.google.com") .openConnection()); urlc.setConnectTimeout(TIME_OUT); urlc.connect(); if (urlc.getResponseCode() == HttpURLConnection.HTTP_OK) { return true; } else { return false; } } catch (MalformedURLException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } } else { return false; } } @Override protected void onPostExecute(Boolean result) { if (listener != null) { listener.onBack(result); } }}
добавьте широковещательный приемник, который может прослушивать изменение сетевого подключения. Затем проверьте, подключено ли устройство к интернету или нет с помощью ConnectivityManager. Обратитесь к этому post или видео для детального понимания. Ниже приведен код:
public class NetworkStateChangeReceiver extends BroadcastReceiver { public static final String NETWORK_AVAILABLE_ACTION = "com.ajit.singh.NetworkAvailable"; public static final String IS_NETWORK_AVAILABLE = "isNetworkAvailable"; @Override public void onReceive(Context context, Intent intent) { Intent networkStateIntent = new Intent(NETWORK_AVAILABLE_ACTION); networkStateIntent.putExtra(IS_NETWORK_AVAILABLE, isConnectedToInternet(context)); LocalBroadcastManager.getInstance(context).sendBroadcast(networkStateIntent); } private boolean isConnectedToInternet(Context context) { try { if (context != null) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } return false; } catch (Exception e) { Log.e(NetworkStateChangeReceiver.class.getName(), e.getMessage()); return false; } } }Я написал этот приемник, чтобы показать уведомление на экране, поэтому вы видите локальную трансляцию со статусом сети. Вот код, чтобы показать уведомление.
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter intentFilter = new IntentFilter(NetworkStateChangeReceiver.NETWORK_AVAILABLE_ACTION); LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false); String networkStatus = isNetworkAvailable ? "connected" : "disconnected"; Snackbar.make(findViewById(R.id.activity_main), "Network Status: " + networkStatus, Snackbar.LENGTH_LONG).show(); } }, intentFilter); } }Activity прослушивает намерение, передаваемое сетевым приемником, и показывает уведомление на экране.
широковещательный код приемника для проверки изменения подключения к интернету:
public class BroadCastDetecter extends BroadcastReceiver { public static boolean internet_status = false; public static void checkInternetConenction(Context context) { internet_status = false; ConnectivityManager check = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (check != null) { NetworkInfo[] info = check.getAllNetworkInfo(); if (info != null) for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { internet_status = true; } } if(internet_status) { //do what you want to if internet connection is available } } } @Override public void onReceive(Context context, Intent intent) { try { checkInternetConenction(context); }catch(Exception e){ } } }добавить в файл манифеста:
<receiver android:name=".BroadCastDetecter"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>
вот удобный способ сделать это для деятельности, фрагмента или контекста. Он также автоматически отменит регистрацию, если вы сделаете это для activity / fragment (в onDestroy), если вы хотите:
abstract class ConnectionBroadcastReceiver : BroadcastReceiver() { companion object { @JvmStatic fun registerWithoutAutoUnregister(context: Context, connectionBroadcastReceiver: ConnectionBroadcastReceiver) { context.registerReceiver(connectionBroadcastReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)) } @JvmStatic fun registerToFragmentAndAutoUnregister(context: Context, fragment: Fragment, connectionBroadcastReceiver: ConnectionBroadcastReceiver) { val applicationContext = context.applicationContext registerWithoutAutoUnregister(applicationContext, connectionBroadcastReceiver) fragment.lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun onDestroy() { applicationContext.unregisterReceiver(connectionBroadcastReceiver) } }) } @JvmStatic fun registerToActivityAndAutoUnregister(activity: AppCompatActivity, connectionBroadcastReceiver: ConnectionBroadcastReceiver) { registerWithoutAutoUnregister(activity, connectionBroadcastReceiver) activity.lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun onDestroy() { activity.unregisterReceiver(connectionBroadcastReceiver) } }) } @JvmStatic fun hasInternetConnection(context: Context): Boolean { val info = (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo return !(info == null || !info.isConnectedOrConnecting) } } override fun onReceive(context: Context, intent: Intent) { val hasConnection = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false) // Log.d("AppLog", "conenctivity changed. hasConnection? $hasConnection") onConnectionChanged(hasConnection) } abstract fun onConnectionChanged(hasConnection: Boolean) }использование в фрагмент:
ConnectionBroadcastReceiver.registerToFragmentAndAutoUnregister(activity!!, this, object : ConnectionBroadcastReceiver() { override fun onConnectionChanged(hasConnection: Boolean) { // Log.d("AppLog", "onConnectionChanged:" + hasConnection) } })
прежде всего мы сделаем класс, который будет проверять связность состояния сети. Итак, давайте создадим класс:
public class AppStatus { private static AppStatus instance = new AppStatus(); static Context context; ConnectivityManager connectivityManager; NetworkInfo wifiInfo, mobileInfo; boolean connected = false; public static AppStatus getInstance(Context ctx) { context = ctx.getApplicationContext(); return instance; } public boolean isOnline() { try { connectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); connected = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected(); return connected; } catch (Exception e) { System.out.println("CheckConnectivity Exception: " + e.getMessage()); Log.v("connectivity", e.toString()); } return connected; } }Теперь сделайте новый класс приемника вещания:
public class ConnectivityReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (AppStatus.getInstance(context).isOnline()) { Intent intent1=new Intent(context,DisplayAct.class); intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent1); } else { Toast.makeText(context, "Please !! Make your network ON", Toast.LENGTH_SHORT).show(); } } }а теперь зарегистрируйте свой широковещательный приемник в манифесте:
<receiver android:name=".ConnectivityReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver>

Comments