Android Q,以编程方式连接到Internet的不同WiFi AP



与Android Q中一样,限制了几个WiFi API。我正在尝试使用备用API连接到Internet的其他WiFi AP。

以下是我的代码:

    WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
    builder.setSsid("wifi-ap-ssid");
    builder.setWpa2Passphrase("wifi-ap-password");
    WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
    NetworkRequest.Builder networkRequestBuilder1 = new NetworkRequest.Builder();
    networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
    networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier);
    NetworkRequest nr = networkRequestBuilder1.build();
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    cm.requestNetwork(nr, callback);

这使我可以连接,但是互联网是禁用的。这是在Android文档中定义的。

我尝试的替代方式如下:

    WifiNetworkSuggestion.Builder wifiNetworkSuggestionBuilder1 = new WifiNetworkSuggestion.Builder();
    wifiNetworkSuggestionBuilder1.setSsid("wifi-ap-ssid");
    wifiNetworkSuggestionBuilder1.setWpa2Passphrase("wifi-ap-password");
    WifiNetworkSuggestion wifiNetworkSuggestion = wifiNetworkSuggestionBuilder1.build();
    List<WifiNetworkSuggestion> list = new ArrayList<>();
    list.add(wifiNetworkSuggestion);
    wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    wifiManager.removeNetworkSuggestions(new ArrayList<WifiNetworkSuggestion>());
    wifiManager.addNetworkSuggestions(list);

在清单中声明许可:

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

使用这种行为不会改变任何行为。

请告知API的顺序,以成功连接到具有Internet功能的其他WiFi AP。

尝试在onavailable((回调中调用bindprocesstonetwork((重新获得网络连接,对我来说很好。

连接到网络:

    WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
    builder.setSsid("wifi-ap-ssid");
    builder.setWpa2Passphrase("wifi-ap-password");
    WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
    NetworkRequest.Builder networkRequestBuilder1 = new NetworkRequest.Builder();
    networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
    networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier);
    NetworkRequest nr = networkRequestBuilder1.build();
    ConnectivityManager cm = (ConnectivityManager)
            context.getSystemService(Context.CONNECTIVITY_SERVICE);
    ConnectivityManager.NetworkCallback networkCallback = new 
        ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(Network network) {
            super.onAvailable(network);
            Log.d(TAG, "onAvailable:" + network);
            cm.bindProcessToNetwork(network);
        }
    });
    cm.requestNetwork(nr, networkCallback);

与绑定网络断开连接:

cm.unregisterNetworkCallback(networkCallback);

wifinetworksuggestion api用于建议用户加入AP(系统将发布通知以供用户加入(

使用wifinetworkspecifier发送您的请求。使用Onavailable((中提供的网络对象。

WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
builder.setSsid("wifi-ap-ssid");
builder.setWpa2Passphrase("wifi-ap-password");
WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier);
NetworkRequest networkRequest = networkRequestBuilder.build();
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.requestNetwork(networkRequest, networkCallback);
networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(@NonNull Network network) {
                //Use this network object to Send request. 
                //eg - Using OkHttp library to create a service request
                 //Service is an OkHttp interface where we define docs. Please read OkHttp docs
                 Service service = null;
                 OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
                okHttpBuilder.socketFactory(network.getSocketFactory());
                service = new Retrofit.Builder()                                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                        .addConverterFactory(GsonConverterFactory.create(gson))
                         .client(okHttpBuilder.build())
                         .build()
                         .create(Service.class);

               Observable<Object> observable = null;
               try {
                  if (service != null) {
                     observable = service.yourRestCall();
                  }
                  Subscriber<Object> sub = new Subscriber< Object >() {
                     @Override
                     public void onError(Throwable e) {
                        //Do on error
                     }
                     @Override
                     public void onNext(Object logs) {
                        //Do on next
                     }
                  };
                 if(observable != null) {
                     observable.subscribeOn(Schedulers.io())
                                          .observeOn(AndroidSchedulers.mainThread()).subscribe(sub);
                 }
                super.onAvailable(network);
            }
        };

使用WiFi访问点DO

完成后

connectivityManager.unregisterNetworkCallback(networkCallback);

来自Google的Google工程师的Google问题跟踪器:

网络建议API流程要求用户批准该应用程序(平台发布通知以询问用户批准(。批准该应用程序后,该平台将在将来的自动连接尝试中考虑该应用程序中的所有网络。但是,此API不能保证该设备何时连接到您的AP进行配置。因此,wifinetworksuggestion不是提供的用例(同行到即时连接(的正确API表面。

使用WiFinetworkSpecifier建立了与WiFi访问点的本地连接,如上所述。在这种情况下,默认网络仍将是蜂窝网络(我们不会破坏其他应用程序的Internet连接(。提出请求的应用程序应使用多网络API将其流量路由到已建立的连接上。|网络|该请求的onavailable((回调中提供的对象是应用程序需要使用的句柄来通过该本地网络打开插座(请访问https://developer.android.com/reference.com/reference/reference/android/android/net/network.htwork.html#bindsocket(java.net.datagramsocket(和其他此类API在|网络|对象表面。

希望这会有所帮助。

如下所述,Android 10有意使Wifinetworkspifier防止实际的Internet连接。它是为了使同行连接。

但是,Wifinetworksuggestion API提供了Internet连接性,并且与Wifinetworkspecifier API的行为相似。只要该设备是当前未连接到任何WiFi网络>,WiFinetworkSuggestion API将自动连接到指定的网络。设备第一次使用它时,会出现通知,询问该应用程序是否可以建议网络。用户必须接受此通知,以使WiFinetworksuggestion API工作。

我发现Android在Wifinetworksuggestion文档中提供的代码有一些编译错误。这是我发现可以使用的代码:

final WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
.setSsid("SSID here")
.setWpa2Passphrase("password here")
.setIsAppInteractionRequired(true) // Optional (Needs location permission)
.build();
// Optional extra suggesstion, you can delete this or add more
final WifiNetworkSuggestion suggestion2 = new WifiNetworkSuggestion.Builder()
.setSsid("SSID here 2")
.setWpa2Passphrase("password here 2")
.setIsAppInteractionRequired(true) // Optional (Needs location permission)
.build();
final List<WifiNetworkSuggestion> suggestionsList = new ArrayList<WifiNetworkSuggestion>();
suggestionsList.add(suggestion1);
suggestionsList.add(suggestion2); // Optional extra suggestion
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
final int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
     // Error handling
}
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;
        }
        // Post connection
    }
};
getApplicationContext().registerReceiver(broadcastReceiver, intentFilter);

您应该在q

中使用Wi-Fi网络建议API
final WifiNetworkSuggestion suggestion1 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test111111")
  .setIsAppInteractionRequired() // Optional (Needs location permission)
  .build()
final WifiNetworkSuggestion suggestion2 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test222222")
  .setWpa2Passphrase("test123456")
  .setIsAppInteractionRequired() // Optional (Needs location permission)
  .build()
final WifiNetworkSuggestion suggestion3 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test333333")
  .setWpa3Passphrase("test6789")
  .setIsAppInteractionRequired() // Optional (Needs location permission)
  .build()
final List<WifiNetworkSuggestion> suggestionsList =
  new ArrayList<WifiNetworkSuggestion> {{
    add(suggestion1);
    add(suggestion2);
    add(suggestion3);
  }};
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);

ConnectivityManager.NetworkCallback()上的onAvailable(Network)回调内(设置WifiNetworkSpecifier.Builder()NetworkRequest.Builder()之后(,请致电ConnectivityManager.bindProcessNetwork,以指导您在连接的网络上的流量,如Network API:https:https:https://htttps:https://。

标识网络。这是通过ConnectivitionManager.networkCallback响应Active ConnectivitionManager#requestNetwork或无源连接Manager#regissherNetworkCallback调用的。它用于通过插座将流量引导到给定的网络,或者通过针对性的套接字或通过ConnectivitionManager#bindProcesstonetwork。

....
private inner class MyCallback : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        // Call this method once this callback is triggered after
        // your call to mConnectivityManager.requestNetwork()
        mConnectivityManager.bindProcessToNetwork(network)
    }
    ....
}
....

最新更新