关闭 wifi 会导致两次调用 onReceive()

Posted

技术标签:

【中文标题】关闭 wifi 会导致两次调用 onReceive()【英文标题】:switching off wifi results in two times call to onReceive() 【发布时间】:2015-09-22 07:55:00 【问题描述】:

我正在使用广播接收器来获得 Internet 可用性。 这是代码

private BroadcastReceiver mConnReceiver = new BroadcastReceiver() 
    public void onReceive(Context context, Intent intent) 
        boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
        String reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
        boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);

        NetworkInfo currentNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);

        if (!cd.isConnectingToInternet()) 
            // Internet Connection is not present
            alert.showAlertDialog(DashBoardActivity.this,
                    "Internet Connection Error",
                    "Please connect to working Internet connection", false);
            // stop executing code by return
            return;
        

        if(currentNetworkInfo.isConnected())
            Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
        else
            Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_LONG).show();
        
    
;

@Override
protected void onResume() 
    // TODO Auto-generated method stub
    super.onResume();

    this.registerReceiver(this.mConnReceiver,
            new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    Toast.makeText(getApplicationContext(), "In resume", Toast.LENGTH_LONG).show();

当我打开 WiFi onReceive 时只调用了一次,但是当我关闭 WiFi onReceive 时调用了两次,因为上面代码中使用的弹出窗口或 Toast 出现了两次。

谁能帮忙解决这个奇怪的错误?

【问题讨论】:

【参考方案1】:
    public void onReceive(Context context, Intent intent) 
        ConnectivityManager connManager = (ConnectivityManager) context
                        .getSystemService(Context.CONNECTIVITY_SERVICE);
        activeNetworkInfo = connManager.getActiveNetworkInfo();
        if (activeNetworkInfo != null && activeNetworkInfo.isAvailable()) a
            Toast.makeText(getApplicationContext(),"Connected",Toast.LENGTH_LONG).show();
             else 
                Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_LONG).show();
            
    

【讨论】:

还是一样的效果 删除 onResume() 上的 registerReceiver ,把它放到你的 onCreate() 中。 在 Oncreate() 中做 registerReceiver; 没什么区别【参考方案2】:

我猜你没有在活动暂停时取消注册接收器。

将此添加到您的活动中

@Override
protected void onPause() 
    // TODO Auto-generated method stub
    super.onPause();

    this.unregisterReceiver(this.mConnReceiver);
    Toast.makeText(getApplicationContext(), "In pause", Toast.LENGTH_LONG).show();

【讨论】:

当我在同一个屏幕上并关闭和打开路由器时,这个错误就会出现。如果我直接从状态栏关闭并打开 wifi。总之它不会在onPause()。当我在应用程序中导航时,它进入onPause,可能是因为它只会在wifi关闭的情况下出现一次。那么问题是什么? @Bunny 在你的onReceive 中放入一个Log.d(...) 并再次检查它是否记录到logcat 两次。 因为我没有做任何更改,所以我为什么要输入Log.d(...) 并再次检查。如果我输入这个会发生什么?我猜它会给出相同的结果。 @Bunny 那么,您是如何发现onReceive 被调用了两次的?【参考方案3】:

据我了解,当我们 关闭设备中的 wifi。

使用以下代码检查 wifi 的状态并采取相应措施:

int extraWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);

    switch (extraWifiState)
    
    case WifiManager.WIFI_STATE_DISABLED:
    case WifiManager.WIFI_STATE_DISABLING:
        enableUI(false);
        break;
    case WifiManager.WIFI_STATE_ENABLED:
        ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
        while(conMan.getActiveNetworkInfo() == null || conMan.getActiveNetworkInfo().getState() != NetworkInfo.State.CONNECTED)
        
            try
            
                Thread.sleep(500);
             catch (InterruptedException e)
            
                e.printStackTrace();
            
        
        update();
        enableUI(true);
        break;
    case WifiManager.WIFI_STATE_ENABLING:
        break;
    case WifiManager.WIFI_STATE_UNKNOWN:
        break;
    


它可以帮助您找到解决问题的方法。

【讨论】:

以上代码中的enableUI(false);enableUI(true);update();是什么? 无论是开机还是关机都在case WifiManager.WIFI_STATE_UNKNOWN:case.什么问题? 对不起,忽略它。删除它并重试@Bunny 你无法获取WIFI_STATE 这是特定手机的问题吗?

以上是关于关闭 wifi 会导致两次调用 onReceive()的主要内容,如果未能解决你的问题,请参考以下文章

多次 onReceive 使用会导致重复的 API 调用

BroadcastReceiver的onReceive方法是否会在动态注册时被调用?

如果我关闭活动,从 BroadcastReceiver.onReceive 调用 peekService 将返回 null

快速关闭然后打开导致加载两次

访问冲突 - 为啥基类析构函数被调用两次? [关闭]

当 Publisher 参数没有要发出的任何新值时,为啥会调用 SwiftUI View 上的 onReceive 块?