Android wifiz自动连接 自动切换 适配 Android 10 api 29 失败问题

项目中需要app自动连接设备热点通信。测试中发现android10的设备无法连接。通过查看Android api文档发现在29之后新增了

WifiNetworkSpecifier 操作管理类 
WifiManager 中的相关函数都已经废弃

所有参考官方问题 适配29之后的连接(头疼处是需要手动确认连接,有知道如何避免弹窗的伙伴可以留言。感激不尽)

判断系统版本

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    changeToWifiAfterQ(wifiName, wifiPwd);
} else {
    changeToWifiBeforeQ(wifiName, wifiPwd);
}

changeToWifiAfterQ的处理过程会有确认弹窗,并有是否连接的回调

 //setSsidPattern/setSsid/setBssidPattern/setBssid should be invoked for specifier
            NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
//                        .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
                    .setSsid(wifiName)
                    .setWpa2Passphrase(wifiPwd)
//                    .setBssid(MacAddress.fromString(scan.BSSID))
                    .build();

            NetworkRequest request =
                    new NetworkRequest.Builder()
                            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                            .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                            .setNetworkSpecifier(specifier)
                            .build();

            networkCallback = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(@NonNull Network network) {
                    super.onAvailable(network);
                    Log.i(TAG, "onAvailable 切换到指定wifi成功");
                    connectivityManager.unregisterNetworkCallback(networkCallback);
                }

                @Override
                public void onUnavailable() {
                    super.onUnavailable();
                    Log.i(TAG, "onUnavailable 切换到指定wifi失败");
                    connectivityManager.unregisterNetworkCallback(networkCallback);
                }
            };
            connectivityManager.requestNetwork(request, networkCallback);

 

全部内容:

使用 

WifiUtil.getIns().init(application);
WifiUtil.getIns().changeToWifi("enee.....n","1234567890");
/**
 * @author zjp1002038
 */
public class WifiUtil {


    private ConnectivityManager connectivityManager;
    private WifiManager mWifiManager;

    private ConnectivityManager.NetworkCallback networkCallback;

    public void changeToWifi(String wifiName, String wifiPwd) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            changeToWifiAfterQ(wifiName, wifiPwd);
        } else {
            changeToWifiBeforeQ(wifiName, wifiPwd);
        }
    }

    /**
     * 切换到指定wifi Android版本小于10
     *
     * @param wifiName 指定的wifi名字
     * @param wifiPwd  wifi密码,如果已经保存过密码,可以传入null
     * @return
     */
    public void changeToWifiBeforeQ(String wifiName, String wifiPwd) {
        if (mWifiManager == null) {
            Log.i(TAG, " ***** init first ***** ");
            return;
        }

        String mWifiName = "\"" + wifiName + "\"";

        /**
         * 判断定位权限
         */
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        //获取wifi列表
        List wifiList = mWifiManager.getConfiguredNetworks();
        boolean bFindInList = false;
        for (int i = 0; i < wifiList.size(); ++i) {
            WifiConfiguration wifiInfo0 = (WifiConfiguration) wifiList.get(i);

            // 先找到对应的wifi
            if (mWifiName.equals(wifiInfo0.SSID) || wifiName.equals(wifiInfo0.SSID)) {
                // 1、 先启动,可能已经输入过密码,可以直接启动
                Log.i(TAG, " set wifi 1 = " + wifiInfo0.SSID);
                doChange2Wifi(wifiInfo0.networkId);
                return;
            }
        }

        // 2、如果wifi还没有输入过密码,尝试输入密码,启动wifi
        if (!bFindInList) {
            WifiConfiguration wifiNewConfiguration = createWifiInfo(wifiName, wifiPwd);//使用wpa2的wifi加密方式
            int newNetworkId = mWifiManager.addNetwork(wifiNewConfiguration);
            if (newNetworkId == -1) {
                Log.e(TAG, "操作失败,需要您到手机wifi列表中取消对设备连接的保存");
            } else {
                doChange2Wifi(newNetworkId);
            }
        }
    }


    /**
     * 切换到指定wifi Android版本大于等于10
     *
     * @param wifiName 指定的wifi名字
     * @param wifiPwd  wifi密码,如果已经保存过密码,可以传入null
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.Q)
    public void changeToWifiAfterQ(String wifiName, String wifiPwd) {
        if (mWifiManager == null || connectivityManager == null) {
            Log.i(TAG, " ***** init first ***** ");
            return;
        }

        /**
         * 判断定位权限
         */
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        //获取wifi扫描列表
//        List<ScanResult> wifiList = mWifiManager.getScanResults();
//        ScanResult scan = null;
//        for (ScanResult scanResult : wifiList) {
//            if (wifiName.equals(scanResult.SSID)) {
//                scan = scanResult;
//                break;
//            }
//        }
        //扫描到了Wi-Fi
//        if (null != scan) {
            //setSsidPattern/setSsid/setBssidPattern/setBssid should be invoked for specifier
            NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
//                        .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
                    .setSsid(wifiName)
                    .setWpa2Passphrase(wifiPwd)
//                    .setBssid(MacAddress.fromString(scan.BSSID))
                    .build();

            NetworkRequest request =
                    new NetworkRequest.Builder()
                            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                            .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                            .setNetworkSpecifier(specifier)
                            .build();

            networkCallback = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(@NonNull Network network) {
                    super.onAvailable(network);
                    Log.i(TAG, "onAvailable 切换到指定wifi成功");
                    connectivityManager.unregisterNetworkCallback(networkCallback);
                }

                @Override
                public void onUnavailable() {
                    super.onUnavailable();
                    Log.i(TAG, "onUnavailable 切换到指定wifi失败");
                    connectivityManager.unregisterNetworkCallback(networkCallback);
                }
            };
            connectivityManager.requestNetwork(request, networkCallback);
//        }else{
//            Log.e(TAG, "未找到目标Wi-Fi");
//        }

    }

    private boolean doChange2Wifi(int newNetworkId) {
        // 如果wifi权限没打开(1、先打开wifi,2,使用指定的wifi
        if (!mWifiManager.isWifiEnabled()) {
            mWifiManager.setWifiEnabled(true);
        }

        boolean enableNetwork = mWifiManager.enableNetwork(newNetworkId, true);
        if (!enableNetwork) {
            Log.e(TAG, "切换到指定wifi失败");
            return false;
        } else {
            Log.e(TAG, "切换到指定wifi成功");
            return true;
        }
    }

    /**
     * 创建 WifiConfiguration,这里创建的是wpa2加密方式的wifi
     *
     * @param ssid     wifi账号
     * @param password wifi密码
     * @return
     */
    private WifiConfiguration createWifiInfo(String ssid, String password) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + ssid + "\"";
        config.preSharedKey = "\"" + password + "\"";
        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        config.status = WifiConfiguration.Status.ENABLED;
        return config;
    }

    public static final String TAG = "WifiUtil";

    private static final WifiUtil ourInstance = new WifiUtil();
    private static Context mContext;

    public static WifiUtil getIns() {
        return ourInstance;
    }

    public void init(Context context) {
        mContext = context;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            connectivityManager = (ConnectivityManager)
                    mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        }
        mWifiManager = (WifiManager) mContext.getSystemService(WIFI_SERVICE);
    }

}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用ConstraintLayout实现Android Studio的UI宽度与设备自动适配的示例代码: ``` <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textView" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout> ``` 在这个示例中,我们使用了ConstraintLayout作为根布局,并且使用了约束来定义TextView的位置和大小。注意到TextView的宽度设置为0dp,这样它的宽度就可以自适应设备的宽度了。 如果需要设置视图的宽度和高度百分比,可以使用“app:layout_constraintWidth_percent”和“app:layout_constraintHeight_percent”属性,例如: ``` <TextView android:id="@+id/textView" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintWidth_percent="0.5" /> ``` 这样TextView的宽度就为屏幕宽度的50%了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值