API Android để kết nối với mạng Wifi

Sep 14 2020

Tôi hoàn toàn bị lạc trong các phiên bản của API WiFi. Tôi muốn kết nối với Mạng WiFi được định cấu hình theo chương trình. Như đã viết trong câu hỏi này: Kết nối với mạng wifi Android theo chương trình

Tôi phát triển trên Android 10 và muốn viết mã cũng tương thích với các phiên bản Android cũ hơn.

Trên Android 10 của tôi, mã được mô tả không hoạt động. Tôi cần mã nào để triển khai chức năng trên Android 10?

Tôi phải làm gì để viết một ứng dụng cũng chạy trên điện thoại Android 9 khác của mình?

Trân trọng Jürgen

Trả lời

matdev Sep 14 2020 at 13:06

Đây là một giải pháp hoạt động từ Android 6 (API cấp 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()); 
 }
MdImtiazHossain Nov 18 2020 at 09:17

Từ Android Q, việc kết nối với Mạng Wifi đã có nhiều thay đổi.

Trước hết, mã bạn đang sử dụng hoặc @matdev được đề cập sử dụng API public int addNetwork (WifiConfiguration config)từ WifiManagerkhông được dùng nữa trong Android 10 và sẽ trả về -1 dưới dạng ID mạng.

Từ Android Q, hai lớp được đề xuất cho kết nối Wifi. Nhưng mỗi người trong số họ đều có ưu và nhược điểm riêng.

1. WifiNetworkSpecifier

Ví dụ về mã từ Thư viện 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);

Quan sát của tôi với việc triển khai này là - Nó giống như giao tiếp P2P và tại thời điểm này, ứng dụng khác từ cùng một thiết bị không thể sử dụng internet từ mạng WiFi được kết nối

2. WifiNetworkSuggestion 

Một ví dụ về mã từ 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);

Quan sát của tôi với việc triển khai được đề cập ở trên là, khi bạn gọi wifiManager.addNetworkSuggestionsnó sẽ trả về thành công và hiển thị cho người dùng một thông báo kết nối. Nếu người dùng chấp nhận, thiết bị sẽ được kết nối với mạng WiFi và ứng dụng khác có thể sử dụng internet. Nhưng nếu người dùng ngắt kết nối mạng và bạn gọi wifiManager.addNetworkSuggestionslại, nó sẽ trả về WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATElỗi.

Có vẻ như API này chỉ cung cấp danh sách đề xuất các mạng mà thiết bị có thể tự động kết nối. Nhưng kết nối sẽ được xác định bởi Hệ điều hành.

Nhưng nếu bạn thực sự cần một giải pháp, một cách không có giấy tờ hãy sử dụng Trình quét mã QR Wifi mặc định từ Nguồn Android có thể phát hiện cả hai lược đồ Mã QR Zxing và DPP.

đây là một ví dụ về mã:

@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);
    }
}