android开发wifi列表名字重复,Android日常踩坑之——自定义WiFi获取列表

本文介绍了在Android应用中实现自定义WiFi功能时遇到的WiFi列表名字重复问题及其解决方案。通过MVP模式,实现扫描、显示WiFi列表,并处理已连接WiFi的状态显示,以及连接WiFi的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

又到了程序猿日常踩坑的时间了,前段时间,做了一个定制化WiFi相关的功能,最近几天空闲,把踩坑的心路历程分享给大家。

需求分析

对于很多应用来说,都不愿意跳转到系统的设置去配置WiFi的信息,那样容易造成APP的整体风格出现混乱。所以,我们就需要自己定制化WiFi相关的模块功能。

具体实现

功能逻辑流程图。

93fefd16f73c

WiFi流程逻辑 .png

功能实现

开始的开始,我们还是孩子(咳咳。。。。)严肃一点,我们要添加获取WiFi和网络的权限

我们需要在界面上设置一个switchButton来根据系统的WiFi状态进行区别

mSwitchButton.setChecked(mWifiManager.isWifiEnabled()); //获取当前系统的WiFi状态,设置btn状态

mSwitchButton.setOnCheckedChangeListener((view, isChecked) -> {

mWifiManager.setWifiEnabled(isChecked);

//更新列表

if (isChecked) {

Toast.makeText(WifiActivity.this, "打开", Toast.LENGTH_SHORT).show();

//第二次点击的时候,清除之前的list

isRefresh = true;

presenter.subscribe(isRefresh);

} else {

Toast.makeText(WifiActivity.this, "关闭", Toast.LENGTH_SHORT).show();

listView.setVisibility(View.GONE);

}

});

//这里是根据适配器进行适配数据

mListAdapter = new WifiListAdapter(this, mScanResults);

listView.setAdapter(mListAdapter);

采用MVP的模式对WiFi获取的数据进行加载。别问我为什么,任性。刚学,就是想用。

3.1 View层,在View层调用Presenter层的接口,实现界面的刷新

/**

* 将数据显示在View上

*

* @param list

*/

@Override

public void displayWifiList(List list) {

listView.setVisibility(View.VISIBLE);

mListAdapter.addAll(list);

Log.i(TAG, "displayWifiList: " + list.toString());

}

3.2 model层,通过扫描周边WiFi信号,获取WiFi信号列表。

public void search() {

new Thread(() -> {

//注册接收WIFI扫描结果的监听类对象

mContext.registerReceiver(mWifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

//开始扫描

mWifiManager.startScan();

mLock.lock();

//阻塞等待扫描结果

try {

mIsWifiScanCompleted = false;

mCondition.await(WIFI_SEARCH_TIMEOUT, TimeUnit.SECONDS);

if (!mIsWifiScanCompleted) {

mSearchWifiListener.onSearchWifiFailed(ErrorType.SEARCH_WIFI_TIMEOUT);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

mLock.unlock();

//删除注册的监听类对象

mContext.unregisterReceiver(mWifiReceiver);

}).start();

}

3.3 好了,到了MVP最为重要的一层,Presenter层了。这一层就是一个中间枢纽的作用,获取model层传递过来的数据,调用View层刷新界面的接口方法,就可以实现啦。

public void search() {

new Thread(() -> {

//注册接收WIFI扫描结果的监听类对象

mContext.registerReceiver(mWifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

//开始扫描

mWifiManager.startScan();

mLock.lock();

//阻塞等待扫描结果

try {

mIsWifiScanCompleted = false;

mCondition.await(WIFI_SEARCH_TIMEOUT, TimeUnit.SECONDS);

if (!mIsWifiScanCompleted) {

mSearchWifiListener.onSearchWifiFailed(ErrorType.SEARCH_WIFI_TIMEOUT);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

mLock.unlock();

//删除注册的监听类对象

mContext.unregisterReceiver(mWifiReceiver);

}).start();

}

4.走到这里,我们其实已经完成了一半的工作了。接下来就是,我们去连接指定的WiFi和断开连接这些细小的逻辑。

4.1 自动连接已经配置好的WiFi,判断WiFi列表中是否有已经配置过得WiFi

//根据ssid判断该wifi是否连接

public boolean isCurrentConnect(String ssID) {

ssID = "\"" + ssID + "\"";

WifiInfo info = getWifiInfo();

Log.i(TAG, "isCurrentConnect: "+info.getBSSID());

//当前的ssid为空,未连接wifi

if (TextUtils.isEmpty(info.getSSID())) {

return false;

} else {//已连接

String tempSSID = info.getSSID();

return tempSSID.equals(ssID);

}

}

然后在适配器中,根据返回的值进行匹配,显示已连接

if(wifiItemId != -1){

if(mWifiSearch.isCurrentConnect(scanResult.SSID)){

holder.wifiName.setTextColor(mContext.getResources().getColor(R.color.colorBlack));

holder.wifiStatus.setText("(已连接)");

}else{

holder.wifiName.setTextColor(mContext.getResources().getColor(R.color.colorWhite));

holder.wifiStatus.setText("(已保存)");

}

}else{

holder.wifiName.setTextColor(mContext.getResources().getColor(R.color.colorWhite));

holder.wifiStatus.setText("");

}

4.2 当我们点击WiFi列表选择连接WiFi的时候,进行搜索判断

/**

* WiFi的点击事件

*/

private void settingWifi() {

listView.setOnItemClickListener((parent, view, position, id) -> {

//1、点击是已经连接的提示 已连接

//2、已保存的直接连接

//3、未保存的 输入密码连接

final ScanResult scanResult = mListAdapter.getItem(position);

int wifiItemId = -1;

if (!TextUtils.isEmpty(scanResult.SSID)) {

wifiItemId = mWifiSearch.IsConfiguration("\"" + scanResult.SSID + "\"");

}

if (wifiItemId != -1) {

if (mWifiSearch.isCurrentConnect(scanResult.SSID)) {

Toast.makeText(mContext, "该wifi已连接!", Toast.LENGTH_SHORT).show();

showDisconnDialog(scanResult.SSID);

} else {

//直接连接

// connectWifi(scanResult,);

mWifiSearch.ConnectWifi(wifiItemId);

Log.i(TAG, "settingWifi: ");

}

} else {

isAuto=false;

//密码连接

WifiPswDialog wifiPswDialog = new WifiPswDialog(mContext, new WifiPswDialog.OnCustomDialogListener() {

@Override

public void back(String str) {

showDialog();

connectWifi(scanResult, str);

isAuto=true;

}

@Override

public void cancel() {

isAuto=true;

}

}, scanResult.SSID);

wifiPswDialog.show();

}

Log.i(TAG, "onItemClick: " + scanResult.SSID + "BSSID" + scanResult.BSSID);

});

}

好了。大体的功能就是这样的,具体代码见git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值