Android 設定Wifi熱點、開啟與關閉的監聽
阿新 • • 發佈:2019-01-31
用過360的面對面快傳,快牙的朋友應該都知道,它們在兩臺裝置間實現檔案傳輸都是通過WiFi熱點實現的,下面我們就來探討一下如何設定熱點名和密碼,並自動建立一個wifi熱點吧,以及如何監聽熱點的開啟與關閉。
一、建立WiFi熱點
其實建立熱點很簡單,先獲取到wifi的服務,再配置熱點名稱、密碼等等,然後再通過反射開啟它就OK了,需要注意的是手機的WiFi連線與熱點是不可同時開啟的,也就是說如果手機連上了一個現有WiFi,就無法開啟自身熱點,反之亦然。所以在開啟熱點是先判斷WiFi是否開啟,如果開啟則先關閉WiFi,然後再根據設定的熱點名和密碼建立熱點。廢話少說,直接上程式碼:
package com.wjj.wifihotmanager; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import android.content.Context; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; /** * @ClassName: WifiHotUtil * @Description: 列印日誌資訊WiFi熱點工具 * @author: jajuan.wang * @date: 2015-05-28 15:12 * version:1.0.0 */ public class WifiHotUtil { public static final String TAG = "WifiApAdmin"; private WifiManager mWifiManager = null; private Context mContext = null; public WifiHotUtil(Context context) { mContext = context; mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); } public void startWifiAp(String ssid, String passwd) { //wifi和熱點不能同時開啟,所以開啟熱點的時候需要關閉wifi if (mWifiManager.isWifiEnabled()) { mWifiManager.setWifiEnabled(false); } if (!isWifiApEnabled()) { stratWifiAp(ssid, passwd); } } /** * 設定熱點名稱及密碼,並建立熱點 * @param mSSID * @param mPasswd */ private void stratWifiAp(String mSSID, String mPasswd) { Method method1 = null; try { //通過反射機制開啟熱點 method1 = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class); WifiConfiguration netConfig = new WifiConfiguration(); netConfig.SSID = mSSID; netConfig.preSharedKey = mPasswd; netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN); netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA); netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); method1.invoke(mWifiManager, netConfig, true); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } /** * 熱點開關是否開啟 * @return */ public boolean isWifiApEnabled() { try { Method method = mWifiManager.getClass().getMethod("isWifiApEnabled"); method.setAccessible(true); return (Boolean) method.invoke(mWifiManager); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return false; } /** * 關閉WiFi熱點 */ public void closeWifiAp() { WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); if (isWifiApEnabled()) { try { Method method = wifiManager.getClass().getMethod("getWifiApConfiguration"); method.setAccessible(true); WifiConfiguration config = (WifiConfiguration) method.invoke(wifiManager); Method method2 = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class); method2.invoke(wifiManager, config, false); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } }
呼叫方式:在activity中:
//例項化WiFi熱點工具類
wifiHotUtil = new WifiHotUtil(this);
//建立熱點
wifiHotUtil.startWifiAp(defaultHotName, defaultHotPwd);
//關閉熱點
wifiHotUtil.closeWifiAp();
二、監聽熱點的開啟與關閉
經過查詢資料發現,android的行動式熱點開啟與關閉都會發出 android.net.wifi.WIFI_AP_STATE_CHANGED 的廣播,但是行動式熱點相關的資訊在WiFimanage中是隱藏的,這個廣播是隱藏的。那我們怎麼監聽呢?好不容易在stackoverflow上找到了解決辦法,連線地址: Monitoring
the Hotspot state in Android,實現程式碼如下:
註冊這個廣播監聽器,就可以監聽熱點的開啟與關閉狀態了。private BroadcastReceiver wifiReceiver = new BroadcastReceiver(){ public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if ("android.net.wifi.WIFI_AP_STATE_CHANGED".equals(action)) { //行動式熱點的狀態為:10---正在關閉;11---已關閉;12---正在開啟;13---已開啟 int state = intent.getIntExtra("wifi_state", 0); Log.i(TAG, "state= "+state); wiFiAPObserver.stateChanged(state); } } };
我使用的是服務+觀察者模式,應用啟動時啟動熱點監聽服務,用於監聽熱點開啟與關閉的狀態。activity或其他需要獲取熱點狀態的地方可以通過服務註冊監聽器,當熱點狀態改變時會遍歷通知每個註冊的例項。上程式碼:
package com.wjj.wifihotmanager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
/**
* @ClassName: WiFiAPService
* @Description: wifi hot manage service
* @author: jajuan.wang
* @date: 2015-06-09 00:43
* version:1.0.0
*/
public class WiFiAPService extends Service {
private static String TAG = "WiFiAPService";
public static String ACTION_START_SERVICE = "action_start_service";
public static String ACTION_STOP_SERVICE = "action_stop_service";
private static WiFiAPObserver wiFiAPObserver = new WiFiAPObserver();
/**
* static method to start service
* @param context
*/
public static void startService(Context context) {
Intent intent = new Intent(context, WiFiAPService.class);
intent.setAction(ACTION_START_SERVICE);
context.startService(intent);
}
/**
* static method to stop service
* @param context
*/
public static void stopService(Context context) {
Intent intent = new Intent(context, WiFiAPService.class);
intent.setAction(ACTION_STOP_SERVICE);
context.startService(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.i(TAG, "intent.getAction()="+intent.getAction());
// option based on action
if (intent.getAction().equals(ACTION_START_SERVICE) == true) {
//startService();
} else if (intent.getAction().equals(ACTION_STOP_SERVICE) == true) {
stopSelf();
}
//重傳Intent。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啟該服務,並將Intent的值傳入。
return Service.START_REDELIVER_INTENT;
}
@Override
public void onCreate() {
registerReceiver(wifiReceiver,new IntentFilter("android.net.wifi.WIFI_AP_STATE_CHANGED"));
super.onCreate();
}
@Override
public void onDestroy() {
unregisterReceiver(wifiReceiver);
wiFiAPObserver.clearWiFiAPListener();
super.onDestroy();
}
/**
* register wiFiAPListener
* @param wiFiAPListener
*/
public static void addWiFiAPListener(WiFiAPListener wiFiAPListener) {
wiFiAPObserver.addWiFiAPListener(wiFiAPListener);
}
/**
* remove wiFiAPListener
* @param wiFiAPListener
*/
public static void removeWiFiAPListener(WiFiAPListener wiFiAPListener) {
wiFiAPObserver.removeWiFiAPListener(wiFiAPListener);
}
private BroadcastReceiver wifiReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("android.net.wifi.WIFI_AP_STATE_CHANGED".equals(action)) {
//行動式熱點的狀態為:10---正在關閉;11---已關閉;12---正在開啟;13---已開啟
int state = intent.getIntExtra("wifi_state", 0);
Log.i(TAG, "state= "+state);
wiFiAPObserver.stateChanged(state);
}
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
熱點監聽器:
package com.wjj.wifihotmanager;
/**
* @ClassName: WiFiAPListener
* @Description: Listenning the state of wifi hot
* @author: jajuan.wang
* @date: 2015-06-09 00:52
* version:1.0.0
*/
public interface WiFiAPListener {
public static final int WIFI_AP_CLOSEING = 10; //wifi hot is closeing
public static final int WIFI_AP_CLOSE_SUCCESS = 11; //wifi hot close success
public static final int WIFI_AP_OPENING = 12; //WiFi hot is opening
public static final int WIFI_AP_OPEN_SUCCESS = 13; //WiFi hot open success
/**
* the state of wifi hot changed
* @param state
*/
public void stateChanged(int state) ;
}
熱點狀態觀察者:
package com.wjj.wifihotmanager;
import java.util.HashSet;
/**
* @ClassName: WiFiAPObserver
* @Description: Listenning the state of wifi hot
* @author: jajuan.wang
* @date: 2015-06-09 00:58
* version:1.0.0
*/
public class WiFiAPObserver implements WiFiAPListener {
/**
* the set to save all registed listener
*/
private HashSet<WiFiAPListener> listenerSet = new HashSet<WiFiAPListener>();
/**
* add wiFiAPListener
* @param wiFiAPListener
*/
public void addWiFiAPListener(WiFiAPListener wiFiAPListener) {
if (!listenerSet.contains(wiFiAPListener)) {
listenerSet.add(wiFiAPListener);
}
}
/**
* remove the wiFiAPListener
* @param wiFiAPListener
*/
public void removeWiFiAPListener(WiFiAPListener wiFiAPListener) {
if (listenerSet.contains(wiFiAPListener)) {
listenerSet.remove(wiFiAPListener);
}
}
/**
* remove all WiFiAPListener
*/
public void clearWiFiAPListener() {
listenerSet.clear();
}
@Override
public void stateChanged(int state) {
//notify all Listener the state changed
for (WiFiAPListener wiFiAPListener : listenerSet) {
wiFiAPListener.stateChanged(state);
}
}
}