android(6.0,11.0)自动开启wifi热点获取热点(SSID)账号密码(getPassphrase)

296 阅读2分钟

(1).增加权限

   AndroidManifest.xml声明权限
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

(2).导入依赖库

build.gradle导入依赖声明
api 'com.linkedin.dexmaker:dexmaker:2.28.1' // ProxyBuilder依赖包
api 'com.github.getActivity:XXPermissions:16.2' // 权限申请依赖包

(3.)WiFi获取工具类

import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class WifiApUtil {

    public static final String TAG = WifiApUtil.class.getSimpleName();
    
    // wifi热点开关
    public static void setWifiApEnabled(boolean isEnable) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
            Log.d(TAG, "安卓6.0及以下,使用setWifiApEnabled反射,开启关闭热点。");

            WifiManager mWifiManager = (WifiManager) MyApplication.applicationContext.getSystemService(Context.WIFI_SERVICE);

            try {
                Method methodWifiApState = mWifiManager.getClass().getMethod("getWifiApState");
                int getWifiApState = (Integer) methodWifiApState.invoke(mWifiManager);

                // 获取属性值
                Field field = mWifiManager.getClass().getDeclaredField("WIFI_AP_STATE_ENABLED");
                int value = (int) field.get(mWifiManager);

                if (isEnable) {
                    if (getWifiApState == value) {
                        Log.d(TAG, "热点已开启");
                        return;
                    }
                }

                Method methodWifiApConfiguration = mWifiManager.getClass().getMethod("getWifiApConfiguration");
                WifiConfiguration mWifiConfiguration = (WifiConfiguration) methodWifiApConfiguration.invoke(mWifiManager);

                Method methodWifiApEnabled = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
                boolean flag = (Boolean) methodWifiApEnabled.invoke(mWifiManager, mWifiConfiguration, isEnable);
                Log.d(TAG, "热点" + (isEnable ? "开启" : "关闭") + "操作状态:" + flag);

                if (flag) {
                    if (isEnable) {
                        Log.d(TAG, "热点成功开启");
                    }
                }

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
            return;
        }

        TestOreoWifiManager mTestOreoWifiManager = new TestOreoWifiManager();
        if (isEnable) {
            Log.d(TAG, "安卓7.0以上,以proxy实现,开启关闭热点。");

            TestOreoWifiManager.TestOnStartTetheringCallback mCallback = new TestOreoWifiManager.TestOnStartTetheringCallback() {
                @Override
                public void onTetheringStarted() {
                    Log.d(TAG, "热点开启状态:" + "onTetheringStarted");
                }

                @Override
                public void onTetheringFailed() {
                    Log.d(TAG, "热点开启操作状态:" + "onTetheringFailed。");
                    Log.d(TAG, "onTetheringFailed");
                }
            };
            mTestOreoWifiManager.startTethering(mCallback);

        } else {
            mTestOreoWifiManager.stopTethering();
        }
    }

    // 关闭热点
    public static void closeWifiAp() {
        WifiApUtil.setWifiApEnabled(false);
    }

}

(4)TestOreoWifiManager工具类

import android.net.ConnectivityManager;
import android.os.Handler;
import android.util.Log;

import com.android.dx.stock.ProxyBuilder;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;

public class TestOreoWifiManager {

    public static final String TAG = TestOreoWifiManager.class.getSimpleName();

    public interface TestOnStartTetheringCallback {

        /**
         * Called when tethering has been successfully started.
         */
        void onTetheringStarted();

        /**
         * Called when starting tethering failed.
         */
        void onTetheringFailed();

    }

    private ConnectivityManager mConnectivityManager;

    public TestOreoWifiManager() {
        mConnectivityManager = MyApplication.applicationContext.getSystemService(ConnectivityManager.class);
    }

    /**
     * Checks where tethering is on.
     * This is determined by the getTetheredIfaces() method, that will return an empty array if not devices are tethered
     *
     * @return true if a tethered device is found, false if not found
     */
    public boolean isTetherActive() {
        try {
            Method method = mConnectivityManager.getClass().getDeclaredMethod("getTetheredIfaces");
            if (method == null) {
                Log.e(TAG, "getTetheredIfaces is null");
            } else {
                String[] res = (String[]) method.invoke(mConnectivityManager, null);
                Log.d(TAG, "getTetheredIfaces invoked");
                Log.d(TAG, Arrays.toString(res));
                if (res.length > 0) {
                    return true;
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Error in getTetheredIfaces");
            e.printStackTrace();
        }
        return false;
    }


    /**
     * This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
     * Does not require app to have system/privileged access
     * Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
     */
    public boolean startTethering(final TestOnStartTetheringCallback callback) {
        // On Pie if we try to start tethering while it is already on, it will be disabled. This is needed when startTethering() is called programmatically.
        if (isTetherActive()) {
            Log.d(TAG, "Tether already active, returning");
            return false;
        }

        File outputDir = MyApplication.applicationContext.getCodeCacheDir();
        Object proxy;
        try {
            proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass()).dexCache(outputDir).handler(new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    switch (method.getName()) {
                        case "onTetheringStarted":
                            callback.onTetheringStarted();
                            break;

                        case "onTetheringFailed":
                            callback.onTetheringFailed();
                            break;

                        default:
                            ProxyBuilder.callSuper(proxy, method, args);
                    }
                    return null;
                }

            }).build();

        } catch (Exception e) {
            Log.e(TAG, "Error in enableTethering ProxyBuilder");
            e.printStackTrace();
            return false;
        }

        Method method = null;
        try {
            method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
            if (method == null) {
                Log.e(TAG, "startTetheringMethod is null");
            } else {
                method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
                Log.d(TAG, "startTethering invoked");
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, "Error in enableTethering");
            e.printStackTrace();
        }
        return false;
    }

    public void stopTethering() {
        try {
            Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
            if (method == null) {
                Log.e(TAG, "stopTetheringMethod is null");
            } else {
                method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
                Log.d(TAG, "stopTethering invoked");
            }
        } catch (Exception e) {
            Log.e(TAG, "stopTethering error: " + e.toString());
            e.printStackTrace();
        }
    }

    private Class OnStartTetheringCallbackClass() {
        try {
            return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
        } catch (ClassNotFoundException e) {
            Log.e(TAG, "OnStartTetheringCallbackClass error: " + e.toString());
            e.printStackTrace();
        }
        return null;
    }

}


(5)权限申请方法


开启热点代码
public void requestSystemSetPermissionAndOptionWifiAp() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            // 安卓6.0以下,不需要申请权限
            WifiApUtil.setWifiApEnabled(true);
        } else {
            // 安卓6.0及以上,需要申请修改系统设置权限
            XXPermissions.with(BaseActivity.this).permission(Permission.WRITE_SETTINGS).request(new OnPermissionCallback() {
                @Override
                public void onGranted(List<String> permissions, boolean all) {
                    if (all) {
                        // 已有权限,开启本地热点
                        WifiApUtil.setWifiApEnabled(true);
                    }
                }

                @Override
                public void onDenied(List<String> permissions, boolean never) {
                    // 用户已禁止权限,弹框提示
                    showDialog("软件需要申请修改系统设置权限,是否去开启相关权限?", new OnDialogClickListener() {
                        @Override
                        public void cancelClick(DialogInterface dialog) {
                            // 用户拒绝进行授权
                            showToast("没有授予相关权限,部分功能将受影响");
                        }

                        @Override
                        public void okClick(DialogInterface dialog) {
                            // 用户同意再次请求权限
                            XXPermissions.startPermissionActivity(BaseActivity.this, permissions, new OnPermissionPageCallback() {
                                @Override
                                public void onGranted() {
                                    requestSystemSetPermissionAndOptionWifiAp();
                                }

                                @Override
                                public void onDenied() {
                                    requestSystemSetPermissionAndOptionWifiAp();
                                }
                            });
                        }
                    });
                }
            });
        }
    }

(7).关闭热点

关闭热点
WifiApUtil.setWifiApEnabled(false);