使用startLocalOnlyHotspot创建热点无法被发现的问题及代码请求
问题原因与解决方案
startLocalOnlyHotspot 创建的是隐藏式WiFi热点(不主动广播SSID),所以普通设备的WiFi扫描列表无法直接发现它。另外你的代码缺少必要权限配置,也未正确获取热点的SSID和密码,导致无法正常连接。
1. 必要权限配置
在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 10+ 需添加 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Android 12+ 需添加 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
注意:Android 6.0+需动态申请位置权限,Android 12+需动态申请NEARBY_WIFI_DEVICES权限,否则热点无法正常启动。
2. 完整可运行代码
import android.Manifest; import android.content.pm.PackageManager; import android.net.wifi.WifiManager; import android.os.Handler; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import androidx.core.app.ActivityCompat; public class MainActivity extends AppCompatActivity { private WifiManager wifiManager; private WifiManager.LocalOnlyHotspotReservation hotspotReservation; private static final int PERMISSION_REQUEST_CODE = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); // 先检查权限 checkPermissions(); } private void checkPermissions() { boolean hasPermissions = true; // Android 12+ 检查NEARBY_WIFI_DEVICES权限 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) { hasPermissions = false; } } else { // 低版本检查位置权限 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { hasPermissions = false; } } // 检查WiFi相关权限 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) { hasPermissions = false; } if (!hasPermissions) { // 动态申请权限 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.NEARBY_WIFI_DEVICES, Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.ACCESS_WIFI_STATE}, PERMISSION_REQUEST_CODE); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.ACCESS_WIFI_STATE}, PERMISSION_REQUEST_CODE); } } else { // 权限已获取,启动热点 startLocalOnlyHotspot(); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQUEST_CODE) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { startLocalOnlyHotspot(); } else { Toast.makeText(this, "权限不足,无法启动热点", Toast.LENGTH_SHORT).show(); } } } private void startLocalOnlyHotspot() { if (wifiManager == null) { Toast.makeText(this, "无法获取WiFi服务", Toast.LENGTH_SHORT).show(); return; } if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) { return; } wifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() { @Override public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) { super.onStarted(reservation); hotspotReservation = reservation; // 获取热点信息 WifiManager.LocalOnlyHotspotReservation.HotspotConfiguration config = reservation.getConfiguration(); String ssid = config.SSID; String password = config.preSharedKey; Toast.makeText(MainActivity.this, "热点已启动\nSSID: " + ssid + "\n密码: " + password, Toast.LENGTH_LONG).show(); // 保存reservation用于后续停止热点 } @Override public void onStopped() { super.onStopped(); Toast.makeText(MainActivity.this, "热点已停止", Toast.LENGTH_SHORT).show(); hotspotReservation = null; } @Override public void onFailed(int reason) { super.onFailed(reason); String errorMsg = switch (reason) { case WifiManager.LocalOnlyHotspotCallback.REASON_BUSY -> "WiFi服务繁忙"; case WifiManager.LocalOnlyHotspotCallback.REASON_UNSUPPORTED -> "设备不支持该功能"; default -> "启动失败,未知原因"; }; Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_SHORT).show(); } }, new Handler()); } // 停止热点的方法 private void stopLocalOnlyHotspot() { if (hotspotReservation != null) { hotspotReservation.close(); } } @Override protected void onDestroy() { super.onDestroy(); // 页面销毁时停止热点 stopLocalOnlyHotspot(); } }
3. 如何连接隐藏热点
因为该热点是隐藏的,其他设备无法通过扫描发现,需要手动添加网络:
- 打开另一台设备的WiFi设置
- 选择“添加网络”或“手动输入网络”
- 输入代码中获取到的SSID、密码,加密方式选择
WPA2 PSK - 保存并连接
关键说明
startLocalOnlyHotspot是Android 8.0(API 26)引入的API,仅支持Android 8.0及以上设备- 该热点是本地仅用的,无法连接到互联网,仅用于设备间的局域网通信
- 热点会在App进程终止或调用
reservation.close()时自动停止
内容的提问来源于stack exchange,提问作者Reaz Ahammed
相关产品推荐
相关产品推荐

