【问题标题】:Broadcastreceiver to detect network is connectedBroadcastreceiver检测网络是否连接
【发布时间】:2015-10-19 18:55:24
【问题描述】:

我正在尝试获取用户连接到网络的那一刻,然后我认为BroadcastReceiver 是一个好方法......我想做的是,当用户连接到网络时知道是否此网络已连接到 Internet。

最重要的是知道 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");


    }
}

问题是当我尝试连接到没有Internet ConnectionWiFi 时,输入是这样的:

D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/RequiresLoginBroadcast﹕ 1 //this occurs sometimes

根据Handling Network Sign-On 文档,我已将Inner Class 更改为此

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;

到目前为止我一直在寻找什么?

  1. How to detect when WIFI Connection has been established in Android?
  2. Android WIFI How To Detect When Specific WIFI Connection is Available
  3. BroadcastReceiver is not working (detect if wifi is connected)

还有更多......但遗憾的是我没有找到正确的答案。

TL;DR

我正在尝试做的事情是获取用户连接到网络的确切事件,然后找到一个很好的方法来检测我是否可以进行 google ping 或检查是否有连接到 Internet (仅限 WIFI,不允许 3G 连接),因为我现在使用的代码有时会失败...

我认为这是了解是否存在 Internet Connection 的好方法,因为我想知道的是检测 Wifi 是否需要浏览器登录。

我们差不多完成了...但我不明白为什么在BroadcastReceiver 上输入 4 次甚至 5 次...。有时说有 Internet connection 而没有...

【问题讨论】:

标签: android


【解决方案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>

【讨论】:

  • 那么您的代码检测到用户何时连接到特定网络?
  • 我的代码检测用户何时连接到任何类型的网络/从任何类型的网络断开连接。
  • 那么Log.d("Network", "No internet :(");表示无法连接到特定网络?
  • 不,这意味着用户与互联网断开连接。
  • .EXTRA_NETWORK_INFO id 已弃用!!该死的
【解决方案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>

【讨论】:

  • 你能解释一下你的代码吗?我没有要求 3g
【解决方案3】:

您需要的一切都包含在本文档中:Determining and Monitoring the Connectivity Status。也看看这个类:Connectivity.java

简单来说,步骤如下:

1.拦截CONNECTIVITY_CHANGE广播。

2.onReceive()方法中,检查是否有网络连接,是Wifi还是GPRS。

这应该很容易实现,并且应该可以正常工作。在某些情况下,与 HTC 和某些三星设备一样,如果修改了核心操作系统,行为可能会有所不同。

【讨论】:

    【解决方案4】:

    我尝试了这种方法(如下),它奏效了。尚未完全测试,但我使用类似的方式接收电池状态。这样就可以减少代码并完成工作。

    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);
    }
    

    【讨论】:

      【解决方案5】:

      NetworkChangeReceiver.java

      import android.content.BroadcastReceiver;
      import android.content.Context;
      import android.content.Intent;
      import android.net.ConnectivityManager;
      import android.net.NetworkInfo;
      import android.util.Log;
      
      public class NetworkChangeReceiver extends BroadcastReceiver {
      
          private NetworkChangeCallback callback;
      
          public NetworkChangeReceiver(NetworkChangeCallback callback) {
              this.callback = callback;
          }                                               
      
          @Override
          public void onReceive(Context context, Intent intent) {
              boolean status = isNetworkAvailable(context);
              showLog("" + status);
              if (callback != null) {
                  callback.onNetworkChanged(status);
              }
          }
      
          private boolean isNetworkAvailable(Context context) {
              try {
                  ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                  NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
                  return (activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting());
              } catch (NullPointerException e) {
                  showLog(e.getLocalizedMessage());
                  return false;
              }
          }
      
          private void showLog(String message) {
              Log.e("NetworkChangeReceiver", "" + message);
          }
      }
      

      MainActivity.java

      public class MainActivity extends AppCompatActivity implements NetworkChangeCallback { 
      
          private NetworkChangeReceiver networkChangeReceiver;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              networkChangeReceiver = new NetworkChangeReceiver(this);
          }   
      
          @Override
          protected void onPause() {
              super.onPause();
              if (networkChangeReceiver != null) {
                  unregisterReceiver(networkChangeReceiver);
              }
          }
      
          @Override
          protected void onResume() {
              super.onResume();
              IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
              registerReceiver(networkChangeReceiver, intentFilter);
          }
      
          @Override
          public void onNetworkChanged(boolean status) {
              Log.e("MainActivity","Status: " + status);
          }
      }
      

      NetworkChangeCallback.java

      public interface NetworkChangeCallback {
          void onNetworkChanged(boolean status);
      }
      

      AndroidManifest.xml

          <receiver android:name=".NetworkChangeReceiver">
              <intent-filter>
                  <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
              </intent-filter>
          </receiver>
      

      【讨论】:

      • 这只会检测用户何时从 WiFi 移动到数据网络,对吧?它不检查它是否真的是互联网连接。我的意思是你可以连接到 wifi 但需要登录,它会像连接一样触发吗?
      【解决方案6】:

      我知道这有点晚了,但对于未来的读者来说,新的和建议的方法似乎 说你应该使用 WorkManager。作为 Android X 的一部分并支持回 API 级别 14,它使检测和运行连接更改时的代码成为一项简单的任务。

      val constraints = Constraints.Builder()
          .setRequiredNetworkType(NetworkType.CONNECTED)
          .build()
      
      val myWorkRequest =
          OneTimeWorkRequestBuilder<MyWorker>()
              .setConstraints(constraints)
              .build()
      
      WorkManager.getInstance(MyApplication.context).enqueue(myWorkRequest)
      

      以及检测到连接时会执行的类:

      class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
          override fun doWork(): Result {
              doThis()
              return Result.success()
          }
      
          private fun doThis() {
              Log.d("ASDF", "::onReceive")
          }
      }
      

      其他资源:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-10
        • 1970-01-01
        • 2012-09-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多