android 7.1 开启WiFi热点

最近项目需要一个开启WiFi热点的功能,由于Android 7.1实现机制跟之前版本有所不同,在网上搜索了很久终于解决了这个问题,特意把过程记录下来,希望大家不要踩坑。

开启WiFi热点函数  主要参考博客 : https://blog.csdn.net/zhang01/article/details/79222057

可以用一个按钮来触发开启热点。

public boolean setWifiApEnabled(boolean enabled) {
        if (enabled) { // disable WiFi in any case
            wifiManager.setWifiEnabled(false);
        }
       
        wifiManager = (WifiManager)getApplicationContext().getSystemService(WIFI_SERVICE);
        mContext = this;
        handler = new Handler(getMainLooper());
        try {
            mResultReceiver = new ResultReceiver(handler);
            WifiConfiguration apConfig = new WifiConfiguration();
            apConfig.SSID = "asdf";
            apConfig.preSharedKey = "12121212";
            apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {             
                Method mMethod = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
                mMethod.invoke(wifiManager,apConfig);              
                ConnectivityManager connectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);              
                Field mField = connectivityManager.getClass().getDeclaredField("TETHERING_WIFI");
                mField.setAccessible(true);
                WriteToLog.writeToLog("field.setAccessible ");
                int mTETHERING_WIFI = (int)mField.get(connectivityManager);
                Log.v("mTETHERING_WIFI:",String.valueOf(mTETHERING_WIFI));       
                Field iConnMgrField = connectivityManager.getClass().getDeclaredField("mService");
                iConnMgrField.setAccessible(true);
                Object iConnMgr = iConnMgrField.get(connectivityManager);
                Class iConnMgrClass = Class.forName(iConnMgr.getClass().getName());             
                Method mStartTethering1 = iConnMgrClass.getMethod("startTethering", int.class,ResultReceiver.class,boolean.class);
                mStartTethering1.setAccessible(true);
                mStartTethering1.invoke(iConnMgr, mTETHERING_WIFI,new ResultReceiver(handler){
                    @Override
                    protected void onReceiveResult(int resultCode, Bundle resultData) {
                    super.onReceiveResult(resultCode, resultData);
                    }
                },true);
                return true;
            } else {
                Method method = wifiManager.getClass().getMethod(
                        "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
                return (Boolean) method.invoke(wifiManager, apConfig, enabled);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            WriteToLog.writeToLog("setWifiApEnabled Exception1: " + e.getMessage());
            return false;
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            WriteToLog.writeToLog("setWifiApEnabled Exception2: " + e.getMessage());
            return false;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            WriteToLog.writeToLog("setWifiApEnabled Exception3: " + e.getMessage());
            return false;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            WriteToLog.writeToLog("setWifiApEnabled Exception4: " + e.getMessage());
            return false;
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            WriteToLog.writeToLog("setWifiApEnabled Exception5: " + e.getMessage());
            return false;
        }
    }

但是运行这个代码以后会抛出异常InvocationTargetException :null 

需要在AndroidManifest.xml文件中增添:android:sharedUserId="andorid.uid.system"

打包出apk,使用 signapk.jar 给自己的apk签名。

java -jar signapk.jar platform.x509.pem platform.pk8 src.apk  dst.apk

将签名好的apk 使用adb push 到手机的/system/app下,注意要使用chmod更改权限

reboot 重启手机  此时你就会发现你的apk的user变成了system这个时候就可以成功开启热点了。

你可能感兴趣的:(android,studio,android)