Android 8.0 上面關於wifi 的一些坑
阿新 • • 發佈:2019-02-01
背景
現在安卓系統已經更新到8.0了。曾經開啟手機wifi以及搜尋wifi的方法可能對8.0的安卓系統不管用了。這裡就提一些在開發中遇到的坑。
一. 開啟wifi 以及 關閉wifi
首先需要開啟修改系統設定的許可權:
private void createWifiHotspot(){
if(wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(false);
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
Log.d("MainActivity","Android 8.0及以上");
if(!Settings.System.canWrite(this)){
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity (intent);
}
else{
setWifiApEnabledForAndroid_O();
}
return;
}
Log.d("MainActivity","Android 8.0及以下");
setWifiApEnabledForAndroid();
}
然後如果是SDK26以上的版本,就用下面的程式碼開啟或關閉wifi。
在網上也能搜到一些別人提到的教程,管用的是這個:
public void setWifiApEnabledForAndroid_O(){
ConnectivityManager connManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY _SERVICE);
Field iConnMgrField;
try{
iConnMgrField = connManager.getClass().getDeclaredField("mService");
iConnMgrField.setAccessible(true);
Object iConnMgr = iConnMgrField.get(connManager);
Class<?> iConnMgrClass = Class.forName(iConnMgr.getClass().getName());
Method startTethering = iConnMgrClass.getMethod("startTethering",int.class,ResultReceiver.class,boolean.class);
startTethering.invoke(iConnMgr,0,null,true);
Toast.makeText(getApplicationContext(),"熱點建立成功",Toast.LENGTH_SHORT).show();
}catch (Exception e){
e.printStackTrace();
}
}
private void closeWifiHotspot_O(){
ConnectivityManager connManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
Field iConnMgrField;
try{
iConnMgrField = connManager.getClass().getDeclaredField("mService");
iConnMgrField.setAccessible(true);
Object iConnMgr = iConnMgrField.get(connManager);
Class<?> iConnMgrClass = Class.forName(iConnMgr.getClass().getName());
Method stopTethering = iConnMgrClass.getMethod("stopTethering",int.class);
stopTethering.invoke(iConnMgr,0);
Toast.makeText(getApplicationContext(),"熱點關閉成功",Toast.LENGTH_SHORT).show();
}catch (Exception e){
e.printStackTrace();
}
}
記得申請對應的許可權
二. 搜尋wifi
其實還是用WifiManager物件的startScan()方法,但是需要申請ACCESS_COARSE_LOCATION許可權,而且要動態獲取。
三. 連線wifi後建立熱點,卻無法用socket連線上server
具體情況是:一部手機建立熱點作為sever,開啟新的執行緒,線上程裡利用ServerSocket監聽連線。另一部手機作為client,連線上熱點後,利用WifiManager的例項的方法getDhcpInfo() 連線Server。然鵝,連線超時或連線拒絕。
原來是需要在manifest檔案中申請兩個許可權:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />//向sd卡寫入
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />//讀取sd卡資訊