Android应用程式可动态开启/关闭wifi热点

时间:2019-12-01 09:27:16

标签: android android-wifi personal-hotspot

我想在我的Android应用程序项目中动态控制wifi热点。我已经厌倦了 Reflection (在Android Oreo及更高版本中将无法使用), startLocalOnyNetwork (但我想要特定的 SSID PASSWORD ,无法对其进行配置)。

然后我将手机固定在了手机上,是否可以将手机固定在手机上?

期望一个api使用特定的 SSID PASSWORD 来打开/关闭wifi热点,或者使用上一个。

有没有可能或解决方法?

谢谢。

1 个答案:

答案 0 :(得分:0)

要打开Wifi热点,需要一些权限

<uses-permission android:name="android.permission.WRITE_SETTINGS"
    tools:ignore="ProtectedPermissions" />

,该权限应由用户动态授予

在应用高级设置->修改系统设置

In apps advanced settings -> Modify system settings

/**
 * 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() {
    File outputDir = mContext.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 {
                        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();
    }
}

使用上述方法使用设置中定义的SSID和密码打开/关闭Wifi热点。

private int AP_STATE_DISABLED = 11;
private int AP_STATE_ENABLING = 12;
private int AP_STATE_ENABLED = 13;
private int AP_STATE_ERROR = 14;

/**
 * @return status hot spot enabled or not
 */
public boolean isHotSpotEnabled(Context context) {
    Method method = null;
    int actualState = 0;
    try {
        WifiManager mWifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        method = mWifiManager.getClass().getDeclaredMethod("getWifiApState");
        method.setAccessible(true);
        actualState = (Integer) method.invoke(mWifiManager, (Object[]) null);
        if (actualState == AP_STATE_ENABLING ||actualState ==  AP_STATE_ENABLED) {
            return true;
        }
    } catch (IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

以上方法可用于获取热点的当前状态