1. 程式人生 > >Android 8.0 上面關於wifi 的一些坑

Android 8.0 上面關於wifi 的一些坑

背景

現在安卓系統已經更新到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卡資訊