Connect to Wifi in Android Q programmatically

谁都会走 提交于 2020-12-05 07:01:05

问题


I had this function to connect in Wifi network, below Android 10 it works fine, but when I tried on Android 10, I had a successful connection but WITHOUT internet, I knew it's a bug in Android 10 but I found this application which can connect to wifi from Android 10 with no problem. I'm blocked for days.

My function :

private void connectToWifi(String ssid, String password)
    {
        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            try {
                Log.e(TAG,"connection wifi pre Q");
                WifiConfiguration wifiConfig = new WifiConfiguration();
                wifiConfig.SSID = "\"" + ssid + "\"";
                wifiConfig.preSharedKey = "\"" + password + "\"";
                int netId = wifiManager.addNetwork(wifiConfig);
                wifiManager.disconnect();
                wifiManager.enableNetwork(netId, true);
                wifiManager.reconnect();

            } catch ( Exception e) {
                e.printStackTrace();
            }
        } else {
            Log.e(TAG,"connection wifi  Q");

            WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
                .setSsid( ssid )
                .setWpa2Passphrase(password)
                    .build();

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

             connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);


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

                     connectivityManager.bindProcessToNetwork(network);
                    Log.e(TAG,"onAvailable");
                }

                  @Override
                  public void onLosing(@NonNull Network network, int maxMsToLive) {
                      super.onLosing(network, maxMsToLive);
                      Log.e(TAG,"onLosing");
                  }

                  @Override
                public void onLost(Network network) {
                    super.onLost(network);
                    Log.e(TAG, "losing active connection");
                }

                @Override
                public void onUnavailable() {
                    super.onUnavailable();
                    Log.e(TAG,"onUnavailable");
                }
            };
            connectivityManager.requestNetwork(networkRequest,networkCallback);


        }
    }

回答1:


In case if you want to connect to WiFi with INTERNET, you should use this kind of NetworkRequest:

NetworkRequest request = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .setNetworkSpecifier(wifiNetworkSpecifier)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
    .build();

Also, you need specify default route for your process to make requests to connected WiFi AP permanently. Just add call of next method to your NetworkCallback under onAvaliable like this:

networkCallback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        createNetworkRoute(network, connectivityManager);
        }
    };
    if (connectivityManager!= null) connectivityManager.requestNetwork(request, networkCallback);

.

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private static void createNetworkRoute(Network network, ConnectivityManager connectivityManager) {
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
          connectivityManager.bindProcessToNetwork(network);
     } else {
          ConnectivityManager.setProcessDefaultNetwork(network);
     }
 } 

Don't forget disconnect from the bound network:

connectivityManager.unregisterNetworkCallback(networkCallback);

Finally, you can find best practice in different libraries like WifiUtils.




回答2:


If you have root access (adb root):

  1. Manually connect to the Wifi Network of your choosing.

  2. Pull these ADB files:

adb pull /data/misc/wifi/WifiConfigStore.xml
adb pull /data/misc/wifi/WifiConfigStore.xml.encrypted-checksum
  1. Save in a folder that would designate the Wifi Network:
Ex:  GarageWifi
Ex:  BusinessWifi

Copy to location of your choosing. Don't change the names of the files you pulled.

  1. Whenever you want to connect to a desired wifi network:
adb push <location>\WifiConfigStore.xml /data/misc/wifi/
adb push <location>\WifiConfigStore.xml.encrypted-checksum /data/misc/wifi/

adb reboot



回答3:


You can try wifisuggestion api, I'm able to connect using them.

final WifiNetworkSuggestion suggestion1 =
            new WifiNetworkSuggestion.Builder()
                    .setSsid("YOUR_SSID")
                    .setWpa2Passphrase("YOUR_PRE_SHARED_KEY")
                    .build();
    final List<WifiNetworkSuggestion> suggestionsList =
            new ArrayList<WifiNetworkSuggestion>();
    suggestionsList.add(suggestion1);

    WifiManager wifiManager =
            (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    int status = wifiManager.addNetworkSuggestions(suggestionsList);
    if (status == 0 ){
        Toast.makeText(this,"PSK network added",Toast.LENGTH_LONG).show();
        Log.i(TAG, "PSK network added: "+status);
    }else {
        Toast.makeText(this,"PSK network not added",Toast.LENGTH_LONG).show();
        Log.i(TAG, "PSK network not added: "+status);
    }



回答4:


So, the solution for me is compile your app with targetSdkVersion 28. and for connection to wifi use this function

connectToWifi(String ssid, String key)

it's just a workaround for the moment, waiting Google to publish a fix for this bug, for more information the issue reported to Google : issuetracker.google.com/issues/138335744

public void connectToWifi(String ssid, String key) {

Log.e(TAG, "connection wifi pre Q");
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = "\"" + ssid + "\"";
wifiConfig.preSharedKey = "\"" + key + "\"";
int netId = wifiManager.addNetwork(wifiConfig);
if (netId == -1) netId = getExistingNetworkId(wifiConfig.SSID);

wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();

}



来源:https://stackoverflow.com/questions/63124728/connect-to-wifi-in-android-q-programmatically

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