zoukankan      html  css  js  c++  java
  • Android WiFi热点7.1以上版本适配

    代码地址如下:
    http://www.demodashi.com/demo/13907.html

    一、准备工作

    开发环境:
     jdk1.8
     AS(3.0.1)
    运行环境:
     华为V10(Android8.0)、华为p20(Android8.1)、华为mate10(Android8.0)

    实现功能:
      Wifi热点的开启关闭。

    二、代码结构

    工程目录

    三、代码详解

    Android 7.0及以前Wifi热点
    Android 7.1、8.0Wifi热点

    看之前评论发现Android7.1以上的手机开启Wifi热点后不能正常使用,故研究了一下如何解决次问题。

    Android 7.0 开启Wifi热点

    在Android7.0及以前的版本开启Wifi热点的方式如下:

    WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",
                            WifiConfiguration.class, boolean.class);
    //反射
    method.invoke(mWifiManager, null, false);
    

    Android 7.1 开启Wifi热点

    对于Android7.1、8.0的设备,通过WifiManager setWifiApEnabled,可以打开Wifi热点,但是会发现此热点,连接不上(由于DHCP没有开启),所以不会分配ip地址,也就导致不能正常使用。

    在Android7.1系统应用Settings,发现其开启热点的方式是通过ConnectivityManager的startTethering方法来开启的。
    查看ConnectivityManager的方法
    三个参数
    四个参数
    startTethering 是隐藏的方法,并且第三个参数OnStartTetheringCallback是ConnectivityManager内部抽象类,也是隐藏的。

    /**
    * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
    * @hide
    */
    @SystemApi
    public static abstract class OnStartTetheringCallback {
        /**
         * Called when tethering has been successfully started.
         */
        public void onTetheringStarted() {};
        /**
    	 * Called when starting tethering failed.
         */
    	public void onTetheringFailed() {};
    }
    

    通过反射的方式并没有找到方式获取startTethering方法,以及创建OnStartTetheringCallback子对象。

    后来通过另一种方式实现了。

    配置jar包

    首先修改ConnectivityManager源码,将TETHERING_WIFI字段、startTethering方法及OnStartTetheringCallback类中隐藏相关的标志去掉,然后单独编译一个jar包。
    将jar包拷贝到工程中,如下所示:
    wifiap jar包
    该jar包会和官方sdk中的android.jar会有冲突,所以需要配置jar包的优先级。
    在app的build.gradle中配置

    provided files('src/main/libs/WifiAp8.jar')
    

    在工程下的build.gradle中添加如下配置:

    allprojects {
        
        gradle.projectsEvaluated {
            tasks.withType(JavaCompile) {
            //设置jar相对包路径或绝对路径
                options.compilerArgs.add('-Xbootclasspath/p:app/src/main/libs/WifiAp8.jar')
            }
        }
    }
    
    编写代码

    开启热点

    if(getWifiAPState() != WIFI_AP_STATE_ENABLED){
    	//Android7.1及以上版本
        if (Build.VERSION.SDK_INT >= 25) {
            mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI,
                    true, new ONStartTetheringCallback());
        }
    }
    

    红色不影响
    在AS中上述代码会有红色显示,但是不影响编译使用。可以正常编译生成apk。使用该方法不需要提前关闭wifi。

    ONStartTetheringCallback类继承了OnStartTetheringCallback抽象类。

    class ONStartTetheringCallback extends
            ConnectivityManager.OnStartTetheringCallback {
    }
    

    关闭热点

    if(getWifiAPState() != WIFI_AP_STATE_DISABLED){
    	//Android7.1及以上版本
        if (Build.VERSION.SDK_INT >= 25) {
            mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
        }
    }
    

    权限
    使用上述功能需要这三个权限:

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    

    还需要在代码中申请WRITE_SETTINGS权限,否则不能正常使用。

    这样就可以了,不只是系统应用可以使用,平成的应用也可以正常使用。亲测(华为P20、华为mate10、华为V10都可以正常使用)。

    欢迎大家关注、评论、点赞
    你们的支持是我坚持的动力。
    欢迎关注我的微信公众号Android WiFi热点7.1以上版本适配

    代码地址如下:
    http://www.demodashi.com/demo/13907.html

    注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

  • 相关阅读:
    pymysql模块的使用
    MySQL创建用户、授权和备份
    多表查询
    单表查询
    mysql性能优化2
    mysql性能优化1
    穷人的思维
    thinkphp所有参数配置
    似水流年
    memecached常用命令
  • 原文地址:https://www.cnblogs.com/demodashi/p/9582552.html
Copyright © 2011-2022 走看看