Broadcastreceiver用于检测网络是否已连接

时间:2015-07-29 00:52:15

标签: android

我试图获得用户连接到网络的那一刻,然后我认为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");


    }
}

问题在于,当我尝试连接到WiFi而没有Internet Connection时,输入是:

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)
  4. 还有更多......但可悲的是,我没有找到正确的答案。

    TL; DR

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

    我认为这是一个很好的方法,可以知道是否有Internet Connection,因为我想知道的事情是在Wifi需要浏览器登录时检测到。

    我们差不多完成了...但我不明白为什么要进入BroadcastReceiver 4次甚至5次......有时会说那里{{1}当没有......

6 个答案:

答案 0 :(得分:23)

这就是我目前正在使用的,而且它的工作正常。当互联网连接时我会收到通知(不仅仅是打开,当有实际的互联网连接时)。
它也适用于任何类型的数据连接,但可以很容易地修改为只接受WiFi,3G,4G等。

代码:

 <div class="form-group">
        <label class="control-label col-sm-4" for="insur1">
            Insurance</label>
        <div class="col-sm-8 col-md-6">
            <select style="float: left;">
                <option>asdf</option>
                <option>asdf</option>
                <option>asdf</option>
            </select>
            <img style="float: left" src="/Images/small.png" class="img-responsive" width="20"
                height="20" alt="Info">
        </div>
    </div>

清单:

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 :(");
            }
        }
    }
}

答案 1 :(得分:10)

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>

答案 2 :(得分:4)

本文档涵盖了您需要的所有内容:Determining and Monitoring the Connectivity Status。另请查看此课程:Connectivity.java

简而言之,步骤应如下:

1。拦截CONNECTIVITY_CHANGE广播。

2。onReceive()方法中,检查是否存在互联网连接,以及是否为Wifi或GPRS。

这应该易于实现,并且应该没有任何问题。在某些情况下,与HTC和某些三星设备一样,如果核心操作系统已被修改,行为可能会有所不同。

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

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>

答案 5 :(得分:0)

我知道这有点晚了,但是对于未来的读者来说,新的建议方法似乎可以 说您应该使用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")
    }
}

其他资源: