如何在Android API 29中使WifiManager工作

3
在使用wifi管理器连接Esp8266时,我突然收到了一个连接错误。输出已经说明了问题。我能够扫描并找到正确的SSID,但是在连接时要么拒绝连接,要么就是无法连接。查看文档后发现,Wifi Manager即将退出历史舞台,并且应该使用WifiNetworkSpecifier?但是这只适用于使用API29及以上版本的手机。我需要在所有手机上都能正常工作。
我已经从我的电脑连接到了Esp8266,并且得到了回应-没有Esp8266的连接问题。
public class ChooseDevice extends AppCompatActivity {

    private WifiManager wifiManager;
    private ListView listView;
    private ArrayList<String> arrayList = new ArrayList<>();
    private ArrayAdapter adapter;
    TextView TV_noDevicesFound;

    BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            List<ScanResult> results = wifiManager.getScanResults();
            unregisterReceiver(this);

            for (ScanResult scanResult : results) {
                Log.d("Here!!", scanResult.SSID);
                if (scanResult.SSID.startsWith("Cessabit")) {
                    arrayList.add(scanResult.SSID);
                    adapter.notifyDataSetChanged();

                }
            }

            if (arrayList.size()==0){
                TV_noDevicesFound.setVisibility(View.VISIBLE);
            }else{
                TV_noDevicesFound.setVisibility(View.INVISIBLE);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose_device);
        TV_noDevicesFound = findViewById(R.id.TV_noDevicesFound);
        listView = findViewById(R.id.deviceList);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String Device_SSID = listView.getItemAtPosition(position).toString();
                connectToDevice(Device_SSID);
                Intent intent = new Intent(ChooseDevice.this, ChooseWifi.class);
                startActivity(intent);
            }
        });

        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);


        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }


        adapter = new ArrayAdapter<>(this, R.layout.layout_list_item, R.id.DeviceTxtView, arrayList);
        listView.setAdapter(adapter);
    }



    private void connectToDevice(String SSID) {
        WifiInfo connection;
        Log.d("Connecting To SSID: ", SSID);
        WifiConfiguration conf = new WifiConfiguration();
        conf.SSID = "\"" + SSID + "\"";
        conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        int netID = wifiManager.addNetwork(conf);
        Log.d("netID", ""+netID);
        wifiManager.disconnect();
        wifiManager.enableNetwork(netID, true);
        wifiManager.reconnect();
        connection = wifiManager.getConnectionInfo();
        String ConnectedSSID = connection.getSSID();
        Log.d("Connected To SSID : ", ConnectedSSID);

    }

    @Override
    protected void onStop(){
        super.onStop();
        try{
            unregisterReceiver(wifiReceiver);
        }catch(final Exception exception){
            Log.d("Receiver try catch","cannot unregister receiver");
        }

    }
    @Override
    protected void onStart(){
        super.onStart();
        arrayList.clear();
        registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        wifiManager.startScan();
        Toast.makeText(this, "Scanning for Devices ..", Toast.LENGTH_SHORT).show();

    }


}

D/Connecting To SSID:: Cessabit-1111
I/zygote: Do partial code cache collection, code=107KB, data=80KB
I/zygote: After code cache collection, code=107KB, data=80KB
    Increasing code cache capacity to 512KB
D/netID: -1
V/NativeCrypto: Read error: ssl=0xec4b4768: I/O error during system call, Software caused connection abort
V/NativeCrypto: Write error: ssl=0xec4b4768: I/O error during system call, Broken pipe
V/NativeCrypto: SSL shutdown failed: ssl=0xec4b4768: I/O error during system call, Success
D/Connected To SSID :: <unknown ssid>

我猜测https://dev59.com/ILbna4cB1Zd3GeqPb4FR#63262649或许能帮助你解决WiFi切换的问题。 - Shredder
1个回答

1

由于API已更改,因此您需要针对Android 10及以上版本执行不同的操作。

请使用WifiNetworkSpecifier发送请求。在onAvailable()中使用提供的网络对象。

    private void connectToDevice(String SSID) {
       if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
           WifiInfo connection;
          Log.d("Connecting To SSID: ", SSID);
          WifiConfiguration conf = new WifiConfiguration();
          conf.SSID = "\"" + SSID + "\"";
          conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
          wifiManager = (WifiManager)  getApplicationContext().getSystemService(Context.WIFI_SERVICE);
          int netID = wifiManager.addNetwork(conf);
          Log.d("netID", ""+netID);
          wifiManager.disconnect();
          wifiManager.enableNetwork(netID, true);
          wifiManager.reconnect();
          connection = wifiManager.getConnectionInfo();
          String ConnectedSSID = connection.getSSID();
          Log.d("Connected To SSID : ", ConnectedSSID);
       } else {
              WifiNetworkSpecifier.Builder builder = new                   WifiNetworkSpecifier.Builder();
              builder.setSsid(SSID);

              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

                super.onAvailable(network);
            }
        };
       }

}

使用完Wifi访问点后,请执行以下操作:

connectivityManager.unregisterNetworkCallback(networkCallback);


3
这段代码在我的Android 10一加7T上无法运行。授权窗口会显示良好的ssid,但当我点击连接时,连接过程会开始“获取ip地址”,然后弹出一个“成功连接”的toast,但授权弹窗再次返回... - Aristide13
2
我在安卓10的OnePlus 6T上遇到了同样的问题。我收到一个弹窗提示连接到正确的网络,然后得到了相同的“连接成功”信息,接着又弹出了同样的弹窗。就像是一个循环... - Vladimir Petrovski
你是否在使用 onAvailable() 回调中提供的网络对象? - Anand Khinvasara
1
我也遇到了同样的问题,有解决方案吗? - Anand Khinvasara
我在你的代码中遇到了一个错误:请求不来自前台应用程序或服务。拒绝来自<myappname>的请求。我正在使用Android 10中的Wifi广播接收器。 - Luis A. Florit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接