【问题标题】:Android API to Connect to Wifi NetworkAndroid API 连接到 Wifi 网络
【发布时间】:2020-09-14 12:30:02
【问题描述】:

我完全迷失在 WiFi API 的版本中。 我想以编程方式连接到配置的 WiFi 网络。 如this question所述: Connect to wifi network Android programmatically

我在 Android 10 上开发,想编写一个也兼容旧 Android 版本的代码。

在我的 android 10 上,所描述的代码不起作用。 在 Android 10 上实现该功能需要哪些代码?

如何编写一个也可以在我的其他 Android 9 手机上运行的应用程序?

问候于尔根

【问题讨论】:

标签: android wifi android-wifi android-developer-api


【解决方案1】:

从 Android Q 开始,连接 Wifi 网络发生了很大变化。

首先,您使用的代码或@matdev 提到的使用来自WifiManager 的API public int addNetwork (WifiConfiguration config) 在Android 10 中已弃用,并将返回-1 作为networkID。

在 Android Q 中,建议使用两个类用于 Wifi 连接。但是他们每个人都有自己的优点和缺点。

1. WifiNetworkSpecifier

WifiUtil 库中的代码示例

WifiNetworkSpecifier.Builder wifiNetworkSpecifierBuilder = new WifiNetworkSpecifier.Builder()
            .setSsid(scanResult.SSID)
            .setBssid(MacAddress.fromString(scanResult.BSSID));

    final String security = ConfigSecurities.getSecurity(scanResult);

    ConfigSecurities.setupWifiNetworkSpecifierSecurities(wifiNetworkSpecifierBuilder, security, password);


    NetworkRequest networkRequest = new NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .setNetworkSpecifier(wifiNetworkSpecifierBuilder.build())
            .build();

    // not sure, if this is needed
    if (networkCallback != null) {
        connectivityManager.unregisterNetworkCallback(networkCallback);
    }

    networkCallback = new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(@NonNull Network network) {
            super.onAvailable(network);

            wifiLog("AndroidQ+ connected to wifi ");

            // bind so all api calls are performed over this new network
            connectivityManager.bindProcessToNetwork(network);
        }

        @Override
        public void onUnavailable() {
            super.onUnavailable();

            wifiLog("AndroidQ+ could not connect to wifi");
        }
    };

    connectivityManager.requestNetwork(networkRequest, networkCallback);

我对这个实现的观察是 - 它更像是 P2P 通信,此时来自同一设备的其他应用程序无法使用连接的 WiFi 网络中的互联网

2. WifiNetworkSuggestion 

来自 developer.android.com 的代码示例

final WifiNetworkSuggestion suggestion1 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test111111")
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final WifiNetworkSuggestion suggestion2 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test222222")
  .setWpa2Passphrase("test123456")
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final WifiNetworkSuggestion suggestion3 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test333333")
  .setWpa3Passphrase("test6789")
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final PasspointConfiguration passpointConfig = new PasspointConfiguration();
// configure passpointConfig to include a valid Passpoint configuration

final WifiNetworkSuggestion suggestion4 =
  new WifiNetworkSuggestion.Builder()
  .setPasspointConfig(passpointConfig)
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final List<WifiNetworkSuggestion> suggestionsList =
  new ArrayList<WifiNetworkSuggestion> {{
    add(suggestion1);
    add(suggestion2);
    add(suggestion3);
    add(suggestion4);
  }};

final WifiManager wifiManager =
  (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

final int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
// do error handling here…
}

// Optional (Wait for post connection broadcast to one of your suggestions)
final IntentFilter intentFilter =
  new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    if (!intent.getAction().equals(
      WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
      return;
    }
    // do post connect processing here...
  }
};
context.registerReceiver(broadcastReceiver, intentFilter);

我对上述实现的观察是,当您调用wifiManager.addNetworkSuggestions 时,它会返回成功并向用户显示连接通知。如果用户接受,设备将连接到 WiFi 网络,其他应用程序可以使用互联网。但是如果用户断开网络,你再次调用wifiManager.addNetworkSuggestions,它会返回 WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE错误。

看起来这个 API 只是提供了设备可以自动连接的网络的建议列表。但连接将由操作系统决定。

但如果您真的需要解决方案,可以使用 Android Source 的 Default Wifi QR Code Scanner 的无证方法,该扫描器可以检测 QR Code schems Zxing 和 DPP。

这是一个代码示例:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode == REQUEST_CODE_WIFI_QR_SCANNER && resultCode == RESULT_OK)
    {
        //WIFI Connection is Successful
    }
    else
    {
        //.......
    }
}

@RequiresApi(api = Build.VERSION_CODES.Q)
private void startWifiQRCodeScanner(Context context)
{
    final String INTENT_ACTION_WIFI_QR_SCANNER = "android.settings.WIFI_DPP_ENROLLEE_QR_CODE_SCANNER";
    WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

    if(wifiManager.isEasyConnectSupported())
    {
        final Intent intent = new Intent(INTENT_ACTION_WIFI_QR_SCANNER);
        startActivityForResult(intent, REQUEST_CODE_WIFI_QR_SCANNER);
    }
}

【讨论】:

  • @Dharman 如果您有带有 wifi 信息的二维码,您的无证方式才有效,对吧?这种方式在你不想使用二维码扫描器的时候是行不通的吧?
  • @JulianSchweppe,是的,除非您使用二维码扫描仪,否则这种方式将不起作用。
【解决方案2】:

这是一个适用于 Android 6(API 级别 23)的解决方案

String AP_SSID = "YourWifiNetworkSSID";
String AP_PASSWORD = "YourWifiNetworkPassword";
wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);

WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + AP_SSID + "\"";   // Please note the quotes. String should contain ssid in quotes

conf.preSharedKey = "\"" + AP_PASSWORD + "\"";

wifiManager.addNetwork(conf);

try {
    List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();

    for (WifiConfiguration i : list) {
        if (i.SSID != null && i.SSID.equals("\"" + AP_SSID + "\"")) {
            wifiManager.disconnect();
            wifiManager.enableNetwork(i.networkId, true);
            wifiManager.reconnect();

            break;
        }
    }
 } catch (SecurityException e) {
     Log.e(TAG, e.getMessage()); 
 }

【讨论】:

  • 您好,感谢您提供代码。我已经找到了这个。问题是从 Android 版本 9 到版本 10 的边界。有很多更改,此代码将不再运行。那么有没有人有处理跨android版本代码的概念? android 10的代码也可以。有什么想法吗??
猜你喜欢
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2015-05-20
  • 2021-03-29
  • 2012-03-02
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多