Android WiFi 权限、广播、连接、踩坑相关记录
来源:互联网 发布:2016淘宝骗保师获刑 编辑:程序博客网 时间:2024/05/19 19:58
emmm…最近项目首页重构,UI重新弄,逻辑拆分重新写,变成我来写了…写完了,踩了好几个坑,好几个都忘记了,赶紧记一下防止都忘记了…
1.权限请求…
既然是WiFi连接,当然首先考虑到的是打开WiFi啊什么的,现在基本都是targetSdkVersion >=23了吧,这些就会有涉及到权限请求的问题.
主要是分为2个部分的权限:
1. 打开WIFI开关
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
这些权限仅仅是普通权限,直接写在清单文件里面即可…
2. 扫描WIFI信号
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
这个权限是隶属于 LOCATION 权限组,需要手动申请该权限.
权限组权限明细
https://developer.android.com/guide/topics/permissions/requesting.html
至于权限请求处理的第三方库,工具类大家自个找吧,多得是…
我这边因为除了常规的打开关闭WiFi,扫描WiFi信号还涉及到实际的业务逻辑,需要检测当前连接的是否为硬件对应的WiFi信号,同时页面和逻辑作不同的处理.撇开业务逻辑,说说常规流程和遇到的坑吧.
1.
工欲善其事必先利其器,先封装一个WifiManager对应的工具类吧,否则操作起来实在麻烦.
2.
判断WiFi是否开启(刚刚进入Activity/Fragment进行判断…)
mWifiManager.isWifiEnabled();
3.
WiFi关闭,点击申请打开WiFi,请求Manifest.permission.ACCESS_FINE_LOCATION权限.
该权限涉及到扫描WiFi列表.
4.
打开WiFi
if (!mWifiManager.isWifiEnabled()) { mWifiManager.setWifiEnabled(true);}
重点来了!!!
代码在执行到这一步的时候,小米/华为手机会弹窗出来(没有三丧,蓝绿厂的测试机,估计也差不多),是否允许打开WiFi开关,WTF…
这和权限有毛线关系,你们吃多了吧…
小米弹窗只需10秒钟,10秒钟没点击就会自动选择拒绝
华为更狠,15秒…
代码逻辑直接就在这里
试了下MOTO X的 类似于原生Google的ROM…好好地,说开就开.
所以一切逻辑请放在这个后面执行,同时以WiFi开关是否打开作为判断用户点击弹窗的结果,顺带加个延时(考虑到有的手机配置低,4系U,甚至还有”良心”诺基亚的2系U),我是延时2000毫秒.发现红米够用,能够在2000毫秒内成功开启WiFi.
在实际过程中,掺杂着业务逻辑,需要一定时间的连接动画,请务必在动画执行完以后再次判断WiFi当前状态,毕竟在连接动画中,一个手势下拉状态栏,WiFi关掉就1,2秒就搞定,否则执行动画结束后,发现逻辑继续执行,但是WiFi是关闭的就尴尬了.
5.获得WiFi列表
mWifiManager.startScan(); // 得到扫描结果 mWifiList = mWifiManager.getScanResults(); // 得到配置好的网络连接 mWifiConfiguration = mWifiManager.getConfiguredNetworks();
遍历去重,建立制定WiFi名称规则的list进行展示和连接.
连不上就直接跳转设置手动连接吧
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
以上仅仅是普通流程,主要问题还是在请求权限和打开WiFi,国内ROM设置的弹窗问题…
实际掺杂了业务逻辑后要麻烦的多,得考虑不同WiFi状态页面的显示情况和连接动画执行情况.
2.广播监听…
part.1主要涉及的是WiFi连接状态和业务逻辑.
这部分主要是对于切换WiFi开关后,通过监听对应广播后进行处理的一些情况和坑.
1.
注册广播和注销广播
/** * 注册wifi广播监听 */ private void sendReceiver() { IntentFilter filter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mWiFiReceiver = new WifiStateReceiver(); mContext.registerReceiver(mWiFiReceiver, filter); } /** * 注销wifi广播监听 */ private void stopReceiver() { if (mWiFiReceiver != null) { mContext.unregisterReceiver(mWiFiReceiver); mWiFiReceiver = null; } }
这个没什么好说的,将注册和注销放在对应的生命周期方法内即可.
2.广播部分
首先是WiFi打开关闭的广播
WifiManager.WIFI_STATE_CHANGED_ACTION
//WIFI打开和关闭... if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1); switch (wifiState) { case WifiManager.WIFI_STATE_DISABLED: //这里处理WiFi关闭以后的逻辑 break; case WifiManager.WIFI_STATE_ENABLED: break; default: break; } }
EXTRA_WIFI_STATE 对应的State有5种,分别是DISABLING、DISABLED、ENABLING、ENABLED、UNKNOWN.
我记得之前我是直接通过这个广播状态来处理整个WiFi变化的逻辑处理,但是后来发现有坑,具体什么坑,抱歉,我忘记了,2333.反正别用就对了,继续往下看.
后来对于EXTRA_WIFI_STATE,主要使用的就是 DISABLED来处理WiFi关闭的情况.至于WiFi开启则是通过 WifiManager.NETWORK_STATE_CHANGED_ACTION
当WifiManager.WIFI_STATE_ENABLED时,就能接收到NETWORK_STATE_CHANGED_ACTION.
它有6种情况,分别是CONNECTING、CONNECTED、SUSPENDED、DISCONNECTING、DISCONNECTED、UNKNOWN.
主要监听的是DISCONNECTED和CONNECTED.
它们代表的状态是 我WiFi开关是开着,但是我没有连接和我WiFi开关是开着,且我已经连接上.
需要注意的是
1.注意添加flag,防止在刚刚进入Activity/Fragment时,切换WiFi开关连接状态,同时执行广播逻辑
2.NetworkInfo.State.CONNECTED内逻辑添加延时处理(针对连接制定设备WiFi信号进行鉴权,认证逻辑处理).
在切换WiFi,且WiFi自动连接时,逻辑会先走DISCONNECTED然后才是CONNECTED,会出现当前已经获得到WIFI是对的,但是实际还没有连接上的这种情况,会导致DISCONNECTED和CONNECTED逻辑冲突,还是建议给CONNECTED逻辑进行延时处理.
3.广播接收去重的问题
每次切换WiFi时,都会重复发送,重复接收到WiFi,需要进行去重.
我这边的办法是通过判断时间来进行去重
private static final int WIFI_DISABLED = 0;private static final int WIFI_DISCONNECTED = 1;private static final int WIFI_CONNECTED = 2;private boolean forOnceByStatus(int index) { long nowTime = TimeUtils.getCurrentTimeInLong(); if ((nowTime - (index == 0 ? timeForDisabled : (index == 1 ? timeForDisconnect : timeForConnect))) > 800) { if (index == WIFI_DISABLED) { timeForDisabled = nowTime; } else if (index == WIFI_DISCONNECTED) { timeForDisconnect = nowTime; } else if (index == WIFI_CONNECTED) { timeForConnect = nowTime; } return true; } else { return false; } }
分别在DISABLED,DISCONNECTED,CONNECTED进行调用,为true才允许执行相关逻辑.
当关闭WiFi:
WIFI关闭我进来了DISCONNECTED,时间是====1509342281409
WIFI关闭我进来了DISABLED,时间是====1509342281589
当开启WiFi:
WIFI开启我进来了DISCONNECTED,时间是====1509342288210
WIFI开启我进来了CONNECTED,时间是====1509342289212
总结
总体来说,WiFi开启/关闭,扫描,连接,广播监听.API还是挺简单的,当涉及掺杂实际的业务逻辑时,就会变得贼鸡儿麻烦.
需要考虑的情况特别多,什么手动给你关WiFi,权限拒绝,弹窗拒绝,连到一半关,连接的不是指定WiFi……
还是多注意,多测试下各种情况吧.
- Android WiFi 权限、广播、连接、踩坑相关记录
- Android Wifi相关广播 -- WIFI_STATE_CHANGED_ACTION
- Android Wifi相关广播 -- NETWORK_STATE_CHANGED_ACTION
- Android网络连接相关广播
- Android网络连接相关广播
- android广播监控wifi连接状态
- Android之广播监控wifi连接状态
- android广播监控wifi连接状态
- android连接wifi相关知识
- Android —— WIFI状态相关的系统广播
- 获取android连接wifi时候的广播地址
- Android静态注册广播receiver检测WIFI连接状况变化
- Android自定义一个广播接收器BroadcastReceiver监听系统wifi连接
- Android编程实现连接Wifi(运用Wifi 相关 API)
- Android编程实现连接Wifi(运用Wifi 相关 API)
- Android编程实现连接Wifi(运用Wifi 相关 API)
- Android编程实现连接Wifi(运用Wifi 相关 API)
- android wifi 广播
- Java奇淫巧技之Lombok
- SQL SERVER命令全集
- 获取当前屏幕的宽度和高度
- Linux邮件服务器的搭建-详细步骤
- 得到一个m长度都为n的数组
- Android WiFi 权限、广播、连接、踩坑相关记录
- Python-OpenCV 处理图像(五):图像中边界和轮廓检测
- Python 对Excel操作读写
- 组合模式
- Web遇见的小问题
- SAX方式解析XML文件的方法分析,并取特定字段生成对象
- 【蓝桥杯】【猜年龄】
- Dialog 之高仿IOS
- 成为一名自由UX设计师--你“够格”吗?