在我的应用程序中,我有 BroadcastReceiver
,它通过 <receiver>
标记作为组件启动,过滤 android.net.conn.CONNECTIVITY_CHANGE
意图 .
我的目标只是知道何时 Build 了Wifi连接,所以我在 onReceive()
所做的是:
NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected()) {
// Wifi is connected
}
它工作正常,但在 Build Wifi连接时,我似乎总是在大约一秒钟内得到两个相同的意图 . 我试图查看我可以从意图获得的任何信息, ConnectivityManager
和 WifiManager
,但我找不到任何可以区分两种意图的信息 .
查看日志,至少还有一个 BroadcastReceiver
也接收到两个相同的意图 .
它运行在搭载Android 2.2的HTC Desire上
任何想法为什么我似乎在Wifi连接时获得“重复”的意图或两者之间的差异可能是什么?
14 回答
找到一个特殊的网络连接案例,说没有互联网,但实际上有 . 事实证明
getActiveNetworkInfo
会在特定情况下返回 DISCONNECTED/BLOCKED ,当电池电量低且app刚刚切换时更换网络看看this post
检查来自intent的networkType并比较activeNetworkInfo.getType()
如果您只想接收一次,您可以通过变量简单地控制它 .
我处理它的方式只是保存网络状态,然后比较它以查看是否有变化 .
如果这是您采用的方法,则必须在片段或活动的
onResume
中重置它,以便它保持当前值:我在我的应用程序中所有片段的父亲
BaseFragment
中做到了这一点 .经过大量的谷歌搜索和调试后,我相信这是确定Wifi连接或断开连接的正确方法 .
BroadcastReceiver中的
onReceive()
方法:与AndroidManifest.xml中的以下接收器元素一起使用
一些解释:
当只考虑
ConnectivityManager.CONNECTIVITY_ACTION
时,我总是得到两个包含相同NetworkInfo实例的意图(getType()== TYPE_WIFI和isConnected()== true)当Wifi连接时 - 这个问题中描述的问题 .当仅使用
WifiManager.NETWORK_STATE_CHANGED_ACTION
时,Wifi断开连接时没有广播意图,但两个意图包含不同的NetworkInfo实例,允许在连接Wifi时确定一个事件 .注意:我收到一个崩溃报告(NPE),其中
intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO)
返回null . 因此,即使它似乎极少发生,添加空检查也许是个好主意 .干杯,托斯滕
如果您正在收听
WifiManager.NETWORK_STATE_CHANGED_ACTION
,您将收到两次,因为NetworkInfo
中有2种方法isConnectedOrConnecting()
isConnected()
第一次
isConnectedOrConnecting()
返回true
和isConnected()
false
第二次
isConnectedOrConnecting()
和isConnected()
返回true
干杯
更新了Torsten的代码,这样当WIFI断开连接时,只会对单个适当的广播采取行动 .
使用NetworkInfo.getDetailedState()== DetailedState.DISCONNECTED进行检查 .
如果您将活动注册为目标侦听器,那么您将收到两次相同的消息 . 具体来说,您需要选择是否要在包级别(XML)或编程级别上进行侦听 .
如果您为广播接收器设置了一个类并附加了监听它并且您将一个intent过滤器附加到该活动,那么该消息将被复制两次 .
我希望这能解决你的问题 .
我通过使用SharedPref with Time解决了两次调用问题 .
因为1.call和2.call之间有小的延迟(大约200 milisec) . 因此,在IF中,第二次呼叫将停止,并且第一次呼叫将继续 .
如果在,我解决了
在
我通过使用NetworkInfo的intent额外解决了这个问题 . 在下面的示例中,如果wifi连接或移动,onReceive事件仅触发一次 .
和我的帮手:
打开WIFI时,
当MOBILE数据为ON时,发送两个广播:广播#1:MOBILE数据断开,广播#2:WIFI连接
关闭MOBILE数据时,仅发送一个广播:广播#1:连接WIFI
在上述两种条件下关闭WIFI时可以观察到类似的行为 .
要区分这两者,请遵循以下#2和#3:
这是在API 21及更高版本上注册连接更改的正确方法 . 以下代码可以放在基本活动中,这样您就可以期望应用程序中的每个屏幕(继承自此活动)获得这些回调 .
首先,创建一个网络回调,监控连接变化 .
然后,在相关位置注册并取消注册此回调 .
并在适当时取消注册 .
请注意,检查
Build.VERSION_CODES.LOLLIPOP
. 此功能仅适用于棒棒糖及以上版本 . 如果您的应用程序支持的API低于21,请务必制定如何处理Pre-Lollipop设备中的网络状态更改的计划 .只听动作“android.net.conn.CONNECTIVITY_CHANGE” . 无论何时 Build 或销毁连接,都会广播它 .
Build 连接后将播放“android.net.wifi.STATE_CHANGE” . 所以你得到两个触发器 .
请享用!