Подключение Broadcastreceiver для обнаружения сети
Я пытаюсь получить тот момент, когда пользователь подключается к сети, тогда я подумал, что BroadcastReceiver
- хороший подход... То, что я хотел бы сделать, - это когда пользователь подключается к сети, знаю, эта сеть имеет подключение к Интернету.
Главное знать, требуется ли WiFi для Browse Log in
Пример: Handling Network Sign-On
документация
Что я пробовал до сих пор?
Я изменил свой BroadcastReceiver
на этот
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
Log.d("Network", "Internet YAY");
} else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
if (isNetworkOnline()) {
Log.d(TAG, String.valueOf(tikis));
NetTask TeInternet = new NetTask();
TeInternet.execute("https://www.google.com");
}
}
Проблема заключается в том, что когда я пытаюсь подключиться к WiFi
без Internet Connection
, это будет следующим:
D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/RequiresLoginBroadcast﹕ 1 //this occurs sometimes
Я изменил Inner Class
на эту запись с помощью Handling Network Sign-On
документации
doInBackground()
:
protected Boolean doInBackground(String...params) {
boolean internetAccessExists = false;
String urlToBeAccessed = params[0];
final int TIMEOUT_VALUE_IN_MILLISECONDS = 15000;
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urlToBeAccessed);
urlConnection = (HttpURLConnection) url.openConnection();
//set the respective timeouts for the connection
urlConnection.setConnectTimeout(TIMEOUT_VALUE_IN_MILLISECONDS);
urlConnection.setReadTimeout(TIMEOUT_VALUE_IN_MILLISECONDS);
//the redirect check is valid only after the response headers have been received
//this is triggered by the getInputStream() method
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
if (!url.getHost().equals(urlConnection.getURL().getHost())) {
internetAccessExists = true;
}
}
//any sort of exception is considered as a redirect.
//more specific exceptions such as SocketTimeOutException and IOException can be handled as well
catch (Exception e) {
Log.d(TAG, e.toString());
} finally {
Log.d(TAG, "Finally");
urlConnection.disconnect();
}
return internetAccessExists;
Что я искал до сих пор?
И еще... но, к сожалению, я не нашел для меня правильного ответа.
TL; DR
То, что я пытаюсь сделать, это получить точное событие, которое пользователи подключают к сети, а затем получить хороший метод для обнаружения, могу ли я сделать ping Google или проверить, есть ли соединение с Интернетом (ТОЛЬКО С WIFI, ПОДКЛЮЧЕНИЕ 3G НЕ РАЗРЕШАЕТСЯ), потому что код, который я использую в данный момент, иногда не работает...
Я думаю, что это хороший метод, чтобы узнать, есть ли Internet Connection
, поскольку вещь, которую я хочу знать, определяет, требуется ли Wifi для входа в браузер.
Мы почти закончили... Но я не понимаю, почему вступает в BroadcastReceiver
4 раза или даже 5.... и иногда говорит, что там Internet Connection
, когда нет...
Ответы
Ответ 1
Это то, что я сейчас использую, и он отлично работает. Я получаю уведомление, когда интернет подключен (не только включен, когда есть фактическое подключение к Интернету).
Он также работает для любого типа подключения к данным, но его можно легко модифицировать, чтобы принимать только WiFi, 3G, 4G и т.д.
код:
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
Log.d("Network", "Internet YAY");
} else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
Log.d("Network", "No internet :(");
}
}
}
}
манифеста:
<receiver
android:name=".receivers.NetworkReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Ответ 2
public abstract class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (null != intent) {
State wifiState = null;
State mobileState = null;
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
wifiState = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
mobileState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
if (wifiState != null && mobileState != null
&& State.CONNECTED != wifiState
&& State.CONNECTED == mobileState) {
// phone network connect success
gNetwork();
} else if (wifiState != null && mobileState != null
&& State.CONNECTED != wifiState
&& State.CONNECTED != mobileState) {
// no network
noNetwork();
} else if (wifiState != null && State.CONNECTED == wifiState) {
// wift connect success
WIFINetwork();
}
}
}
}
манифест установлен
<receiver android:name=".receiver.AssistantReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Ответ 3
Все, что вам нужно, описано в этом документе: Определение и мониторинг состояния подключения. Также посмотрите на этот класс: Connectivity.java
.
Вкратце, шаги должны быть следующими:
1. Перехватите трансляцию CONNECTIVITY_CHANGE
.
2. В onReceive()
проверьте, присутствует ли подключение к Интернету, и является ли это Wifi или GPRS.
Это должно быть легко реализовать, и оно должно работать без проблем. В некоторых случаях, как и в случае с HTC и некоторыми устройствами Samsung, поведение может меняться, если основная ОС была изменена.
Ответ 4
Каждый раз, когда вы проверяете intenet с помощью широковещательного приемника
![введите описание изображения здесь]()
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>
Ответ 5
Я пробовал этот подход (см. ниже), и он работал. Еще не полностью протестирован, но я использую аналогичные для получения статуса батареи. Таким образом, меньше кода, и он выполняет эту работу.
private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
Log.d(LOG_TAG, "We have internet connection. Good to go.");
} else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
Log.d(LOG_TAG, "We have lost internet connection");
}
}
}
};
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkReceiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
if (networkReceiver != null)
unregisterReceiver(networkReceiver);
}