Android自动连接指定的wifi,免密码或指定密码

原文:Android自动连接指定的wifi,免密码或指定密码

一、运行时的状态

遇到一个这样的要求:“不进行扫描操作,怎么对指定的免密码WIFI进行连接(之前没有连接过)”,于是动手写了一个Demo,如图所示未连接成功时的状态,第一个编辑框让用户输入SSID,第二个编辑框输入密码,密码可以根据实例情况输入,也可以不输入密码,因为有些Wifi免密码。这里的免密码不是指可以破解wifi密码。注意图片中手机顶部的wifi图标,是没有的,说明此时并没有打开手机的wifi。在手机上运行状态如下所示:

输入SSID,点击连接后的状态,当手机的wifi没有打开时,程序将自动打开wifi,打开后再连接指定的wifi。

测试的手机信息如下:

二、功能实现

2.1、项目结构如下所示:

2.2、页面布局activity_main.xml文件如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/txtSSID"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SSID:"
        android:textSize="@dimen/activity_horizontal_margin" />

    <EditText
        android:id="@+id/editSSID"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="FBI" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Password:"
        android:textSize="@dimen/activity_horizontal_margin" />

    <EditText
        android:id="@+id/editPwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="" />

    <Button
        android:id="@+id/btnConnect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Connect" />

    <TextView
        android:id="@+id/txtMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" />

</LinearLayout>

 

2.3、清单文件AndroidManifest.xml内容如下,中间添加了对wifi访问的用户权限部分非常重要

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.wifigo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 2.4、Wifi连接管理类WifiConnector.java,有不少是参考热心网友的博客,谢谢了!

package com.example.wifigo;

import java.util.List;

import android.net.wifi.*;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

public class WifiConnector {
    Handler mHandler;
    WifiManager wifiManager;

    /**
     * 向UI发送消息
     * @param info 消息
     */
    public void sendMsg(String info) {
        if (mHandler != null) {
            Message msg = new Message();
            msg.obj = info;
            mHandler.sendMessage(msg);// 向Handler发送消息
        } else {
            Log.e("wifi", info);
        }
    }

    //WIFICIPHER_WEP是WEP ,WIFICIPHER_WPA是WPA,WIFICIPHER_NOPASS没有密码
    public enum WifiCipherType {
        WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
    }

    // 构造函数
    public WifiConnector(WifiManager wifiManager) {
        this.wifiManager = wifiManager;
    }

    // 提供一个外部接口,传入要连接的无线网
    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.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        }
        // 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;
    }

    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() {
            try {
                // 打开wifi
                openWifi();
                sendMsg("opened");
                Thread.sleep(200);
                // 开启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) {
                    sendMsg("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);
                sendMsg("enableNetwork status enable=" + enabled);
                boolean connected = wifiManager.reconnect();
                sendMsg("enableNetwork connected=" + connected);
                sendMsg("连接成功!");
            } catch (Exception e) {
                // TODO: handle exception
                sendMsg(e.getMessage());
                e.printStackTrace();
            }
        }
    }

    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;
    }
}

2.5、MainActivity.java代码,完成接收用户的输入与调用wifi连接功能,如下所示:

package com.example.wifigo;

import com.example.wifigo.WifiConnector.WifiCipherType;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    Button btnConnect;
    WifiManager wifiManager;
    WifiConnector wac;
    TextView textView1;
    EditText editPwd;
    EditText editSSID;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnConnect = (Button) findViewById(R.id.btnConnect);
        textView1 = (TextView) findViewById(R.id.txtMessage);
        wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        wac = new WifiConnector(wifiManager);

         editPwd=(EditText) findViewById(R.id.editPwd);
         editSSID=(EditText) findViewById(R.id.editSSID);

        wac.mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // 操作界面
                textView1.setText(textView1.getText()+"\n"+msg.obj+"");
                super.handleMessage(msg);
            }
        };
        btnConnect.setOnClickListener(new Button.OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    wac.connect(editSSID.getText().toString(), editPwd.getText().toString(),
                            editPwd.getText().toString().equals("")?WifiCipherType.WIFICIPHER_NOPASS:WifiCipherType.WIFICIPHER_WPA);
                } catch (Exception e) {
                    textView1.setText(e.getMessage());
                }

            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

2.6、小结

时间比较紧,代码比较粗糙,这毕竟只是一个demo,如果您需要使用在商业项目中这可能只具有抛砖引玉的作用了;另外测试时发现如果手机的wifi没有打开,依靠程序打开时程序会崩溃,后面发现有可能是打开wifi时需要一段时间,所以代码中增加了一些人为的延时操作,尽量用更加优雅的办法替代;我使用一台Android 4.x.x的meizu note 1手机和一个DLink DIR-600N的老路由器测试没有问题,使用自己的笔记本电脑作热点,带密码连接没有问题,这不代表在其它环境下就正常了。 

 2.7、参考示例:

下载示例源码

 

时间: 2024-08-03 09:48:06

Android自动连接指定的wifi,免密码或指定密码的相关文章

wifi热点创建和自动连接

1.wifi热点的创建 /** * 创建wifi热点 * @param ssid 热点信息 * @param passwd 密码 * @author wanghongbin */ public void startWifiAp(Context context, String ssid, String passwd) { //关闭wifi closeWifi(); //关闭热点 closeWifiAp(); //激活热点 invokeWifiAp(ssid, passwd); } /** * 激活

WIFI中CMCC自动连接如何禁止

  首先,你的手机要进行root.教程和工具论坛里一找一大把,就不再多说了.root以后,要用到一个工具:RE管理器.安卓市场或是Google市场都可以下载得到. 打 开RE管理器,进入路径:/etc/wifi/default_ap.conf,打开你会发现里面默认设置CMCC为WLAN接入点的文本信息.轻按RE 管理器右上方的Mount R/W(读写)改为Mount R/O(只读),点击下方工具栏中的删除按钮,把该文件删除.(有些版本可能要长按该文件并在弹出菜单中选择删除) 回到RE管理器根目录

wifi万能钥匙怎么查看密码

  wifi万能钥匙查看密码手机篇: 首先我们要有2个软件 1.wifi万能钥匙: 2.RE管理器: 步骤一:打开你的wifi万能钥匙的应用,点击一键查询万能钥匙, 步骤二:我们发现有两个,后面带两个蓝色钥匙的标志,就是可以连接的 步骤三:我们随便点一个连接,它会提示正在连接,现在已经是连接上了,连接名字是CCCCCCCCCC这个连接 步骤四:打开你的额RE管理器,(前提是你的手机一定要ROOT)找到data--misc--wifi(你的手机要是没有ROOT是打不开的) 步骤五:打开wpa_su

Android开发——自动连接指定SSID的wifi热点(不加密/加密)

最近在做一个项目,其中涉及到一块"自动连接已存在的wifi热点"的功能,在网上查阅了大量资料,五花八门,但其中一些说的很简单,即不能实现傻瓜式的拿来就用,有些说的很详细,但其中不乏些许错误造成功能无法实现,经过浣熊多方努力,终于成功将功能实现,遂将一点点小成就拿出来与大家分享. 首先需要感谢这篇文章的作者:http://blog.chinaunix.net/uid-22342564-id-3228565.html 在这篇文章中,作者定义了一个wifi工具类,其中存在着操作wifi的各种

Android系统控制连接usb外部存储设备的代码在哪里能找到,我想在其中增加一个选择指定设备的功能

问题描述 Android系统控制连接usb外部存储设备的代码在哪里能找到,我想在其中增加一个选择指定设备的功能 代码指的是系统代码,Android系统支持USBhost功能.当u盘插在手机上时,系统自动甄别其是否为指定外设,如果是,没有额外动作,一切如常:如果不是,系统自动移除外设:楼主是Android新手,希望大家给予些帮助或思路

wifi热点-Android 如何获取所有的wifi连接历史记录?

问题描述 Android 如何获取所有的wifi连接历史记录? 不是附近的wifi热点,而是本机所有连接过的wifi热点名称.也就是保存过的wifi热点信息. 解决方案 1.首先安卓系统必须root才可以获取这样的文件信息. 2.root之后使用Re管理器这样的软件. 3.路径:?/data/misc/wifi 4.文件名称:wpa_supplicant.conf 用文本模式查看 在这里就有你要查看的连接WiFi密码名称

wi-fi- android 如何判断已连接上指定的wifi网络?注意是验证!!!

问题描述 android 如何判断已连接上指定的wifi网络?注意是验证!!! mWifiAdmin.addNetWork(mWifiAdmin.CreateWifiInfo(getSSID, "", 1)使用这个方法去连接wifi返回true后表示wifi连接成功,但是还需要好像wifi连接真正稳定下来还需要一段时间,这个时候我用当前当前手机的网络状态是否为wifi和当前手机连接wifi的ssid和指定要连接wifi的ssid去比较是否连接成功,但是都判断成功后有网络请求有时候还是失

谷歌推WiFi应用 可自动连接谷歌的免费热点

硅谷网讯 据国外http://www.aliyun.com/zixun/aggregation/31646.html">媒体报道,谷歌正在开发一种新的WiFi应用程序,可以帮助用户省去手动无线接入热点的麻烦.据了解,这家搜索巨头已经开发了Android和iOS版本的自动验证程序,可自动连接到星巴克门店内或其它免费的谷歌热点. 不过现在看起来,这一应用类类似一个非常有限的测试.而且谷歌也没有明确保证会正式发布它.但有消息称,谷歌已经在内部讨论将自己更快的WiFi连接部署到美国所有7千家星巴克

谷歌推WiFi应用 可自动连接谷歌热点

2月21日消息,据国外http://www.aliyun.com/zixun/aggregation/31646.html">媒体报道,谷歌正在开发一种新的WiFi应用程序,可以帮助用户省去手动无线接入热点的麻烦.据了解,这家搜索巨头已经开发了Android和iOS版本的自动验证程序,可自动连接到星巴克门店内或其它免费的谷歌热点. 不过现在看起来,这一应用类类似一个非常有限的测试.而且谷歌也没有明确保证会正式发布它.但有消息称,谷歌已经在内部讨论将自己更快的WiFi连接部署到美国所有7千家