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

Android网络开发之WIFI

如何在Ubuntu下建立虚拟wifi热点供Android,Kindle

android怎么开启wifi热点

Android中WIFI开发总结

Android 修改默认WiFi热点名称