普段、M5StackをWi-Fiルーター(アクセスポイント)として実験を行っています。毎回設定画面からWi-Fiを切り替えるのは手間なので、アプリ内から指定のSSIDへ自動接続する機能を実装しました。
必要なパーミッション
Android 10以降でWi-Fi接続を制御するには、位置情報の権限が必要です。AndroidManifest.xmlに以下を追記します。
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
Wi-Fi接続の実装
Android 10 (API 29) から導入された WifiNetworkSpecifier を使用します。これにより、OSのWi-Fi設定を汚さずに、アプリが動作している間だけ特定のWi-Fiを利用することが可能です。
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
@RequiresApi(api = Build.VERSION_CODES.Q)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
connectToWifi("yourSSID", "yourPassword");
}
}
private void connectToWifi(String ssid, String password) {
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifier)
.build();
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.requestNetwork(networkRequest, new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(android.net.Network network) {
super.onAvailable(network);
connectivityManager.bindProcessToNetwork(network);
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Connected to " + ssid, Toast.LENGTH_SHORT).show());
}
@Override
public void onUnavailable() {
super.onUnavailable();
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Failed to connect to " + ssid, Toast.LENGTH_SHORT).show());
}
});
}
}
このコードでは、WifiNetworkSpecifierを使用してWiFiネットワークに接続し、ConnectivityManagerを使用して接続を管理します。onAvailableメソッドとonUnavailableメソッドをオーバーライドして、接続が成功したかどうかを確認できます。
実装のポイント
WifiNetworkSpecifier: SSIDとパスワードを指定して「このネットワークを使いたい」というリクエストを作成します。requestNetwork: 実行すると、OS標準の接続確認ダイアログが表示されます。ユーザーが許可すると接続が開始されます。bindProcessToNetwork: ここが重要です。 これを行うことで、アプリ内のHTTPリクエストなどが強制的にこのWi-Fiを経由するようになります。




コメント