设备断开网络连接后如何接收通知?

问题描述

| 我知道您可以编写代码来确定设备是否已连接到网络。 但是在我的应用程序中,如果设备将其状态从“网络”更改为“无网络”,我想做的就是得到通知。例如,当用户进入隧道并丢失信号时,就会发生这种情况。或者,当使用WiFi时,用户超出了接入点的范围,无法再访问Internet。 Android API是否提供了一些您可以在其中注册侦听器的工具,以便每次网络状态发生变化时都得到通知? 我找到了这段代码并尝试使用它,但是它没有任何作用。网络状态更改时,我没有收到任何通知。
public class ConnectivityManager extends PhoneStateListener{

Activity activity;
public ConnectivityManager(Activity a){
    TelephonyManager telephonyManager = (TelephonyManager)a.getSystemService(Context.TELEPHONY_SERVICE);
    telephonyManager.listen(this,PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
    activity = a;
}

@Override
public void onDataConnectionStateChanged(int state) {
    super.onDataConnectionStateChanged(state);
    switch (state) {
    case TelephonyManager.DATA_DISCONNECTED:
        new AlertDialog.Builder(activity).
        setCancelable(false).
        setTitle(\"Connection Manager\").
        setMessage(\"There is no network connection. Please connect to internet and start again.\").
        setNeutralButton(\"Ok\",new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int whichButton) {
                System.exit(0);
            }
        }).create();
        break;

    case TelephonyManager.DATA_CONNECTED:
        break;
    }
}
}
另外,我在AndroidManifest.xml中添加了适当的权限:
<uses-permission android:name=\"android.permission.INTERNET\"></uses-permission>
<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"></uses-permission>
<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"></uses-permission>
    

解决方法

        
myTelephonyManager=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

callStateListener = new PhoneStateListener(){
    public void onDataConnectionStateChanged(int state){
        switch(state){
        case TelephonyManager.DATA_DISCONNECTED:
            Log.i(\"State: \",\"Offline\");
            // String stateString = \"Offline\";
            // Toast.makeText(getApplicationContext(),// stateString,Toast.LENGTH_LONG).show();
            break;
        case TelephonyManager.DATA_SUSPENDED:
            Log.i(\"State: \",\"IDLE\");
            // stateString = \"Idle\";
            // Toast.makeText(getApplicationContext(),Toast.LENGTH_LONG).show();
            break;
        }
    }       
};                      
myTelephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); 
    ,        您可能要考虑使用
BroadcastReceiver
代替
ConnectivityManager.CONNECTIVITY_ACTION
。从文档:   网络连接发生了变化。连接已建立或丢失。受影响的网络的NetworkInfo作为附加发送。应该咨询一下发生了哪种连接事件。 与“ 5”不同,此接收器可用于WiFi和蜂窝数据连接,后者仅会通知您蜂窝网络的变化。     ,        接受的答案对我不起作用(我的平板电脑已连接到WiFi-没有3G)。以下代码为我工作:
public class ConnectivityChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context,Intent intent) {
        System.out.println(\"*** Action: \" + intent.getAction());
        if(intent.getAction().equalsIgnoreCase(\"android.net.conn.CONNECTIVITY_CHANGE\")) {
            Toast.makeText(context,\"Connection changed\",Toast.LENGTH_SHORT).show();
        }
    }
}
并更改为AndroidManifest.xml
<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />

<receiver android:name=\".custom.ConnectivityChangeReceiver\">
            <intent-filter>
                <action android:name=\"android.net.conn.CONNECTIVITY_CHANGE\" />
            </intent-filter>
</receiver>
    ,        不确定是否会有所帮助,但这看起来很相似...     ,        我通过轮询ConnectivityManager来实现此功能。
_connectivityManager = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
一旦我们有了连接管理器,就不时轮询它,然后查看您是否仍然连接
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Runnable networkStatusChecker = new Runnable() {
    public void run() {
        NetworkInfo activeNetwork = _connectivityManager.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        if(!isConnected) {
            System.out.println(\"disconnected from network\");
            networkCheckerHandle.cancel(true);
        }
    }
};
final ScheduledFuture networkCheckerHandle = scheduler.scheduleAtFixedRate(networkStatusChecker,10,SECONDS);
    ,        如果您想在Kotlin中这样做。用这个
   val isInternetWorking: Boolean by lazy {
        var success = false
        try {
            val url = URL(\"https://google.com\")
            val connection = url.openConnection() as HttpURLConnection
            connection.connectTimeout = 10000
            connection.connect()
            success = connection.responseCode === 200
        } catch (e: IOException) {
            e.printStackTrace()
        }

        return@lazy success
    }
在线程中执行此操作。     ,        您可以轻松使用Merlin和他的胡须。在这里,您还可以获得连接类型:移动或wifi。
implementation \'com.novoda:merlin:1.2.0\'

private MerlinsBeard merlinsBeard;

private NetworkChecker(Context context){

    Merlin merlin = new Merlin.Builder()
            .withConnectableCallbacks()
            .withDisconnectableCallbacks()
            .build(context);

    merlinsBeard = new MerlinsBeard.Builder().build(context);

    merlin.registerConnectable(() -> {
        Timber.d(\"Connection enabled\");
    });

    merlin.registerDisconnectable(() -> {
        Timber.d(\"Connection disabled\");
    });

    merlin.bind();
}


public boolean getConnected(){
    return merlinsBeard.isConnected();
}
    

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...