【问题标题】:Android: Turn On/Off WiFi Hotspot Programmatically on Android Marshmallow (6.0)Android:在 Android Marshmallow (6.0) 上以编程方式打开/关闭 WiFi 热点
【发布时间】:2016-02-09 12:25:47
【问题描述】:

我遇到了这个帖子 (Android: How to Enable/Disable Wifi or Internet Connection Programmatically),这与我想问的非常相似。我已经尝试了由 Ashish Sahu (https://stackoverflow.com/users/1780737/ashish-sahu) 发布的答案提供的解决方案,它似乎在除 Marshmallow (6.0) 之外的其他 Android 版本上完美运行。

是否可以在 Android Marshmallow 上切换和设置 WiFi 热点?我尝试使用 mHotspot (http://www.mhotspot.com/),它可以在 Android Marshmallow 上完成这项工作,但我只是不知道如何实现它。

提前致谢。

【问题讨论】:

  • 我设法通过使用我的 Ashish Sahu 在stackoverflow.com/questions/6394599/… 中提供的代码来修复它。并在 build.gradle 中将我的 targetSdkVersion 修复为低于 23。 Lex Hobbit 在答案中提供的代码也可以使用,但如前所述,Ashish Sahu 提供的代码看起来更干净。

标签: android wifi android-wifi android-6.0-marshmallow personal-hotspot


【解决方案1】:

我对这个问题的回答是:

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;

public class WifiAPController extends Activity {
    public int a;
    public int b;
    public String password;
    public String APname;

    private static int g;
    private static int h;
    private static int i;
    private static int j;
    private WifiManager wifiManager;
    private String logTAG;
    private int wifiState;
    private boolean o;

    class wifiControllerTask extends AsyncTask {
        WifiAPController wifiAPControllerClass;
        boolean a;
        boolean b;
        Context mContext;

        public wifiControllerTask(WifiAPController wifiAPController, boolean arg3, boolean arg4, Context context) {
            this.wifiAPControllerClass = wifiAPController;
            this.a = arg3;
            this.b = arg4;
            this.mContext = context;
        }

        protected Void a(Void[] arg3) {
            try {
                WifiAPController.wifiToggle(this.wifiAPControllerClass, this.a);
            } catch (Exception v0) {
            }
            return null;
        }

        public void a() {
            int sdkCurrentVersion = 21;
            try {
                if (this.a) {
                    if (Build.VERSION.SDK_INT < sdkCurrentVersion) {
                        return;
                    }

                    this.wifiAPControllerClass.wifiToggle(this.mContext);
                    return;
                }

                if (Build.VERSION.SDK_INT < sdkCurrentVersion) {
                    return;
                }
            } catch (Exception v0) {
                Log.e("noti error", v0.getMessage());
            }
        }

        protected void a(Void arg2) {
            super.onPostExecute(arg2);
            try {
                this.a();
            } catch (IllegalArgumentException v0) {
                try {
                    this.a();
                } catch (Exception v0_1) {
                }
            }

            if (this.b) {
                this.wifiAPControllerClass.finish();
            }
        }

        protected Object doInBackground(Object[] arg2) {
            return this.a(((Void[]) arg2));
        }

        protected void onPostExecute(Object arg1) {
            this.a(((Void) arg1));
        }

        protected void onPreExecute() {
            super.onPreExecute();
        }
    }


    static {
        WifiAPController.g = 0;
        WifiAPController.h = 0;
        WifiAPController.i = 1;
        WifiAPController.j = 4;
    }

    public WifiAPController() {
        super();
        this.a = 2;
        this.b = 3;
        this.logTAG = "WifiAP";
        this.wifiState = -1;
        this.o = false;
    }

    static int wifiToggle(WifiAPController wifiAPController, boolean wifiToggleFlag) {
        return wifiAPController.wifiToggle(wifiToggleFlag);
    }

    private void initWifiAPConfig(WifiConfiguration wifiConfiguration){
        wifiConfiguration.SSID = "SomeName";
        wifiConfiguration.preSharedKey = "SomeKey1";
        wifiConfiguration.hiddenSSID = false;
        wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        wifiConfiguration.allowedKeyManagement.set(4);
        wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    }

    private int wifiToggle(boolean wifiToggleFlag) {
        int wifiState;
        String stateString;
        StringBuilder message;
        long sleepTimeout = 500;
        int maxAttemptCount = 10;
        int errorState = -1;
        Log.d(this.logTAG, "*** setWifiApEnabled CALLED **** " + wifiToggleFlag);
        WifiConfiguration wifiConfiguration = new WifiConfiguration();
        initWifiAPConfig(wifiConfiguration);
        if ((wifiToggleFlag) && this.wifiState == errorState) {
            this.wifiState = this.wifiManager.getWifiState();
        }

        if (!(!wifiToggleFlag || this.wifiManager.getConnectionInfo() == null)) {
            Log.d(this.logTAG, "disable wifi: calling");
            this.wifiManager.setWifiEnabled(false);
            int attemptCount = maxAttemptCount;
            while (attemptCount > 0) {
                if (this.wifiManager.getWifiState() == 1) {
                    break;
                }

                Log.d(this.logTAG, "disable wifi: waiting, pass: " + (10 - attemptCount));
                try {
                    Thread.sleep(sleepTimeout);
                    --attemptCount;
                } catch (Exception v4_1) {
                }
            }

            Log.d(this.logTAG, "disable wifi: done, pass: " + (10 - attemptCount));
        }

        try {
            message = new StringBuilder();
            stateString = wifiToggleFlag ? "enabling" : "disabling";
            Log.d(this.logTAG, message.append(stateString).append(" wifi ap: calling").toString());
            Log.d(this.logTAG, this.APname);
            Log.d(this.logTAG, this.password);
            Log.d(this.logTAG, "" + this.wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class).invoke(this.wifiManager, wifiConfiguration, true).toString());
            int res = this.wifiManager.addNetwork(wifiConfiguration);
            Log.d(this.logTAG, "" + res);
            wifiState = (int) this.wifiManager.getClass().getMethod("getWifiApState").invoke(this.wifiManager);
            Log.d(this.logTAG, "" + wifiState);
        } catch (Exception v0_1) {
            Log.e("wifi", v0_1.getMessage());
            wifiState = errorState;
        }

        while (maxAttemptCount > 0) {
            if (this.wifiToggle() != WifiAPController.h && this.wifiToggle() != this.b && this.wifiToggle() != WifiAPController.j) {
                break;
            }
            message = new StringBuilder();
            stateString = wifiToggleFlag ? "enabling" : "disabling";
            Log.d(this.logTAG, message.append(stateString).append(" wifi ap: waiting, pass: ").append(10 - maxAttemptCount).toString());
            sleepTimeout = 500;
            try {
                Thread.sleep(sleepTimeout);
                --maxAttemptCount;
            } catch (Exception v0_1) {
            }
        }
        message = new StringBuilder();
        stateString = wifiToggleFlag ? "enabling" : "disabling";
        Log.d(this.logTAG, message.append(stateString).append(" wifi ap: done, pass: ").append(10 - maxAttemptCount).toString());

        if (!wifiToggleFlag) {
            if ((this.wifiState >= WifiManager.WIFI_STATE_ENABLING && this.wifiState <= WifiManager.WIFI_STATE_UNKNOWN) || (this.o)) {
                Log.d(this.logTAG, "enable wifi: calling");
                this.wifiManager.setWifiEnabled(true);
            }

            this.wifiState = errorState;
            return wifiState;
        }
        return wifiState;
    }

    public int wifiToggle() {
        int result;
        int v4 = 10;
        try {
            result = (int) this.wifiManager.getClass().getMethod("getWifiApState").invoke(this.wifiManager);
        } catch (Exception v0) {
            result = -1;
        }

        if (result >= v4) {
            WifiAPController.g = v4;
        }

        WifiAPController.h = WifiAPController.g;
        WifiAPController.i = WifiAPController.g + 1;
        this.a = WifiAPController.g + 2;
        this.b = WifiAPController.g + 3;
        WifiAPController.j = WifiAPController.g + 4;
        return result;
    }

    public void wifiToggle(Context context) {
        Intent v0 = new Intent(context, MainActivity.class);
    }

    public void wifiToggle(String apname, String pass, WifiManager wifiManager, Context context) {
        boolean v2 = true;
        if (this.wifiManager == null) {
            this.wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        }

        this.APname = apname;
        this.password = pass;
        int v0 = this.wifiToggle() == this.b || this.wifiToggle() == this.a ? 1 : 0;
        if (v0 != 0) {
            v2 = false;
        }

        new wifiControllerTask(this, v2, false, context).execute(new Void[0]);
    }
}

另外,在主 Activity 中你应该这样调用:

    WifiAPController wifiAPController  = new WifiAPController();
    wifiAPController.wifiToggle("mHotspot", "12345678", wifiManager, context);

不要忘记权限:

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

我在 Nexus 6 上使用 Marshmallow(6.0) 对此进行了测试

【讨论】:

  • 很抱歉我花了太长时间才回复...我尝试使用您的代码,但我是初学者,无法满足 wifiAPController.wifiToggle 中参数的要求...你能帮忙解决一下 wifiManager 和上下文吗?非常感谢您的帮助!
  • 上下文上下文 = getApplicationContext(); WifiManager wifiManager = (WifiManager) 上下文 .getSystemService(Context.WIFI_SERVICE);
  • 此方法无效。我在运行 Android 6.0.1 的 S6 上进行了测试。旧方法,简单地使用反射,会由于 WRITE_SETTINGS 未被授予而导致崩溃。我认为这不再是通过 3rd 方应用程序实现的了。
  • 有人验证吗?我做了反射的事情,它一直工作到我的 s6 上的 android 6.0.1 和你一样。希望他们没有永久破坏这一点。
  • 伙计们,请使用this note,正如@user2826067 所写的那样。这个更干净,适用于 6.0-7.1 Android。
【解决方案2】:

有人试一试吗?

http://www.ibtimes.co.uk/how-enable-tethering-android-6-0-marshmallow-update-1524792

它基本上说你运行一个 adb shell 并这样做:

设置将全局 tether_dun_required 设为 0

现在显然这不是应用程序可以做的事情,但我只想让我的 android 程序以编程方式在我的手机上为我打开和关闭网络共享,所以如果它对我有用,我会很高兴。 不过听起来,它只是取消了对运营商的控制,不确定它是否能绕过棉花糖本身对我们这些不幸的开发者造成的任何新限制。

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多