在之前的博客文章中,我写了点在 Android 6 系统中连接到指定名称的 Wifi 的体验.然而,在 Android 7 中,有一些东西又变化了.另外就是在那篇文章中我说要提供代码,结果拖到这篇文章,也没有提供.那么,请忽略那篇文章,来看看这篇吧.

不变

首先聊下 Android 6 到 Android 7之间没有变化的一些东西.想要让设备连接到指定名称的热点,那么一定要经历以下的几个过程:

  1. 打开 Wifi
  2. 包装出 WifiConfiguration 对象
  3. WifiConfiguration 对象获得 WifiManager 对象中 WifiConfiguration 的 index
  4. 用 enableNetwork 连接网络
  5. 使用完毕,断开网络然后删除创建出的配置文件
  6. 关闭 Wifi

  1. 在 Android 6 中,如果系统中已经存在了其他的 app 或者是由系统生成的热点信息,那么它将会返回 -1,而在 Android 7上并不是这个设定,是直接返回 index 的值
  2. 在 Android 7 中,无法使用 removeNetwork 这个公开的方法删除一个已有的配置,虽然在删除后,在系统中显示已经被删除,但是当重新关闭再打开 Wifi 开关时,会发现被删除的配置由系统进行创建.这里,需要使用系统的隐藏方法 forget 进行删除

以上就是所有信息了.以下是代码:

package com.xxxxxxxx.wifitest7;

import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity"; private final static String WIFI_SSID = "TP-LINK_ACA6";
private Button mBtnOpenWifi;
private Button mBtnCloseWifi;
private Button mBtnAddWifi;
private Button mBtnDelWifi;
private Button mBtnConnect;
private Button mBtnDisConnect;
private TextView mTextViewShowResult; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initUi();
} private void initUi() {
mBtnOpenWifi = (Button) findViewById(R.id.btnOpenWifi);
mBtnOpenWifi.setOnClickListener(this);
mBtnCloseWifi = (Button) findViewById(R.id.btnCloseWifi);
mBtnCloseWifi.setOnClickListener(this);
mBtnAddWifi = (Button) findViewById(R.id.btnAddWifi);
mBtnAddWifi.setOnClickListener(this);
mBtnDelWifi = (Button) findViewById(R.id.btnDelWifi) ;
mBtnDelWifi.setOnClickListener(this);
mBtnConnect = (Button) findViewById(R.id.btnConnect);
mBtnConnect.setOnClickListener(this);
mBtnDisConnect = (Button) findViewById(R.id.btnDisConnect);
mBtnDisConnect.setOnClickListener(this);
mTextViewShowResult = (TextView) findViewById(R.id.textViewShowResult);
} @Override
public void onClick(View view) {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
mTextViewShowResult.setText("");
// "TP-LINK_ACA6"
switch (view.getId()) {
case R.id.btnOpenWifi:
if (openWifi()) {
mTextViewShowResult.setText("正在打开 Wifi,请稍等");
} else {
mTextViewShowResult.setText("打开 Wifi 失败,Wifi 已经开启?");
}
break;
case R.id.btnCloseWifi:
if (closeWifi()) {
mTextViewShowResult.setText("正在关闭 Wifi,请稍等");
} else {
mTextViewShowResult.setText("关闭 Wifi 失败,Wifi 已经关闭?");
}
break;
case R.id.btnAddWifi:
int networkId = addWifiItem(WIFI_SSID);
mTextViewShowResult.setText("得到的 Wifi 的 ID 是:" + networkId);
break;
case R.id.btnDelWifi:
forgetConfiguration(this,createWifiConfiguration(WIFI_SSID));
break;
case R.id.btnConnect:
connectToSpecSsid(addWifiItem(WIFI_SSID));
break;
case R.id.btnDisConnect:
disableSpecSsid(addWifiItem(WIFI_SSID));
break;
}
} public static WifiConfiguration createWifiConfiguration(String SSID) {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.allowedKeyManagement.clear();
wifiConfiguration.allowedAuthAlgorithms.clear();
wifiConfiguration.hiddenSSID = true; // 无密码
wifiConfiguration.SSID = "\"" + SSID + "\"";
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); return wifiConfiguration;
} private boolean openWifi() {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
boolean result = false;
switch (wifiManager.getWifiState()) {
case WifiManager.WIFI_STATE_DISABLED:
case WifiManager.WIFI_STATE_DISABLING:
wifiManager.setWifiEnabled(true);
result = true;
break;
case WifiManager.WIFI_STATE_ENABLED:
case WifiManager.WIFI_STATE_ENABLING:
result = false;
break;
}
return result;
} private boolean closeWifi() {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
boolean result = false;
switch (wifiManager.getWifiState()) {
case WifiManager.WIFI_STATE_ENABLED:
case WifiManager.WIFI_STATE_ENABLING:
wifiManager.setWifiEnabled(false);
result = true;
break;
case WifiManager.WIFI_STATE_DISABLED:
case WifiManager.WIFI_STATE_DISABLING:
result = false;
break;
}
return result;
} private int addWifiItem (String ssid) {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();
int networkId = -10;
if (null != wifiConfigurations) {
for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
if (wifiConfiguration.SSID.equals("\"" + ssid + "\"")) {
networkId = wifiConfiguration.networkId;
break;
}
}
} if (networkId == -10) {
networkId = wifiManager.addNetwork(createWifiConfiguration(ssid));
} return networkId;
} private boolean delWifiItem (String ssid) {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();
boolean result = false;
int networkId = -10;
if (null != wifiConfigurations) {
for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
if (wifiConfiguration.SSID.equals("\"" + ssid + "\"")) {
networkId = wifiConfiguration.networkId;
Log.i(TAG, "delWifiItem: 找到对应的 ssid,编号为:" + networkId);
break;
}
}
} if (networkId != -10) {
Log.i(TAG, "delWifiItem: 执行删除指定网络的过程");
wifiManager.removeNetwork(networkId);
result = true;
} wifiConfigurations = wifiManager.getConfiguredNetworks();
for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
if (wifiConfiguration.SSID.equals("\"" + ssid + "\"")) {
Log.i(TAG, "delWifiItem: 又找到对应的 ssid,编号为:" + networkId);
result = false;
break;
}
} return result;
} private boolean connectToSpecSsid(int netId) {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
return wifiManager.enableNetwork(netId,true);
} private boolean disableSpecSsid(int netId) {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
return wifiManager.disableNetwork(netId);
} public static void forgetConfiguration(Context context, WifiConfiguration config) {
if (config == null) {
return;
} WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configuredNetworks = wifiMan.getConfiguredNetworks();
if (configuredNetworks == null) {
Log.e(TAG, "failed to get configured networks");
return;
} for (WifiConfiguration wc : configuredNetworks) {
if (wc != null && wc.SSID != null && TextUtils.equals(wc.SSID, config.SSID)) {
wifiMan.forget(wc.networkId, null);
Log.d(TAG, "forgot network config: " + wc.toString());
break;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xxxxxx.wifitest7.MainActivity"> <Button
android:id="@+id/btnOpenWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:text="@string/open_wifi"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/> <Button
android:id="@+id/btnCloseWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:layout_marginTop="32dp"
android:text="@string/close_wifi"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/> <TextView
android:id="@+id/textViewShowResult"
android:layout_width="321dp"
android:layout_height="220dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
app:layout_constraintLeft_toLeftOf="@+id/btnOpenWifi"
app:layout_constraintRight_toRightOf="@+id/btnCloseWifi"
app:layout_constraintTop_toBottomOf="@+id/btnConnect"
app:layout_constraintHorizontal_bias="0.484"/> <Button
android:id="@+id/btnConnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="8dp"
android:text="@string/connect"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnAddWifi"/> <Button
android:id="@+id/btnDisConnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
android:text="@string/disconnect"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnDelWifi"/> <Button
android:id="@+id/btnAddWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/addwifi"
app:layout_constraintTop_toBottomOf="@+id/btnOpenWifi"
android:layout_marginStart="32dp"
app:layout_constraintLeft_toLeftOf="parent"/> <Button
android:id="@+id/btnDelWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/delwifi"
app:layout_constraintTop_toBottomOf="@+id/btnCloseWifi"
android:layout_marginEnd="32dp"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

Android 7.1.1 又出幺蛾子了 —— 再谈 Android 上的 Wifi 连接的更多相关文章

  1. 再谈Android应用瘦身

    Android应用apk安装包的大小,虽然对于现在WiFi普及情况而言消耗流量已经微乎其微,但是,对于一款好的应用,对于一款负责任的应用,当然是越小越好了. 引言: .应用越小,下载越快,也就意味着新 ...

  2. 再谈Android AsyncTask的优缺点

    导语:之前做习惯了Framework层的开发,今天在武汉斗鱼公司面试APP客户端的开发,其中一道题是讲述Asynctask的优缺点,我靠,我只是知道有这么一个东西,会用而已,看来之前的生活太过于安逸, ...

  3. Android配置----小米手机通过wifi连接ADB调试Android应用

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  4. android中常用的弹出提示框

    转自:http://blog.csdn.net/centralperk/article/details/7493731 我们在平时做开发的时候,免不了会用到各种各样的对话框,相信有过其他平台开发经验的 ...

  5. 【Android】创建Popwindow弹出菜单的两种方式

    方法一的Activity package com.app.test02; import android.app.Activity; import android.os.Bundle; import a ...

  6. Android 如何解决dialog弹出时无法捕捉Activity的back事件

    Android 如何解决dialog弹出时无法捕捉Activity的back事件 在一些情况下,我们需要捕捉back键事件,然后在捕捉到的事件里写入我们需要进行的处理,通常可以采用下面三种办法捕捉到b ...

  7. Python_内置函数之round的幺蛾子

    pycharm运行结果 1 ret = round(0.5) print(ret) >>> 0 ret1 = round(1.5) print(ret1) >>> ...

  8. xamarin.android 实现 Activity 底部弹出对话框菜单

    Resources/drawable 下新增如下文件: push_bottom_in.xml <?xml version="1.0" encoding="utf-8 ...

  9. Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?

    原文:http://www.xuebuyuan.com/1608083.html 最近在研究Activity的启动流程,老罗的blog在看,也找了其它资料学习,也跟过Android4.3的源码, 在跟 ...

随机推荐

  1. LL(1)文法--递归下降程序

    递归下降程序 递归下降程序一般是针对某一个文法的.而递归下降的预测分析是为每一个非终结符号写一个分析过程,由于文法本身是递归的,所以这些过程也是递归的. 以上是前提. Sample 假如给的是正规式子 ...

  2. es6 入坑笔记(五)

    Symbol 主要用做key或私有变量,Symbol是唯一的不可重复的,也是一个单独的数据类型 定义形式: let demo=Symbol("aaaa"); 1.Symbol不能使 ...

  3. angular1.x todolist 实现

    将要计划完成事的列表存在localStroage ,实现本地同步删除,同步增加. <!DOCTYPE html> <html lang="zh" ng-app=& ...

  4. 基于 HTML5 Canvas 的 Web SCADA 组态电机控制面板

    前言 HT For Web 提供完整的基于 HTML5 图形界面组件库.您可以轻松构建现代化的,跨桌面和移动终端的企业应用,无需担忧跨平台兼容性,及触屏手势交互等棘手问题.也可用于快速创建和部署,高度 ...

  5. MySQL - CentOS 下 MySQL 5.6 安装

    1. 概述 最近没啥东西可写, 随便写点 mysql 5.6 的安装 去年写的 装上去过 三次以上 2. 准备 系统 CentOS 7.4 3. 安装 1. 直接安装 # mysql服务端: mysq ...

  6. STM32串口一直进中断

    调试过程中遇到了使用串口什么都没接却一直进中断,接串口线到电脑上测试又正常的问题. 网上有人说需要将USART的RX模式从输入浮空改成输入上拉,改后测试正常,问题解决. 分析可能是什么都不接时浮空模式 ...

  7. 20155315 2016-2017-2 《Java程序设计》第二周学习总结

    教材学习内容总结 在教材中,有一句话叫做 伪代码是最好的注释. 一开始我不理解什么是伪代码,但在参考了百度和C语言的学习过程后,我发现伪代码的作用就相当于是解决问题前期的流程图设计,伪代码设计好了之后 ...

  8. 20155317 2016-2017-2 《Java程序设计》第十学习总结

    20155317 2016-2017-2 <Java程序设计>第十学习总结 教材学习内容总结 1.网络编程的概念: 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作 ...

  9. ruby学习笔记(1)-puts,p,print的区别

    ruby学习笔记-puts,p,print的区别 共同点:都是用来屏幕输出的. 不同点:puts 输出内容后,会自动换行(如果内容参数为空,则仅输出一个换行符号):另外如果内容参数中有转义符,输出时将 ...

  10. [2016北京集训测试赛7]isn-[树状数组+dp+容斥]

    Description Solution 定义dp[i][j]为在1到i个数中选了j个数,并且保证选了i的选法总数. dp[i][j]为所有满足A[k]>A[i]的k(k<i)的dp[k] ...