android通过代码连接wifi

Android SDK API 29(对应Android 10)以下,可以在app之中通过代码直接设置wifi名称和密码进行连接。

API 29及其以上版本,增加了动态管理权限功能,弃用了之前的接口,同时app连接wifi时必须通过用户同意,具体方式是弹出一个页面显示要连接的wifi,用户点击连接之后再返回app。

1. API < 29

a. 首先初始化,检查权限,若无则申请权限

//检查wifi权限
if (ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    //若无则申请
    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
else
{
    //初始化
    wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
}

 b. 扫描wifi,以供后续操作,若不执行这一步直接连接则会出错:

//扫描并列出wifi,以供后续操作
wifiScanReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        boolean success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
        if (success) {
            scanResults = wifiManager.getScanResults();

            for (ScanResult scanResult : scanResults) {
                String SSID = scanResult.SSID;
                String BSSID = scanResult.BSSID;
                String capabilities = scanResult.capabilities;
                int level = scanResult.level;

                Log.d("WIFISCAN", "SSID: " + SSID + ", BSSID: " + BSSID);
            }
        }
    }
};

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(wifiScanReceiver, intentFilter);
wifiManager.startScan();

c. 连接指定wifi,此处为了演示直接填写ssid和密码,实际情况之中可以从上一步的wifi列表之中选取,并由用户输入(api>=29时这一步是可以运行,但无连接wifi的效果):

WifiConfiguration wifiConfiguration = new WifiConfiguration();
//注意,密码和SSID两边必须再加一对双引号!!!
wifiConfiguration.SSID = "\"wifi SSID\"";  
wifiConfiguration.preSharedKey = "\"password\"";

int networkId = wifiManager.addNetwork(wifiConfiguration);
//wifiManager.disconnect();  //断开链接
wifiManager.enableNetwork(networkId, true);
wifiManager.reconnect();
Log.d("ConnectWifi", "reconnect ok!");

2. API < 29的另一个解决方案,使用WifiUtils库:

GitHub - ThanosFisherman/WifiUtils: Easily Connect to WiFi Networks

更加简单,适用于api小于29的android,api>29时无法正常搜索到wifi:

//开启wifi
WifiUtils.withContext(getApplicationContext()).enableWifi();        
//搜索wifi
WifiUtils.withContext(getApplicationContext()).scanWifi(this::getScanResults).start();

处理搜索结果:

private void getScanResults(@NonNull final List<ScanResult> results)
{
    if (results.isEmpty())
    {
        Log.i(TAG, "SCAN RESULTS IT'S EMPTY");
        return;
    }
    Log.i(TAG, "GOT SCAN RESULTS " + results);
}

若不为空,则连接指定wifi:

//连接wifi
WifiUtils.withContext(getApplicationContext())
  .connectWith("wifi SSID", "password")
  .setTimeout(40000)
  .onConnectionResult(new ConnectionSuccessListener() {
      @Override
      public void success() {
          Toast.makeText(MainActivity.this, "SUCCESS!", Toast.LENGTH_SHORT).show();
      }

      @Override
      public void failed(@NonNull ConnectionErrorCode errorCode) {
          Toast.makeText(MainActivity.this, "EPIC FAIL!" + errorCode.toString(), Toast.LENGTH_SHORT).show();
      }
  })
  .start();

 3. API >= 29

API大于29时,弃用了WifiConfiguration这个更加底层可以直接操作的类。但是初始化和搜索wifi列表的代码与API<29的a和b部分代码相同,只是连接wifi的部分做了修改,调用下面代码时,将会出现一个页面显示要连接的wifi,用户点击连接之后再返回app:

WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
  .setSsid("wifi SSID")
  .setWpa2Passphrase("password")
  .build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
  .setNetworkSpecifier(wifiNetworkSpecifier)
  .build();
ConnectivityManager connectivityManager = (ConnectivityManager)this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.requestNetwork(networkRequest, new ConnectivityManager.NetworkCallback());

将下面代码替换上面最后一句来重写回调函数,以获取更详细的信息:

networkCallback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(@NonNull Network network) {
      super.onAvailable(network);
      Log.i("ConnectWifi", "onAvailable 切换到指定wifi成功"+network);
      connectivityManager.bindProcessToNetwork(network);
      connectivityManager.getNetworkInfo(network);
      NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
      boolean connected = networkInfo.isConnected();
      boolean available = networkInfo.isAvailable();
      NetworkInfo.DetailedState detailedState = networkInfo.getDetailedState();
      Log.i("ConnectWifi", "onAvailable connected= "+connected);
      Log.i("ConnectWifi", "onAvailable available= "+available);
      Log.i("ConnectWifi", "onAvailable detailedState= "+detailedState);
  }

  @Override
  public void onUnavailable() {
      super.onUnavailable();
      Log.i("ConnectWifi", "onUnavailable 切换到指定wifi失败");
      connectivityManager.unregisterNetworkCallback(networkCallback);
  }
};
connectivityManager.requestNetwork(networkRequest, networkCallback);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值