1. Android開啟熱點(diǎn)的API
Android 8.0及以上,Android官方提供了開啟熱點(diǎn)的API
wifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback(){
@Override
public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
super.onStarted(reservation);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.i(TAG, "Wifi Hotspot is on now, " + reservation.getWifiConfiguration().SSID);
Log.i(TAG, "Wifi Hotspot is on now, " + reservation.getWifiConfiguration().preSharedKey);
}
}
@Override
public void onStopped() {
super.onStopped();
Log.i(TAG, "onStopped: ");
}
@Override
public void onFailed(int reason) {
super.onFailed(reason);
Log.i(TAG, "onFailed: ");
}
}, new Handler());
05-21 20:37:18.517 18966-18966/com.gnet.rxjavademo I/hotspot: Wifi Hotspot is on now, AndroidShare_6819
05-21 20:37:18.517 18966-18966/com.gnet.rxjavademo I/hotspot: Wifi Hotspot is on now, a329a61ae014
該API生成的熱點(diǎn)名稱和密碼都是隨機(jī)的字符串,也就是一次性的,回調(diào)中可以獲取到SSID和preSharedKey(就是密碼)。而且要注意以下兩點(diǎn):
- 1、需要網(wǎng)絡(luò)權(quán)限和定位權(quán)限(這點(diǎn)有點(diǎn)想不通)
int granted = ContextCompat.checkSelfPermission(this, Manifest.permission_group.LOCATION);
if (granted == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 0x11);
}
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 2、這個(gè)熱點(diǎn)是不能訪問外網(wǎng)的,只能是局域網(wǎng)內(nèi)使用,所以沒啥太大的用處。
- 3、保持這個(gè)熱點(diǎn)的引用是有生命周期,我自己的例子中是局部變量,wifiManager是Actvity的一個(gè)私有屬性,當(dāng)擁有該wifiManager的Activity被Destroy時(shí),當(dāng)前創(chuàng)建的這個(gè)本地?zé)狳c(diǎn)也會(huì)自動(dòng)關(guān)閉。因此,需要將這個(gè)wifiMananger放在生命周期更長的類中。
綜上,在Android 8.0上,沒有開啟可訪問互聯(lián)網(wǎng)的手機(jī)熱點(diǎn)的方法。
2. 獲取熱點(diǎn)開關(guān)狀態(tài):
Android的API是隱藏的,不能直接用,這里只能用反射的方式來獲取熱點(diǎn)開啟狀態(tài)
/**
* 判斷熱點(diǎn)是否開啟
* @param context
* @return
*/
public static boolean isWifiApOpen(Context context) {
try {
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//通過放射獲取 getWifiApState()方法
Method method = manager.getClass().getDeclaredMethod("getWifiApState");
//調(diào)用getWifiApState() ,獲取返回值
int state = (int) method.invoke(manager);
//通過放射獲取 WIFI_AP的開啟狀態(tài)屬性
Field field = manager.getClass().getDeclaredField("WIFI_AP_STATE_ENABLED");
//獲取屬性值
int value = (int) field.get(manager);
//判斷是否開啟
if (state == value) {
return true;
} else {
return false;
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return false;
}
3. 獲取當(dāng)前熱點(diǎn)的名稱:
獲取熱點(diǎn)名稱的API也是別隱藏了,通過反射的方式獲取。但是,Android 8.0以上,即使通過反射的方式也是獲取不到的,代碼運(yùn)行時(shí)會(huì)報(bào)SecurityException,后面會(huì)說Android 8.0上的處理方法。
public static String getWiFiApSSID(Context context) {
String ssid = "";
// Android 8 及以上無法獲取到ssid
if (Build.VERSION.SDK_INT < 26) {
try {
WifiManager manager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
//拿到getWifiApConfiguration()方法
Method method = manager.getClass().getDeclaredMethod("getWifiApConfiguration");
//調(diào)用getWifiApConfiguration()方法,獲取到 熱點(diǎn)的WifiConfiguration
WifiConfiguration configuration = (WifiConfiguration) method.invoke(manager);
ssid = configuration.SSID;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
/*BluetoothAdapter myDevice = BluetoothAdapter.getDefaultAdapter();
ssid = myDevice.getName();*/
return "";
}
return ssid;
}
針對Android 8.0以上,沒有現(xiàn)成的API可用。經(jīng)過搜索,發(fā)現(xiàn)可以通過獲取手機(jī)名稱來獲取熱點(diǎn)名稱。


在系統(tǒng)設(shè)置,關(guān)于手機(jī)界面,有設(shè)備名稱,在名稱修改界面可以看到一行字:“使用藍(lán)牙互聯(lián)、WiFi直連、熱點(diǎn)共享和USB連接時(shí),其他設(shè)備將看到此名稱”
也就是說,設(shè)備名稱和熱點(diǎn)名稱是保持一致的。
于是,尋找獲取手機(jī)名稱的方法:
BluetoothAdapter myDevice = BluetoothAdapter.getDefaultAdapter();
String deviceName = myDevice.getName();
但是,這個(gè)方法也有問題,就是它只能獲取手機(jī)默認(rèn)的名稱,如果用戶手動(dòng)修改了設(shè)備名稱,這個(gè)方法返回的還是默認(rèn)的名稱。
所以,沒招了。。。誰有更好的方法,歡迎留言。
4. Android開啟熱點(diǎn)本機(jī)IP
Android手機(jī)開啟熱點(diǎn)后,本機(jī)的IP地址是固定的192.168.43.1