Android API to Connect to Wifi Network

戏子无情 提交于 2020-12-15 05:49:47

问题


I'm totaly lost in the versions of WiFi APIs. I want to connect to a configured WiFi Network programmaticaly. As decribed in this question: Connect to wifi network Android programmatically

I develop on Android 10 and want to write a code that is also compatible with older Android Versions.

On my android 10 the code described does not work. What code do I need to implement the functionality on Android 10?

What do I do to write an application that also runs on my other Android 9 phone?

Regards Jürgen


回答1:


Here is a solution working from Android 6 (API level 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()); 
 }



回答2:


From Android Q, connecting to Wifi Network has changes a lot.

First of all the code you are using or @matdev mentioned uses API public int addNetwork (WifiConfiguration config) from WifiManager is deprecated in Android 10 and will return -1 as networkID.

From Android Q, two classes are suggested for Wifi connection. But each of them has its own advantage and disadvantage.

1. WifiNetworkSpecifier

A code example from WifiUtil Library

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

My observation with this implementation is - It is more like P2P communication, and at this time other application from the same device cannot use internet from the connected WiFi network

2. WifiNetworkSuggestion 

A code example from 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);

My observation with the above mentioned implementation is, when you call the wifiManager.addNetworkSuggestions it return success and show user a notification for connection. If the user accept, device gets connected to the WiFi network and other app can user internet. But if user disconnect from network and you call wifiManager.addNetworkSuggestions again, it will return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE error.

It looks like this API just provide a suggestion list of networks where the device can auto connect. But the connection will be determined by the OS.

But if you really need a solution, an undocumented way use to the Default Wifi QR Code Scanner from Android Source that can detect both QR Code schems Zxing and DPP.

here is an a code example :

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


来源:https://stackoverflow.com/questions/63884367/android-api-to-connect-to-wifi-network

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!