相关文章推荐
干练的小刀  ·  Whl自助搜索下载器 - ...·  2 月前    · 
热心肠的雪糕  ·  Runtime.getRuntime.exe ...·  4 月前    · 
咆哮的创口贴  ·  python typing mapping ...·  1 年前    · 

Android系统的移动设备大多支持无线WLAN技术。利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能。针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不同的系统框架API,下文将按照不同的使用功能分别介绍。

扫描无线设备

该功能通常只允许在系统自带的设置应用中使用,当然如果是第三方应用的目标版本在Android 9.0即API 28以下,也可以使用该功能。扫描周围的无线设备,需要用到 android.net.wifi.WifiManager wifi管理类。

在扫描无线设备时,需要启用设备的位置开关,同时申请 Manifest.permission.ACCESS_FINE_LOCATION ="android.permission.ACCESS_FINE_LOCATION" 精确定位权限或者 Manifest.permission.ACCESS_COARSE_LOCATION ="android.permission.ACCESS_COARSE_LOCATION" 模糊定位权限。
另外,由于需要使用设备的WLAN才能扫描,所以需要申请获取设备自身wifi状态的权限 Manifest.permission.ACCESS_WIFI_STATE ="android.permission.ACCESS_WIFI_STATE"
同样扫描也会修改设备自身的wifi状态,所以也需要声明wifi状态修改的权限 Manifest.permission.CHANGE_WIFI_STATE ="android.permission.CHANGE_WIFI_STATE"

首先在可以获取上下文环境 Context 对象的位置,调用该对象的 getSystemService(String name) 方法,参数 name 值为 Context.WIFI_SERVICE ="wifi" ,返回 WifiManager wifi管理类对象。

在需要开启扫描的位置,调用 WifiManager 对象的 startScan() 方法,即可开始扫描,该方法会返回 boolean 类型的结果标志是否成功启动扫描。

虽然已经成功启动了扫描无线设备的功能,但是查看扫描结果还需要借助四大组件中负责进程间通信的广播接收器。自定义 BroadcastReceiver 的目的就是用于接收扫描结果。因此在调用 context.registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter) 方法注册该广播接收器时,通过 IntentFilter 对象设置的意图行为 addAction(String action) 传入的参数 action 值为 WifiManager.SCAN_RESULTS_AVAILABLE_ACTION ="android.net.wifi.SCAN_RESULTS" 。最终,在该类的 onReceiver(Context context, Intent intent) 方法中,可以对接收到的参数 intent 意图获取保存的结果,调用该参数的 getBooleanExtra(String key, boolean default) 方法,传入参数 key 的值为 WifiManager.EXTRA_RESULTS_UPDATED ="resultsUpdated" ,即可得到 boolean 类型的实际扫描结果。

在得到扫描结果为 true 之后,可以继续调用 WifiManager 对象的 getScanResults() 方法获取扫描结果,得到由 android.net.wifi.ScanResult 扫描结果类组成的 List 数组。

建立网络连接

通过WLAN设备可以建立网络连接,以此与其他WLAN设备通信。建立wifi连接的途径主要有两种,包括连接其他WLAN广播设备,或者与另外一个WLAN设备建立一对一连接(俗称热点连接)。之后的连接状态和通信过程,则都是主要借助 android.net.ConnectivityManager 连接管理类。获取该连接管理类对象的方法同样是在可以获取上下文环境 Context 对象的位置,调用该对象的 getSystemService(String name) 方法,参数 name 值为 Context.CONNECTIVITY_SERVICE ="connectivity" ,返回 ConnectivityManager 连接管理类对象。其后流程暂先不表,这里主要介绍如何建立wifi连接。

与其他WLAN设备建立网络连接,首先要在清单文件中声明获取wifi状态权限 Manifest.permission.ACCESS_WIFI_STATE

WLAN广播连接

在Android 10即API 29版本以前,主要依赖 WifiManager 管理类对象。而从Android10及API 29版本开始,改由 android.net.wifi.WifiNetworkSuggestion wifi网络建议类执行相关操作。

适用于API 29之前版本

通过 android.net.wifi.WifiConfiguration 的相关变量,配置要连接的WLAN设备信息,包括 SSID 对应的wifi名, preSharedKey 对应的wifi密码, allowKeyManagement 对应的加密方式等信息。
在创建并配置 WifiConfiguration 对象的相关信息之后,调用 WifiManager 对象的 addNetwork(WifiConfiguration config) 方法,将上述对象作为参数 config 的值传入,即可得到 int 类型的本地id索引值,如果添加失败,则返回的该索引值将为非正数。成功得到该索引值之后,再次调用 WifiManager 对象的 enableNetwork(int netId, boolean attemptConnect) ,其参数 netId 即得到的索引值传入,参数 attemptConnect 如果为 true 会立即尝试连接,否则只是保存该wifi信息,并不会自动连接。

一旦系统尝试连接,网络连接状态会通过系统广播实时发送,因此如果想在应用程序中实时监听网络连接状态,只需要在获取上下文环境 Context 对象的位置,注册一个自定义的 BroadcastReceiver 广播接收器。监听的 Intent 意图对象中的 action 参数值 WifiManager.RSSI_CHANGED_ACTION ="android.net.wifi.RSSI_CHANGED" 为连接的WLAN设备RSSI发生改变时的行为标签。另外可以通过意图对象的 getBundle() 等系列参数获取网络状态信息,其值均在 WifiManager 中以常量形式定义。

适用于API 29及以后版本

通过 android.net.wifi.WifiNetworkSuggestion.Builder 建造者模式的无参构造方法和 setX() 系列方法配置要连接的WLAN设备信息,包括 setSsid(String ssid) 对应的wifi名,和 setWpa2Passphrase(String passphrase) 对应设置wpa2加密模式下的密码,及其他相关参数。最终调用该对象的 build() 方法,返回建造出来的 WifiNetworkSuggestion wifi网络建议类的实例化对象。可以同时创建多个不同的 WifiNetworkSuggestion 对象,以 List 列表的形式保存。
之后调用 WifiManager 管理类对象的 addNetworkSuggestions(List<WifiNetworkSuggestion> networkSuggestions) 方法,参数 networkSUggestions 便是所有要保存的 WifiNetworkSuggestion 对象集合。返回 int 类型的结果标记添加操作是否执行成功,如果执行成功,将会返回 WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS=0 的标记值。

在网络添加成功后,同样可以通过注册自定义的 BroadcastReceiver 的方式监听网络连接状态。与API 29以前的版本不同的是,这里要监听的 Intent 意图对象中的参数 action 行为值为 WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION ="android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION" ,在该行为值下同样可以获取网络状态信息。

———————————————————————————————转载请注明出处:白少木丿—————————————————