Android WiFi开发 (二)Wifi热点

版权声明:本文出自朋永的博客,转载必须注明出处。 https://blog.csdn.net/VNanyesheshou/article/details/50812271

接着上一篇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,添加上此权限就可以成功开启了。

DEMO下载


猜你喜欢

转载自blog.csdn.net/VNanyesheshou/article/details/50812271