android开发步步为营之48:通过WifiManager自动连上某个wifi热点

最近参加了个某个创业公司的面试,他们做了个应用,就是用户打开他们的应用就可以提供免费上网的功能,然后面试的过程中,那哥们说,你对wifi这些协议你懂吗?需要用到比较底层的东西哦,我勒个去,就这么一个上网功能就需要很底层吗?搞得很高深的样子,真是底层是涉及到修改android的框架了,修改手机ROM了,你们做到这一步了吗?没有吧,只是在android框架提供api基础上实现的,为此,我今天特意实验了一把。也就10几分钟就搞定的事情,我被你们懵到了,额。。。

开发过程中主要用到WifiManager这个系统自带的服务,它有如下几个状态

WifiManager.WIFI_STATE_DISABLED: //wifi不可用

WifiManager.WIFI_STATE_DISABLING://wifi 正在关闭或者断开

WifiManager.WIFI_STATE_ENABLED://wifi已经打开可用

WifiManager.WIFI_STATE_ENABLING://wifi正在打开或者连接

WifiManager.WIFI_STATE_UNKNOWN://未知消息

好,开始我们的实验:

     第一步:AndroidManifest.xml添加相关权限

<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.INTERNET" />

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

     第二步:新建测试页面/study/res/layout/activity_wifi.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity" >

<Button

android:id="@+id/btnWifi"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="47dp"

android:text="自动连上wifi" />

</RelativeLayout>

       第三步:实现Activity,WifiManagerTestActivity.java

/**

* 自动选择连上某个wifi信号

*/

package com.figo.study;

import java.util.List;

import android.app.Activity;

import android.content.Context;

import android.net.wifi.WifiConfiguration;

import android.net.wifi.WifiConfiguration.AuthAlgorithm;

import android.net.wifi.WifiConfiguration.KeyMgmt;

import android.net.wifi.WifiManager;

import android.os.Bundle;

import android.text.TextUtils;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

/**

* @author zhuzhifei

*/

public class WifiManagerTestActivity extends Activity {

private Button btnWifi;

WifiManager wifiManager;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_wifi);

//获取wifi管理服务

wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

btnWifi = (Button) findViewById(R.id.btnWifi);

btnWifi.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

//    connect("newhome","newhome123",WifiCipherType.WIFICIPHER_WEP);

//启动wifi

connect("newhome","newhome123",WifiCipherType.WIFICIPHER_WPA);

}

});

}

private static final String TAG = WifiManagerTestActivity.class

.getSimpleName();

// 定义几种加密方式,一种是WEP,一种是WPA,还有没有密码的情况

public enum WifiCipherType {

WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID

}

// 提供一个外部接口,传入要连接的无线网ssid,password,

public void connect(String ssid, String password, WifiCipherType type) {

Thread thread = new Thread(new ConnectRunnable(ssid, password, type));

thread.start();

}

// 查看以前是否也配置过这个网络

private WifiConfiguration isExsits(String SSID) {

List<WifiConfiguration> existingConfigs = wifiManager

.getConfiguredNetworks();

for (WifiConfiguration existingConfig : existingConfigs) {

if (existingConfig.SSID.equals("\"" + SSID + "\"")) {

return existingConfig;

}

}

return null;

}

private WifiConfiguration createWifiInfo(String SSID, String Password,

WifiCipherType Type) {

WifiConfiguration config = new WifiConfiguration();

config.allowedAuthAlgorithms.clear();

config.allowedGroupCiphers.clear();

config.allowedKeyManagement.clear();

config.allowedPairwiseCiphers.clear();

config.allowedProtocols.clear();

config.SSID = "\"" + SSID + "\"";

// nopass

if (Type == WifiCipherType.WIFICIPHER_NOPASS) {

config.wepKeys[0] = "";

config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

config.wepTxKeyIndex = 0;

}

// wep

if (Type == WifiCipherType.WIFICIPHER_WEP) {

if (!TextUtils.isEmpty(Password)) {

if (isHexWepKey(Password)) {

config.wepKeys[0] = Password;

} else {

config.wepKeys[0] = "\"" + Password + "\"";

}

}

config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);

config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);

config.allowedKeyManagement.set(KeyMgmt.NONE);

config.wepTxKeyIndex = 0;

}

// wpa

if (Type == WifiCipherType.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.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

config.allowedPairwiseCiphers

.set(WifiConfiguration.PairwiseCipher.CCMP);

config.status = WifiConfiguration.Status.ENABLED;

}

return config;

}

// 打开wifi功能

private boolean openWifi() {

boolean bRet = true;

if (!wifiManager.isWifiEnabled()) {

bRet = wifiManager.setWifiEnabled(true);

}

return bRet;

}

//启动一个新线程打开wifi

class ConnectRunnable implements Runnable {

private String ssid;

private String password;

private WifiCipherType type;

public ConnectRunnable(String ssid, String password, WifiCipherType type) {

this.ssid = ssid;

this.password = password;

this.type = type;

}

@Override

public void run() {

// 打开wifi

openWifi();

// 开启wifi功能需要一段时间(我在手机上测试一般需要1-3秒左右),所以要等到wifi

// 状态变成WIFI_STATE_ENABLED的时候才能执行下面的语句

while (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {

try {

// 为了避免程序一直while循环,让它睡个100毫秒检测……

Thread.sleep(100);

} catch (InterruptedException ie) {

}

}

WifiConfiguration wifiConfig = createWifiInfo(ssid, password, type);

//

if (wifiConfig == null) {

Log.d(TAG, "wifiConfig is null!");

return;

}

WifiConfiguration tempConfig = isExsits(ssid);

if (tempConfig != null) {

wifiManager.removeNetwork(tempConfig.networkId);

}

int netID = wifiManager.addNetwork(wifiConfig);

boolean enabled = wifiManager.enableNetwork(netID, true);

Log.d(TAG, "enableNetwork status enable=" + enabled);

boolean connected = wifiManager.reconnect();

Log.d(TAG, "enableNetwork connected=" + connected);

}

}

private static boolean isHexWepKey(String wepKey) {

final int len = wepKey.length();

// WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)

if (len != 10 && len != 26 && len != 58) {

return false;

}

return isHex(wepKey);

}

private static boolean isHex(String key) {

for (int i = key.length() - 1; i >= 0; i--) {

final char c = key.charAt(i);

if (!(c >= ‘0‘ && c <= ‘9‘ || c >= ‘A‘ && c <= ‘F‘ || c >= ‘a‘

&& c <= ‘f‘)) {

return false;

}

}

return true;

}

}

时间: 2024-10-11 17:57:59

android开发步步为营之48:通过WifiManager自动连上某个wifi热点的相关文章

android开发 更新升级安装到一半自动闪退

如题:android开发 更新升级安装到一半自动闪退,,,解决办法,如下(红色为我新增的代码) /**     * 安装APK文件     */    private void installApk()    {        File apkfile = new File(mSavePath, mHashMap.get("name")); //apkfile  获取已经下载好的待安装apk文件        if (!apkfile.exists())        {       

Android开发中使用七牛云存储进行图片上传下载

Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储原理,上面这幅图片是官方给出的原理图,表述当然比较清晰了.可以看出,要进行图片上传的话可以分为五大步: 1. 客户端用户登录到APP的账号系统里面: 2. 客户端上传文件之前,需要向业务服务器申请七牛的上传凭证,这个凭证由业务服务器使用七牛提供的服务端SDK生成: 3. 客户端使用七牛提供的客户端S

黑客有办法让你的iPhone自动连上钓鱼wifi

近年来,越来越多因为蹭免费网络而泄露银行账户密码或者支付宝密码的案件发生,警察蜀黍提醒广大市民注意三点:1.谨慎连接公共WiFi:在机场.星巴克.麦当劳和星级酒店等有免费WiFi的公共场合,不法分子会伪造免费wifi,进行钓鱼犯罪,对此,市民要明察秋毫,问清楚工作人员哪个才是官方wifi才进行连接. 2.不要使用手机浏览器登陆手机银行和支付宝:黑客则会引导用户至山寨钓鱼网站,或者设置钓鱼网站,从而获取账号及密码.因此,市民最好通过银行官网网页,或者手机银行客户端登录,这两种渠道均经过了层层加密,

android开发步步为营之70:android接入Google Analytics总结

求人不如求己,今天项目里要接入Google Analytics,这个是做应用统计分析用的,可以查看当前手机活跃用户,事件点击等等数据,先看看效果: 之前eclipse里面接入已经成功,昨天项目组决定项目转成使用android studio来开发,看google官方文档,官方文档https://developers.google.com/analytics/devguides/collection/android/v4/,然后官方文档里面的配置文件是用google-services.json的,这

android开发步步为营之20:网络设置

网络设置这块在手机应用里面是非常重要的一块,因为一般应用都需要和外部网络做交互的.本篇文章就展示了一个比较经典应用场景.比如我最近在开发的转账应用.这个是需要和网络交互的.当用户打开应用之后,应用首先会判断用户是否已经打开wifi或者gprs网络.没有则跳转到系统的无线和网络设置界面,当用户设置好了之后,我这里做了一个更人性化的处理,创建了一个广播接收器,因为我们知道,手机在打开网络或者收到短信的时候,都会对外发布一条广播.一旦网络连接上了之后,我的这个广播接收器,就会收到信息,然后判断当前的转

android开发步步为营之56:Android开发技术点总结(持续更新)

1.eclipse svn插件下载 http://subclipse.tigris.org/update_1.6.x http://subclipse.tigris.org/update_1.8.x 64位机器 http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 2.eclipse常用插件下载 http://blog.csdn.net/jackiehff/article/details/8181945 3.unico

android开发步步为营之58:给图片绘制圆形气泡背景效果

最近在开发项目的时候,有一个需求,需要给应用图标绘制圆形气泡背景,有了彩色气泡这样显得漂亮一点,气泡的颜色是应用图标的颜色均值,先看看效果,然后,我再给出demo. demo应用图标是这样的: 添加气泡背景后是这样的: 仔细看圆形背景颜色是图标颜色的均值. 好的,下面我们来完成这个demo. 第一步.编写页面activity_drawcycle.xml <?xml version="1.0" encoding="utf-8"?> <LinearLa

android开发步步为营之68:Facebook原生广告接入总结

开发应用的目的是干嘛?一方面当然是提供优质服务给用户,还有一方面最重要的还是须要有盈利.不然谁还有动力花钱花时间去开发app? 我们的应用主攻海外市场,所以主要还是接入国外的广告提供商.本文就今天刚完毕接入facebook原生广告功能,介绍一下怎样接入fb的原生广告.供大家參考.         第一步:申请接入账号(须要FQ) https://developers.facebook.com/docs/audience-network/getting-started#company_info h

android开发步步为营之62:进程间通信之Aidl

android进程之间通信,比如一个app和另外一个app交互,有哪几种方式,主要有1.activity的跳转  2.contentprovider  3.broadcast  4.aidl,个人认为前面3种相对简单,应用场景也不一样.本文研究一下使用aidl进行进程之间的通信. aidl全称是Android Interface Definition Language,即接口定义语言,依我理解,这个其实和.net,java里面的webservice相似的,webservice也有个wsdl We