Android 扫描WiFi,连接WiFi¶
- win7
- Android Studio 3.0.1
概述¶
在Android应用中扫描WiFi热点。并把搜索到的WiFi热点信息显示出来。
连接、切换到指定的WiFi。
申请权限¶
申请网络和WiFi相关的权限
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
WiFi信息扫描¶
使用WifiManager.startScan()
方法开始搜索WiFi信息。
收取广播WifiManager.SCAN_RESULTS_AVAILABLE_ACTION
获得搜索结果。搜索结果是ScanResult
类。
private WifiManager mWifiManager;
// 在Fragment中获取WifiManager
mWifiManager = (WifiManager) getActivity().getApplication().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
// 启动搜索
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
mWifiManager.startScan();
注册广播,获取WiFi搜索结果
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
List<ScanResult> scanResults = mWifiManager.getScanResults();
// 获取到结果后进行其他操作...
}
}
};
将WiFi搜索结果显示出来¶
使用RecyclerView
显示搜索到的结果。提供选择功能。
/**
* WiFi搜索
* Created by Rust on 2018/5/18.
*/
public class WiFiScanFragment extends Fragment {
private static final String TAG = "WiFiScanFragment";
public static final String F_TAG = "f_tag_WiFiScanFragment";
private View mTipLayout;
private Button mRefreshWiFiBtn;
private EditText mWiFiPrefixEt;
private String mWiFiPrefix = "";
private WifiManager mWifiManager;
private WiFiReAdapter mWiFiReAdapter;
private TextView mChosenInfoTv;
public static WiFiScanFragment newFrag() {
return new WiFiScanFragment();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWifiManager = (WifiManager) getActivity().getApplication().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
getActivity().registerReceiver(mBroadcastReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Log.d(TAG, "onCreate: 注册广播");
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag_numbers_upgrade, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mTipLayout = view.findViewById(R.id.tip_layout);
mRefreshWiFiBtn = view.findViewById(R.id.refresh_wifi_btn);
mWiFiPrefixEt = view.findViewById(R.id.wifi_prefix_et);
mChosenInfoTv = view.findViewById(R.id.chosen_info_tv);
view.findViewById(R.id.top_back_iv).setOnClickListener(mOnClickListener);
view.findViewById(R.id.top_end_iv).setOnClickListener(mOnClickListener);
view.findViewById(R.id.choose_all_btn).setOnClickListener(mOnClickListener);
view.findViewById(R.id.choose_none_btn).setOnClickListener(mOnClickListener);
view.findViewById(R.id.choose_revert_btn).setOnClickListener(mOnClickListener);
mRefreshWiFiBtn.setOnClickListener(mOnClickListener);
RecyclerView wifiRv = view.findViewById(R.id.wifi_rv);
mWiFiReAdapter = new WiFiReAdapter();
wifiRv.setAdapter(mWiFiReAdapter);
wifiRv.setLayoutManager(new GridLayoutManager(getActivity(), 3));
mWiFiReAdapter.setOnItemClickListener(mOnItemClickListener);
mWiFiPrefixEt.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
mWiFiPrefix = s.toString();
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().unregisterReceiver(mBroadcastReceiver);
Log.d(TAG, "onDestroy: 销毁广播");
}
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.top_back_iv:
getActivity().finish();
break;
case R.id.top_end_iv:
if (mTipLayout.getVisibility() != View.VISIBLE) {
mTipLayout.setVisibility(View.VISIBLE);
} else {
mTipLayout.setVisibility(View.GONE);
}
break;
case R.id.refresh_wifi_btn:
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
mWifiManager.startScan();
mRefreshWiFiBtn.setText("扫描中..");
ToastUtil.showShort(getActivity(), "开始扫描");
break;
case R.id.choose_all_btn:
mWiFiReAdapter.chooseAll();
updateChosenNoteUI();
break;
case R.id.choose_none_btn:
mWiFiReAdapter.chooseNone();
updateChosenNoteUI();
break;
case R.id.choose_revert_btn:
mWiFiReAdapter.chooseRevert();
updateChosenNoteUI();
break;
}
}
};
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
List<ScanResult> scanResults = mWifiManager.getScanResults();
mWiFiReAdapter.clearList();
String lowerPrefix = mWiFiPrefix.toLowerCase();
ToastUtil.showShort(getActivity(), "扫描结束");
mRefreshWiFiBtn.setText("刷新");
for (ScanResult s : scanResults) {
// Log.d(TAG, "onReceive: " + s);
if (!TextUtils.isEmpty(s.SSID) && s.SSID.toLowerCase().startsWith(lowerPrefix)) {
mWiFiReAdapter.addOrUpdateWiFiScanResult(s);
}
}
mWiFiReAdapter.notifyDataSetChanged();
updateChosenNoteUI();
}
}
};
public void updateChosenNoteUI() {
mChosenInfoTv.setText(String.format(Locale.CHINA, "已选:%d", mWiFiReAdapter.getChosenWiFi().size()));
}
private WiFiAdapterOnItemClickListener mOnItemClickListener = new WiFiAdapterOnItemClickListener() {
@Override
public void onItemClick(int pos) {
mWiFiReAdapter.revertChosen(pos);
updateChosenNoteUI();
}
};
private class WiFiReAdapter extends RecyclerView.Adapter<WVH> {
private WiFiAdapterOnItemClickListener onItemClickListener;
private List<WiFiItem> wifiList;
WiFiReAdapter() {
wifiList = new ArrayList<>(20);
}
void setOnItemClickListener(WiFiAdapterOnItemClickListener listener) {
this.onItemClickListener = listener;
}
void clearList() {
wifiList.clear();
}
void addOrUpdateWiFiScanResult(ScanResult scanResult) {
boolean has = false;
for (WiFiItem item : wifiList) {
if (item.scanResult.SSID.equals(scanResult.SSID)) {
has = true;
item.scanResult = scanResult;
}
}
if (!has) {
wifiList.add(new WiFiItem(scanResult));
}
}
void chooseAll() {
for (WiFiItem i : wifiList) {
i.chosen = true;
}
notifyDataSetChanged();
}
void chooseNone() {
for (WiFiItem i : wifiList) {
i.chosen = false;
}
notifyDataSetChanged();
}
void chooseRevert() {
for (WiFiItem i : wifiList) {
i.chosen = !i.chosen;
}
notifyDataSetChanged();
}
void revertChosen(final int pos) {
WiFiItem item = wifiList.get(pos);
item.chosen = !item.chosen;
notifyItemChanged(pos);
}
List<ScanResult> getChosenWiFi() {
List<ScanResult> res = new ArrayList<>();
for (WiFiItem item : wifiList) {
if (item.chosen) {
res.add(item.scanResult);
}
}
return res;
}
@Override
public WVH onCreateViewHolder(ViewGroup parent, int viewType) {
return new WVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_wifi, parent, false));
}
@Override
public void onBindViewHolder(WVH holder, final int position) {
final int pos = position;
WiFiItem item = wifiList.get(pos);
holder.ssidTv.setText(item.scanResult.SSID);
holder.chosenCb.setChecked(item.chosen);
holder.itemRoot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != onItemClickListener) {
onItemClickListener.onItemClick(pos);
}
}
});
}
@Override
public int getItemCount() {
return wifiList.size();
}
}
static class WiFiItem {
boolean chosen = false;
ScanResult scanResult;
WiFiItem(ScanResult s) {
scanResult = s;
}
}
static class WVH extends RecyclerView.ViewHolder {
View itemRoot;
CheckBox chosenCb;
TextView ssidTv;
TextView noteTv;
WVH(View itemView) {
super(itemView);
itemRoot = itemView;
chosenCb = itemView.findViewById(R.id.chosen_cb);
ssidTv = itemView.findViewById(R.id.ssid_tv);
noteTv = itemView.findViewById(R.id.note_tv);
}
}
public interface WiFiAdapterOnItemClickListener {
void onItemClick(final int pos);
}
}
连接WiFi¶
创建连接WiFi的帮助类;连接WiFi需要WifiManager
检查目标SSID是否已经被保存
private static WifiConfiguration getExistsCfg(String SSID, final WifiManager wifiManager) {
List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
return existingConfig;
}
}
return null;
}
创建wpa加密的WiFi配置,接下来连接到这个WiFi需要这些信息
private static WifiConfiguration createWpaWifiInfo(String SSID, String password) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
config.preSharedKey = "\"" + password + "\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
// 此处需要修改否则不能自动重联
// config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
return config;
}
连接到指定WiFiWifiConfiguration
;如果wifiManager.addNetwork
返回值是-1,表示操作失败
如果切换WiFi成功,会在广播中收到WifiManager.NETWORK_STATE_CHANGED_ACTION
private static void connectToWiFi(WifiConfiguration config, final WifiManager wifiManager) {
int wcgID = wifiManager.addNetwork(config);
android.util.Log.d(TAG, LOG_PRE + "connectToWiFi: " + config.SSID + "; res==" + wcgID);
if (wcgID == -1) {
android.util.Log.d(TAG, LOG_PRE + "操作失败");
}
boolean enRes = wifiManager.enableNetwork(wcgID, true);
Log.d(TAG, LOG_PRE + "切换到WiFi: " + config.SSID + "; enable " + enRes);
}
操作WiFi时,就像操作蓝牙一样,可能会需要自定义一些延时,给系统调用硬件设备一些时间。
public class NUHelper {
private static final String TAG = "NU";
private static final String LOG_PRE = "Helper - ";
private static final String DEF_WIFI_PWD = "88888888";
public static int mSwitchWiFiWaitMM = 3000; // 切换WiFi时等待的最小时间
/**
* 当前正在处理的WiFi
*/
public static String mCurrSSID = ""; // 没有双引号包围
/**
* 连接等待池中的下一个WiFi
*/
public synchronized static void connectToNext(final ScanResult scanResult, final WifiManager wifiManager) {
mCurrSSID = scanResult.SSID;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(mSwitchWiFiWaitMM); // 等待WiFi操作
} catch (InterruptedException e) {
e.printStackTrace();
}
android.util.Log.d(TAG, LOG_PRE + "开始处理 " + mCurrSSID);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
android.util.Log.d(TAG, LOG_PRE + "当前WiFi: " + wifiInfo.getSSID());
if (wifiInfo.getSSID().equals("\"" + mCurrSSID + "\"")) {
android.util.Log.d(TAG, LOG_PRE + "是当前连接的WiFi " + mCurrSSID);
// 当前已经连接上了这个目标WiFi
} else {
WifiConfiguration cfg = getExistsCfg(mCurrSSID, wifiManager);
if (null == cfg) {
android.util.Log.d(TAG, LOG_PRE + "没有连接过这个WiFi - " + mCurrSSID);
cfg = createWpaWifiInfo(mCurrSSID, DEF_WIFI_PWD);
} else {
android.util.Log.d(TAG, LOG_PRE + "之前连接过这个WiFi - " + mCurrSSID);
}
connectToWiFi(cfg, wifiManager);
}
}
}).start();
}
}
参考资料¶
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~