Android WiFi开发 Wifi热点
Posted VNanyesheshou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android WiFi开发 Wifi热点相关的知识,希望对你有一定的参考价值。
接着上一篇wifi的扫描连接等,这一篇主要说一下手机开启Wifi热点。
demo的下载地址会在最下面贴出来。
图片:
1 创建WIFI热点
经测试开启wifi热点(无秘密,wpa安全类型,wpa2安全类型)都可以正常开启并使用。
需要注意的是wifi和wifi热点不能同时打开,也就是连接wifi的时候,开启热点需要先将wifi关闭才可以。
用到的主要代码:
package com.vn.wifitest.utils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.util.Log;
public class WifiAPUtil
private static final String TAG = "WifiAPUtil";
public final static boolean DEBUG = true;
public static final int MESSAGE_AP_STATE_ENABLED = 1;
public static final int MESSAGE_AP_STATE_FAILED = 2;
//默认wifi秘密
private static final String DEFAULT_AP_PASSWORD = "12345678";
private static WifiAPUtil sInstance;
private static Handler mHandler;
private static Context mContext;
private WifiManager mWifiManager;
//监听wifi热点的状态变化
public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
public static int WIFI_AP_STATE_DISABLING = 10;
public static int WIFI_AP_STATE_DISABLED = 11;
public static int WIFI_AP_STATE_ENABLING = 12;
public static int WIFI_AP_STATE_ENABLED = 13;
public static int WIFI_AP_STATE_FAILED = 14;
public enum WifiSecurityType
WIFICIPHER_NOPASS, WIFICIPHER_WPA, WIFICIPHER_WEP, WIFICIPHER_INVALID, WIFICIPHER_WPA2
private WifiAPUtil(Context context)
if(DEBUG) Log.d(TAG,"WifiAPUtils construct");
mContext = context;
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
IntentFilter filter = new IntentFilter();
filter.addAction(WIFI_AP_STATE_CHANGED_ACTION);
context.registerReceiver(mWifiStateBroadcastReceiver, filter);
protected void finalize()
if(DEBUG) Log.d(TAG,"finalize");
mContext.unregisterReceiver(mWifiStateBroadcastReceiver);
public static WifiAPUtil getInstance(Context c)
if (null == sInstance)
sInstance = new WifiAPUtil(c);
return sInstance;
public boolean turnOnWifiAp(String str, String password,WifiSecurityType Type)
String ssid = str;
//配置热点信息。
WifiConfiguration wcfg = new WifiConfiguration();
wcfg.SSID = new String(ssid);
wcfg.networkId = 1;
wcfg.allowedAuthAlgorithms.clear();
wcfg.allowedGroupCiphers.clear();
wcfg.allowedKeyManagement.clear();
wcfg.allowedPairwiseCiphers.clear();
wcfg.allowedProtocols.clear();
if(Type == WifiSecurityType.WIFICIPHER_NOPASS)
if(DEBUG)Log.d(TAG, "wifi ap----no password");
wcfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN, true);
wcfg.wepKeys[0] = "";
wcfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wcfg.wepTxKeyIndex = 0;
else if(Type == WifiSecurityType.WIFICIPHER_WPA)
if(DEBUG)Log.d(TAG, "wifi ap----wpa");
//密码至少8位,否则使用默认密码
if(null != password && password.length() >= 8)
wcfg.preSharedKey = password;
else
wcfg.preSharedKey = DEFAULT_AP_PASSWORD;
wcfg.hiddenSSID = false;
wcfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wcfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
//wcfg.allowedKeyManagement.set(4);
wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wcfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
else if(Type == WifiSecurityType.WIFICIPHER_WPA2)
if(DEBUG)Log.d(TAG, "wifi ap---- wpa2");
//密码至少8位,否则使用默认密码
if(null != password && password.length() >= 8)
wcfg.preSharedKey = password;
else
wcfg.preSharedKey = DEFAULT_AP_PASSWORD;
wcfg.hiddenSSID = true;
wcfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wcfg.allowedKeyManagement.set(4);
//wcfg.allowedKeyManagement.set(4);
wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wcfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
try
Method method = mWifiManager.getClass().getMethod("setWifiApConfiguration",
wcfg.getClass());
Boolean rt = (Boolean)method.invoke(mWifiManager, wcfg);
if(DEBUG) Log.d(TAG, " rt = " + rt);
catch (NoSuchMethodException e)
Log.e(TAG, e.getMessage());
catch (IllegalArgumentException e)
Log.e(TAG, e.getMessage());
catch (IllegalAccessException e)
Log.e(TAG, e.getMessage());
catch (InvocationTargetException e)
Log.e(TAG, e.getMessage());
return setWifiApEnabled();
//获取热点状态
public int getWifiAPState()
int state = -1;
try
Method method2 = mWifiManager.getClass().getMethod("getWifiApState");
state = (Integer) method2.invoke(mWifiManager);
catch (Exception e)
Log.e(TAG, e.getMessage());
if(DEBUG)Log.i("WifiAP", "getWifiAPState.state " + state);
return state;
private boolean setWifiApEnabled()
//开启wifi热点需要关闭wifi
while(mWifiManager.getWifiState() != WifiManager.WIFI_STATE_DISABLED)
mWifiManager.setWifiEnabled(false);
try
Thread.sleep(200);
catch (Exception e)
Log.e(TAG, e.getMessage());
return false;
// 确保wifi 热点关闭。
while(getWifiAPState() != WIFI_AP_STATE_DISABLED)
try
Method method1 = mWifiManager.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, boolean.class);
method1.invoke(mWifiManager, null, false);
Thread.sleep(200);
catch (Exception e)
Log.e(TAG, e.getMessage());
return false;
//开启wifi热点
try
Method method1 = mWifiManager.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, boolean.class);
method1.invoke(mWifiManager, null, true);
Thread.sleep(200);
catch (Exception e)
Log.e(TAG, e.getMessage());
return false;
return true;
//关闭WiFi热点
public void closeWifiAp()
if (getWifiAPState() != WIFI_AP_STATE_DISABLED)
try
Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
method.setAccessible(true);
WifiConfiguration config = (WifiConfiguration) method.invoke(mWifiManager);
Method method2 = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method2.invoke(mWifiManager, config, false);
catch (NoSuchMethodException e)
e.printStackTrace();
catch (IllegalArgumentException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
catch (InvocationTargetException e)
e.printStackTrace();
public void regitsterHandler(Handler handler)
mHandler = handler;
public void unregitsterHandler()
mHandler = null;
//监听wifi热点状态变化
private BroadcastReceiver mWifiStateBroadcastReceiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
if(DEBUG)Log.i(TAG,"WifiAPUtils onReceive: "+intent.getAction());
if(WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction()))
int cstate = intent.getIntExtra(EXTRA_WIFI_AP_STATE, -1);
if(cstate == WIFI_AP_STATE_ENABLED)
if(mHandler != null)
mHandler.sendEmptyMessage(MESSAGE_AP_STATE_ENABLED);
if(cstate == WIFI_AP_STATE_DISABLED || cstate == WIFI_AP_STATE_FAILED)
if(mHandler != null)
mHandler.sendEmptyMessage(MESSAGE_AP_STATE_FAILED);
;
//获取热点ssid
public String getValidApSsid()
try
Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration configuration = (WifiConfiguration)method.invoke(mWifiManager);
return configuration.SSID;
catch (Exception e)
Log.e(TAG, e.getMessage());
return null;
//获取热点密码
public String getValidPassword()
try
Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration configuration = (WifiConfiguration)method.invoke(mWifiManager);
return configuration.preSharedKey;
catch (Exception e)
Log.e(TAG, e.getMessage());
return null;
//获取热点安全类型
public int getValidSecurity()
WifiConfiguration configuration;
try
Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
configuration = (WifiConfiguration)method.invoke(mWifiManager);
catch (Exception e)
Log.e(TAG, e.getMessage());
return WifiSecurityType.WIFICIPHER_INVALID.ordinal();
if(DEBUG)Log.i(TAG,"getSecurity security="+configuration.allowedKeyManagement);
if(configuration.allowedKeyManagement.get(KeyMgmt.NONE))
return WifiSecurityType.WIFICIPHER_NOPASS.ordinal();
else if(configuration.allowedKeyManagement.get(KeyMgmt.WPA_PSK))
return WifiSecurityType.WIFICIPHER_WPA.ordinal();
else if(configuration.allowedKeyManagement.get(4)) //4 means WPA2_PSK
return WifiSecurityType.WIFICIPHER_WPA2.ordinal();
return WifiSecurityType.WIFICIPHER_INVALID.ordinal();
使用方法:
Activity生命周期中
//初始化WifiAPUtil类
WifiAPUtil.getInstance(getApplicationContext())
//注册handler
WifiAPUtil.getInstance(this).regitsterHandler(mHandler);
//接收message,做处理
private Handler mHandler = new Handler()
public void handleMessage(Message msg)
switch (msg.what)
case WifiAPUtil.MESSAGE_AP_STATE_ENABLED:
String ssid = WifiAPUtil.getInstance(WifiApActivity.this).getValidApSsid();
String pw = WifiAPUtil.getInstance(WifiApActivity.this).getValidPassword();
int security = WifiAPUtil.getInstance(WifiApActivity.this).getValidSecurity();
mWifiApState.setText("wifi热点开启成功"+"\\n"
+"SSID = "+ssid+"\\n"
+"Password = "+pw +"\\n"
+"Security = "+security);
break;
case WifiAPUtil.MESSAGE_AP_STATE_FAILED:
mWifiApState.setText("wifi热点关闭");
break;
default:
break;
;
在activity销毁的时候
@Override
protected void onDestroy()
super.onDestroy();
WifiAPUtil.getInstance(this).unregitsterHandler();
添加点击事件
//开启wifi热点
WifiAPUtil.getInstance(WifiApActivity.this).turnOnWifiAp(ssid, password, mWifiType);
//关闭wifi热点
WifiAPUtil.getInstance(WifiApActivity.this).closeWifiAp();
2 监听热点的状态
当wifi热点状态发送变化,系统会发送广播 android.net.wifi.WIFI_AP_STATE_CHANGED,所以我们只要注册监听这个广播就可以了。
wifi ap状态值。
public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
public static int WIFI_AP_STATE_DISABLING = 10;
public static int WIFI_AP_STATE_DISABLED = 11;
public static int WIFI_AP_STATE_ENABLING = 12;
public static int WIFI_AP_STATE_ENABLED = 13;
public static int WIFI_AP_STATE_FAILED = 14;
动态注册
public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
//注册广播接收者
IntentFilter filter = new IntentFilter();
filter.addAction(WIFI_AP_STATE_CHANGED_ACTION);
context.registerReceiver(mWifiStateBroadcastReceiver, filter);
广播接收者
通过监听wifiap状态的变化,发送消息给相关activity
//监听wifi热点状态变化
private BroadcastReceiver mWifiStateBroadcastReceiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
if(DEBUG)Log.i(TAG,"WifiAPUtils onReceive: "+intent.getAction());
if(WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction()))
int cstate = intent.getIntExtra(EXTRA_WIFI_AP_STATE, -1);
if(cstate == WIFI_AP_STATE_ENABLED)
if(mHandler != null)
mHandler.sendEmptyMessage(MESSAGE_AP_STATE_ENABLED);
if(cstate == WIFI_AP_STATE_DISABLED || cstate == WIFI_AP_STATE_FAILED)
if(mHandler != null)
mHandler.sendEmptyMessage(MESSAGE_AP_STATE_FAILED);
;
3 遗留问题
在配置wificonfiguration的时候有过属性是hiddenSSID,这个是设置wifi热点AP是否隐藏的,
但是设置wcfg.hiddenSSID = true或false并没有发现有什么不同,按理说设置为true,ssid隐藏应该搜索不到这个热点,
但是都可以搜索到。还请知道的可以留言指教,十分感谢。
之前有朋友说5.0系统的开启热点有问题,我这里没有5.0的手机,使用华为p9Android6.0手机测试确实开启不了热点,需要添加write_settings,添加上此权限就可以成功开启了。
apk测试 低版本下载:链接: https://pan.baidu.com/s/1dzK3rEiwlaD0QrpWe-Vrgg 提取码: 1qpr
apk测试 8.0下载:链接:https://pan.baidu.com/s/14mQqiaaz5ik0vht8MSYDpg 提取码:dwat
DEMO下载
以上是关于Android WiFi开发 Wifi热点的主要内容,如果未能解决你的问题,请参考以下文章
android手机如何获取自己手机设置的wifi热点的bssid