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卡信息

猜你喜欢

转载自blog.csdn.net/banzhihuanyu/article/details/81056561