web-dev-qa-db-ja.com

Android 8.0(Oreo)でプログラムでwifiホットスポットをオン/オフにする方法

Android以下の方法を使用して、リフレクションを使用してWiFiホットスポットをオン/オフにする方法を知っています。

private static boolean changeWifiHotspotState(Context context,boolean enable) {
        try {
            WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            Method method = manager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class,
                    Boolean.TYPE);
            method.setAccessible(true);
            WifiConfiguration configuration = enable ? getWifiApConfiguration(manager) : null;
            boolean isSuccess = (Boolean) method.invoke(manager, configuration, enable);
            return isSuccess;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

ただし、上記の方法は機能していませんAndroid 8.0(Oreo)。

上記のメソッドをAndroid 8.0で実行すると、logcatで次のステートメントが表示されます。

com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true

Android 8.0でホットスポットをオン/オフする他の方法はありますか

17
Chandrakanth

LocalOnlyHotspotルートが道だと思いましたが、@ edsappfactory.comがコメントで述べたように、それは閉じたネットワークのみを提供し、インターネットへのアクセスを提供しません。

Oreoでは、ホットスポッティング/テザリングはConnectionManagerとその注釈付き@SystemApiに移動したため、(名目上)アクセスできません。

私がやっていたことの一部として、アプリを作成して github here に配置しました。リフレクションを使用して関数を取得し、 DexMakerConnectionManager.OnStartTetheringCallbackのサブクラスを生成します(これにもアクセスできません)。

すべてうまくいくと思います-端が少し荒いので、自由に改善してください!

関連するコードのビットは次のとおりです。

MyOnStartTetheringCallback を起動するためにDexMakerで生成されたコールバックを取得しようとする忍耐力を失ったため、そのコードはすべて混乱してコメントアウトされました。

17
Jon

Jonの提案によると、Android Oreo以上でWifi HotSpotを有効にする別の方法がありました。

public boolean enableTetheringNew(MyTetheringCallback callback) {
    File outputDir = mContext.getCodeCacheDir();
    try {
        proxy = ProxyBuilder.forClass(classOnStartTetheringCallback())
                .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 (IOException e) {
        e.printStackTrace();
    }
    ConnectivityManager manager = (ConnectivityManager) mContext.getApplicationContext().getSystemService(ConnectivityManager.class);

    Method method = null;
    try {
        method = manager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, classOnStartTetheringCallback(), Handler.class);
        if (method == null) {
            Log.e(TAG, "startTetheringMethod is null");
        } else {
            method.invoke(manager, TETHERING_WIFI, false, proxy, null);

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

private Class classOnStartTetheringCallback() {
    try {
        return Class.forName("Android.net.ConnectivityManager$OnStartTetheringCallback");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}
3
Vishal Sharma