Android Marshmallow下按钮控制移动热点开关问题求助
解决Android Marshmallow(6.0)下无法开启移动热点的问题
嘿,我刚好踩过Android 6.0上手动开启热点的坑,结合你的描述,问题大概率出在权限处理和隐藏API的反射调用细节上,给你一步步拆解解决方案:
一、先补全必要的权限(Manifest+动态授权)
Android 6.0开始对系统设置类权限做了严格限制,只在Manifest加权限远远不够:
1. Manifest中必须声明的权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 关键:修改系统设置必须要这个权限,6.0+不能自动授权 --> <uses-permission android:name="android.permission.WRITE_SETTINGS" />
2. 动态申请WRITE_SETTINGS权限
这个权限无法通过常规的requestPermissions()申请,必须引导用户手动开启:
private boolean checkWriteSettingsPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Settings.System.canWrite(this)) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, 1001); return false; } else { return true; } } return true; }
在点击按钮触发热点操作前,先调用这个方法确保权限已获取。
二、正确的热点开启反射代码(适配6.0)
Android官方的WifiManager.setWifiApEnabled()是隐藏API,必须用反射调用,而且6.0下的方法签名要严格匹配:
完整的点击监听代码替换你的片段
btnHotspotOn.setOnClickListener(new View.OnClickListener() { @Override @SuppressLint("WifiManagerLeak") public void onClick(View v) { // 先检查权限 if (!checkWriteSettingsPermission()) { Toast.makeText(getApplicationContext(), "请授予修改系统设置权限", Toast.LENGTH_SHORT).show(); return; } WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); // 先关闭Wi-Fi(Android设备无法同时开启Wi-Fi和热点) if (wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(false); } try { // 反射获取WifiManager的隐藏方法 Method method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class); // 传入null表示使用默认配置(无密码的开放热点) boolean result = (boolean) method.invoke(wifiManager, null, true); if (result) { Toast.makeText(getApplicationContext(), "热点已开启", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "热点开启失败", Toast.LENGTH_SHORT).show(); } } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "反射调用失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } } });
三、关键注意事项
- Wi-Fi必须关闭:Android设备无法同时开启Wi-Fi和移动热点,所以开启前要先关闭Wi-Fi
- 默认配置限制:传入
null作为WifiConfiguration参数会开启无密码的开放热点,如果需要加密热点,你得构造对应的WifiConfiguration对象 - 反射兼容性:部分厂商ROM可能对隐藏API做了修改,如果反射失败,可能需要适配厂商的自定义方法(原生6.0系统无此问题)
内容的提问来源于stack exchange,提问作者SANKET DARWANTE
相关产品推荐
相关产品推荐

