返回顶部
首页 > 资讯 > 精选 >如何在Android应用中连接指定的Wifi
  • 724
分享到

如何在Android应用中连接指定的Wifi

androidroiwifi 2023-05-31 08:05:41 724人浏览 泡泡鱼
摘要

如何在Android应用中连接指定的Wifi?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。代码: ....................  

如何在Android应用中连接指定的Wifi?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

代码:

 ....................  //Open按键点击后的逻辑  mOpenWifiButton.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    //WifiManager的isWifiEnabled接口,用于判断Wifi开关是否已经开启    if (!mWifiManager.isWifiEnabled()) {     //setWifiEnabled接口用于开启Wifi     mWifiManager.setWifiEnabled(true);     mMainHandler.post(mMainRunnable);    }   }  });  ....................

mMainRunnable的代码如下,主要用于判断Wifi是否开启成功。

................ private Runnable mMainRunnable = new Runnable() {  @Override  public void run() {   if (mWifiManager.isWifiEnabled()) {    //开启成功后,使能Get按键    mGetWifiInfoButton.setEnabled(true);   } else {    mMainHandler.postDelayed(mMainRunnable, 1000);   }  } }; ..............

这部分代码,主要使用了WifiManager的公有接口,开启Wifi开关及判断开启状态。
这部分操作需要的权限是:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

Get按键被点击后,对应的代码如下:

.................  mGetWifiInfoButton.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    if (mWifiManager.isWifiEnabled()) {     //getScanResults接口将返回List<ScanResult>     //ScanResult中保留了每个接入点的基本信息     mScanResultList = mWifiManager.getScanResults();     //多个接入点可能携带相同的信息,形成一个整体的Wifi覆盖网络     //因此,筛除一些冗余信息     sortList(mScanResultList);     //我使用的是RecyclerView,得到数据后,刷新界面进行显示     mWifiInfoRecyclerView.getAdapter().notifyDataSetChanged();    }   }  });  .................

上面这部分代码也比较简单,主要利用WifiManager的getScanResults接口,获取终端探索到的接入点信息。
其中,sortList的代码如下:

 .............. private void sortList(List<ScanResult> list) {  TreeMap<String, ScanResult> map = new TreeMap<>();  //demo中仅按照SSID进行筛选  //实际使用时,还可以参考信号强度等条件  for (ScanResult scanResult : list) {   map.put(scanResult.SSID, scanResult);  }  list.clear();  list.addAll(map.values()); } .............

这部分代码唯一需要注意的地方是,需要申明权限:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

同时,在高版本中还需要主动获取运行时权限。

权限的要求,是由WifiServiceImpl的实现决定的,我们以Android 7.0为例,看看对应的代码:

public List<ScanResult> getScanResults(String callingPackage) { //这里要求的是ACCESS_WIFI_STATE enforceAccessPermission(); ............ try {  ...........  if (!canReadPeerMacAddresses && !isActiveNetworkScorer    //在checkCallerCanAccessScanResults中检查了ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION    //如果没有这两个权限,就会返回一个empty List    && !checkCallerCanAccessScanResults(callingPackage, uid)) {   return new ArrayList<ScanResult>();  }  ........... } fianlly {  .......... }}

获取到信息后,就可以显示和点击列表中的Item了。

由于自己使用的是RecyclerView,因此这部分工作全部交给了对应ViewHolder:

 ............... private class ScanResultViewHolder extends RecyclerView.ViewHolder {  private View mView;  private TextView mWifiName;  private TextView mWifiLevel;  ScanResultViewHolder(View itemView) {   super(itemView);   mView = itemView;   mWifiName = (TextView) itemView.findViewById(R.id.ssid);   mWifiLevel = (TextView) itemView.findViewById(R.id.level);  }  void bindScanResult(final ScanResult scanResult) {   //将接入点的名称和强度显示到界面上   mWifiName.setText(     getString(R.string.scan_wifi_name, "" + scanResult.SSID));   mWifiLevel.setText(     getString(R.string.scan_wifi_level, "" + scanResult.level));   //点击Item后,就连接对应的接入点   mView.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {     //createWifiConfig主要用于构建一个WifiConfiguration,代码中的例子主要用于连接不需要密码的Wifi     //WifiManager的addNetwork接口,传入WifiConfiguration后,得到对应的NetworkId     int netId = mWifiManager.addNetwork(createWifiConfig(scanResult.SSID, "", WIFICIPHER_NOPASS));     //WifiManager的enableNetwork接口,就可以连接到netId对应的wifi了     //其中boolean参数,主要用于指定是否需要断开其它Wifi网络     boolean enable = mWifiManager.enableNetwork(netId, true);     Log.d("ZJTest", "enable: " + enable);     //可选操作,让Wifi重新连接最近使用过的接入点     //如果上文的enableNetwork成功,那么reconnect同样连接netId对应的网络     //若失败,则连接之前成功过的网络     boolean reconnect = mWifiManager.reconnect();     Log.d("ZJTest", "reconnect: " + reconnect);    }   });  } } .................

以上就是连接指定Wifi的基本套路,从代码中容易看出,关键问题是如何创建出有效的WifiConfiguration。
自己测试时,初始创建WifiConfiguration失败,手机怎么都没法连接到热点上,后来修改后,基本功能终于能够实现:

 .................... private static final int WIFICIPHER_NOPASS = 0; private static final int WIFICIPHER_WEP = 1; private static final int WIFICIPHER_WPA = 2; private WifiConfiguration createWifiConfig(String ssid, String passWord, int type) {  //初始化WifiConfiguration  WifiConfiguration config = new WifiConfiguration();  config.allowedAuthAlGorithms.clear();  config.allowedGroupCiphers.clear();  config.allowedKeyManagement.clear();  config.allowedPairwiseCiphers.clear();  config.allowedProtocols.clear();  //指定对应的SSID  config.SSID = "\"" + ssid + "\"";  //如果之前有类似的配置  WifiConfiguration tempConfig = isExist(ssid);  if(tempConfig != null) {   //则清除旧有配置   mWifiManager.removeNetwork(tempConfig.networkId);  }  //不需要密码的场景  if(type == WIFICIPHER_NOPASS) {   config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);  //以WEP加密的场景  } else if(type == WIFICIPHER_WEP) {   config.hiddenSSID = true;   config.wepKeys[0]= "\""+password+"\"";   config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);   config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);   config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);   config.wepTxKeyIndex = 0;  //以WPA加密的场景,自己测试时,发现热点以WPA2建立时,同样可以用这种配置连接  } else if(type == WIFICIPHER_WPA) {   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.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);   config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);   config.status = WifiConfiguration.Status.ENABLED;  }  return config; } ................. private WifiConfiguration isExist(String ssid) {  List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();  for (WifiConfiguration config : configs) {   if (config.SSID.equals("\""+ssid+"\"")) {    return config;   }  }  return null; } .................

自己写完demo后,以一个手机建立热点,分别测试了有密码和无密码的场景(对应的,需要修改createWifiConfig的传入参数)。

发现demo运行的手机在两种场景下,均能够连接到指定热点。

Demo地址如下:

https://GitHub.com/ZhangJianIsAStark/Demos/tree/master/wifitest

在本文的最后,补充一下终端作为热点时的接口。

public boolean isWifiApEnabled()

具有@Systemapi、@hide注解的公有接口,判断手机的热点是否开启。

在Android 5.1之前,这个接口没有@SystemApi注解,

于是有很多代码会利用Java发射机制,获取该方法并判断手机热点是否开启。

现在那些老代码已经没法使用了。

现在的做法(以5.1以上为例),应该利用广播接收器监听WifiManager中定义的WIFI_AP_STATE_CHANGED_ACTION。

注意到该Action也有@SystemApi注解,所以要直接监听对应的字符串,示例如下(上面链接中的demo也有涉及):

................... private BroadcastReceiver mBroadcastReceiver; private void reGISterBroadcastReceiver() {  mBroadcastReceiver = new BroadcastReceiver() {   @Override   public void onReceive(Context context, Intent intent) {    //收到广播后,利用"wifi_state"的字段,得到AP的状态    int state = intent.getIntExtra("wifi_state", 11);    Log.d("ZJTest", "AP state: " + state);   }  };  IntentFilter intentFilter = new IntentFilter();  //添加Action对应的字符信息  intentFilter.addAction("android.net.wifi.WIFI_AP_STATE_CHANGED");  this.registerReceiver(mBroadcastReceiver, intentFilter); } ......... private void unregisterBroadcastReceiver() {  this.unregisterReceiver(mBroadcastReceiver); } ..........

我暂时没有深究Wifi模块开启AP的流程。

不过从自己的测试结果来看,Wifi开启或关闭AP时,推测发送的应该是Sticky类型的广播。

于是,只要APK注册了广播监听器,立马就会得到回复,明白当前AP的状态。

例如,我在开启AP后,再打开自己的测试Demo,立马会收到如下信息:

//对应WIFI_AP_STATE_ENABLED,定义于WifiManager中,@SystemApi02-20 17:48:52.470 12773-12773/? D/ZJTest: AP state: 13

手动关闭AP后可以得到如下结果:

//WIFI_AP_STATE_DISABLING02-20 17:49:35.803 12773-12773/stark.a.is.zhang.wifitest D/ZJTest: AP state: 10//WIFI_AP_STATE_DISABLED02-20 17:49:36.960 12773-12773/stark.a.is.zhang.wifitest D/ZJTest: AP state: 11
public boolean setWifiApConfiguration(WifiConfiguration wifiConfig)public WifiConfiguration getWifiApConfiguration()

@SystemApi,设置和获取Wifi-AP的配置信息。

可以看出不论手机作为AP还是STA,在Framework中均利用WifiConfiguration抽象对应的配置信息,包括鉴权算法、密码、SSID、协议等。

这种设计是符合802.11协议精神的,毕竟在物理设备的角度上,AP和STA是完全对等的。只不过在实际情况中,根据各自的需求,特质化了一些组件。

实际上从底层协议来看,仅在传输这个角度上,AP和STA的主要区别仅在于收到数据帧后的处理流程不同。AP收到数据帧后,发现目的地址不是自己,就会进入转发流程;而STA可能就直接丢弃该数据帧了。当然如果从控制的角度来看,即考虑通信信令,AP和STA还是主从的关系。

public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled)

@SystemApi,改变Wifi-AP的开关状态。开启的AP,将使用参数定义的WifiConfiguration信息。

关于如何在Android应用中连接指定的Wifi问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网精选频道了解更多相关知识。

--结束END--

本文标题: 如何在Android应用中连接指定的Wifi

本文链接: https://www.lsjlt.com/news/224514.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何在Android应用中连接指定的Wifi
    如何在Android应用中连接指定的Wifi?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。代码: ....................  ...
    99+
    2023-05-31
    android roi wifi
  • Android应用中是如何判断是否成功连接了指定wifi
    本篇文章给大家分享的是有关Android应用中是如何判断是否成功连接了指定wifi,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。代码如下://通过反射的方式去判断wifi是否已...
    99+
    2023-05-31
    android roi
  • Android连接指定Wifi的方法实例代码
    本篇文章主要记录一下Android中打开Wifi、获取Wifi接入点信息及连接指接入点的方法。 自己写的demo主要用于测试接口的基本功能,因此界面及底层逻辑比较粗糙。 dem...
    99+
    2022-06-06
    方法 Android
  • Android 判断是否连接成功了指定wifi
    最近在做wifi的相关的东西,打印WifiInfo的时候 无意间发现一个参数,改参数可以查看是否连接成功了指定wifi,但是这是隐藏的,遂将其反射之。代码如下: //通过反射...
    99+
    2022-06-06
    连接 Android
  • 如何在Ubuntu18.04中连接隐藏的WiFi
    今天就跟大家聊聊有关如何在Ubuntu18.04中连接隐藏的WiFi,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。启动Ubuntu后,点击桌面右上侧倒三角。弹出下拉菜单,点击选择【w...
    99+
    2023-06-13
  • Android应用怎么利用wifi对手机进行连接
    Android应用怎么利用wifi对手机进行连接?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。首先电脑,手机连接同一个网络在Android studio中Terminal中...
    99+
    2023-05-31
    android wifi roi
  • Ubuntu如何用命令行连接wifi
    Ubuntu用命令行连接wifi的方法:使用ifconfig命令查看当前无线对应的接口名是什么。ifconfig再根据无线接口名用iwlist命令去扫描有哪些wifi。#例如接口名:wlp2s0iwlist wlp2s0 scanning ...
    99+
    2024-04-02
  • 如何在Linux系统下命令行中实现Wifi连接
    这篇文章主要讲解了“如何在Linux系统下命令行中实现Wifi连接”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何在Linux系统下命令行中实现Wifi连接”吧!无论何时要安装一款新的 L...
    99+
    2023-06-13
  • ubuntu用wifi连接android调试程序的步骤
    注:如果没有 root 权限也是可以试试,一般情况下,都需要 root 权限,才能连接成功。 1.需要确保你的开发 PC 和 Android 手机都连上了 wifi 并处于同一...
    99+
    2022-06-06
    ubuntu 程序 Android
  • Linux终端中如何使用Nmcli命令连接WiFi
    小编给大家分享一下Linux终端中如何使用Nmcli命令连接WiFi,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!nmcli命令是redhat7或者centos7...
    99+
    2023-06-27
  • php如何连接指定数据库
    要连接指定的数据库,可以使用PHP的mysqli扩展或PDO扩展。下面是使用mysqli扩展连接指定数据库的示例代码:```php/...
    99+
    2023-10-10
    php 数据库
  • 定时任务如何在Android应用中实现
    本篇文章给大家分享的是有关定时任务如何在Android应用中实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。首先要在AndroidManifest.xml中进行注册<r...
    99+
    2023-05-31
    android roi
  • 如何在Android应用中实现自定义View
    本篇文章为大家展示了如何在Android应用中实现自定义View,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Android自定义view的种类自定义view大概可以分为四个大类,主要是通过实现方式...
    99+
    2023-05-31
    android view roi
  • Linux系统中如何通过命令连接wifi
    Linux系统中如何通过命令连接wifi,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在我们安装Linux系统之后第一件事就是联网了,大多数人选择通过有线进行联网,本片文章和大...
    99+
    2023-06-28
  • win11如何查看已连接的wifi密码
    本文小编为大家详细介绍“win11如何查看已连接的wifi密码”,内容详细,步骤清晰,细节处理妥当,希望这篇“win11如何查看已连接的wifi密码”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。win11查看已连...
    99+
    2023-07-02
  • Win10如何查看已连接的WiFi密码
    Win10如何查看已连接的WiFi密码?我们日常中都会经常的使用电脑,电脑如果没有安装网络,我们就可以链接wifi来进行上网,有小伙伴在使用的过程中忘记密码了,那么我们应该如何在win10中查看密码呢,如果你不知道如何查看。小编下面整理了W...
    99+
    2023-07-10
  • 如何在Android应用中自定义一个控件
    本篇文章为大家展示了如何在Android应用中自定义一个控件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。开发自定义控件的步骤:了解View的工作原理 2、 编写继承自View的子类3、 为自定义V...
    99+
    2023-05-31
    android roi
  • ajax中指定innerHTML时如何应用其中的SCRIPT
    本篇文章为大家展示了ajax中指定innerHTML时如何应用其中的SCRIPT,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 其实这...
    99+
    2024-04-02
  • 如何在 Go 应用程序中指定 Windows 文件路径?
    在Go语言应用程序中指定Windows文件路径并不复杂。首先,我们需要使用filepath包中的Join函数来拼接路径。然后,我们可以使用os包中的Chdir函数将当前工作目录切换到指...
    99+
    2024-02-13
    go语言
  • Notification如何在Android应用中使用
    Notification如何在Android应用中使用?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Android  Notification使用详解...
    99+
    2023-05-31
    android notification roi
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作