首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Android8.0 (Oreo)中以编程方式打开/关闭wifi热点

如何在Android8.0 (Oreo)中以编程方式打开/关闭wifi热点
EN

Stack Overflow用户
提问于 2017-08-31 14:48:09
回答 3查看 29.1K关注 0票数 20

我知道如何使用下面的方法在android中使用反射打开/关闭wifi热点。

代码语言:javascript
运行
复制
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;
    }

,但上面的方法不适用于Android8.0(奥利奥).

当我在Android8.0中执行上述方法时,我在logcat中得到以下语句。

代码语言:javascript
运行
复制
com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true

在Android8.0上还有其他方式来打开/关闭hotspot吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-01 08:56:09

我终于找到解决办法了。Android8.0,他们提供了公共api来打开/关闭热点。WifiManager

下面的是打开hotspot的代码

代码语言:javascript
运行
复制
private WifiManager.LocalOnlyHotspotReservation mReservation;

@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
    WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

    manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {

        @Override
        public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
            super.onStarted(reservation);
            Log.d(TAG, "Wifi Hotspot is on now");
            mReservation = reservation;
        }

        @Override
        public void onStopped() {
            super.onStopped();
            Log.d(TAG, "onStopped: ");
        }

        @Override
        public void onFailed(int reason) {
            super.onFailed(reason);
            Log.d(TAG, "onFailed: ");
        }
    }, new Handler());
}

private void turnOffHotspot() {
    if (mReservation != null) {
        mReservation.close();
    }
}

如果热点打开,将调用onStarted(WifiManager.LocalOnlyHotspotReservation reservation)方法。使用WifiManager.LocalOnlyHotspotReservation引用,您可以调用close()方法来关闭hotspot。

注意:打开热点,Location(GPS)应该在设备中启用。否则,它将抛出SecurityException

票数 22
EN

Stack Overflow用户

发布于 2018-03-19 05:20:02

我原以为LocalOnlyHotspot路线是实现这一目标的途径,但正如@edsappfactory.com在评论中所说的那样--它只提供封闭的网络,没有互联网接入。

在奥利奥,热点/绑定移动到ConnectionManager,其注释的@SystemApi,所以(名义上)无法访问。

作为我正在做的事情的一部分,我制作了一个应用程序,并把它放在github这里上。它使用反射获取函数,使用DexMaker生成ConnectionManager.OnStartTetheringCallback的子类(这也是不可访问的)。

认为所有的工作,好-有点粗糙的边缘,所以请随时做得更好!

相关代码的内容如下:

我失去了耐心,试图让我的DexMaker生成的回调触发MyOnStartTetheringCallback,所以所有的代码都乱七八糟,被注释掉了。

票数 23
EN

Stack Overflow用户

发布于 2018-09-07 09:47:38

根据乔恩的建议,我找到了另一种方法来启用Android及以上版本的WifiHotSpot。

代码语言:javascript
运行
复制
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;
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45984345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档