Androidアプリ開発

Wi-Fiデバイスにネットワーク接続する

この記事は約19分で読めます。
記事内に広告が含まれています。
スポンサーリンク

この記事はAndroidスマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Javaの開発経験、XML構文規則、Androidのアプリ開発経験がある方を対象としています。
Androidのアプリ開発でお役にたててれば、嬉しいです。
(これからAndroidのアプリ開発やJavaでの開発を始めたい方への案内は、
記事の最後で紹介します)

この記事のテーマ


GoProやInsta360などのWi-Fiデバイスにネットワーク接続する

ポイント

GoProやInsta360などのWi-Fiデバイスに接続する場合、システムサービスのWifiManagerConnectivityManagerを使用してネットワーク接続します。

WifiManager

ConnectivityManager

Wi-Fiデバイスにネットワーク接続

Wi-Fiネットワークに接続する場合、ネットワーク接続の権限(ACCESS_NETWORK_STATE, CHANGE_NETWORK_STATE, INTERNET)、Wi-Fi接続の権限(ACCESS_WIFI_STATECHANGE_WIFI_STATE)が必要です。
また、Wi-Fi接続では付近にあるデバイスを操作するために位置情報の権限(ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION)です。
位置情報を取得する権限については、AndroidManifest.xmlへの追加とは別にユーザー承認のリクエストが必要です。

AndroidManifest.xml

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    :

ユーザー承認のリクエストの実装はコチラです↓↓↓

Wi-Fiネットワークへの接続はWifiManagerConnectivityManagerを使用します。
WifiManagerConnectivityManagergetSystemServiceを使用して取得します。
現在のネットワーク接続をNetworkRequestで取得(Android12以降と前で違う)します。
ネットワーク接続の取得後、Wi-Fiネットワークに接続します。
ネットワーク接続が取得できない場合はタイムアウトを設けて、Wi-Fiネットワークに接続します。

    private WifiManager         wifiManager;
    private ConnectivityManager connectivityManager;
    private ConnectivityManager.NetworkCallback
                                networkCallback;
    private Handler             handler = new Handler(Looper.getMainLooper());
    private Runnable            runnable;
    private String              wifi;
    public String               SSID; // SSID
    public String               PASS; // パスワード
    :

    wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest networkRequest = new NetworkRequest.Builder()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .build();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        networkCallback = new ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
            @Override
            public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities capabilities) {
                super.onCapabilitiesChanged(network, capabilities);
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    WifiInfo info = (WifiInfo) capabilities.getTransportInfo();
                    wifi = info != null ? info.getSSID() : wifiManager.getConnectionInfo().getSSID();
                }
                // Wi-Fi接続
                connectSystemWifi(SSID, PASS);
            }
        };
    } else {
        networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(@NonNull Network network) {
                super.onAvailable(network);
                NetworkCapabilities capabilities = connManager.getNetworkCapabilities(network);
                if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    WifiInfo info = (WifiInfo) capabilities.getTransportInfo();
                    wifi = info != null ? info.getSSID() : wifiManager.getConnectionInfo().getSSID();
                }
                // Wi-Fi接続
                connectSystemWifi(SSID, PASS);
            }
        };
    }
    connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
    handler = new Handler(Looper.getMainLooper());
    runnable = () -> connectSystemWifi(SSID, PASS);
    // タイムアウト
    handler.postDelayed(runnable, 3000);
    :

Wi-Fi接続(connectSystemWifi)

Wi-Fi接続はNetworkRequestにSSIDとパスワードをセットして、ConnectivityManagerでリクエストします。
結果はコールバックのonAvailableonUnavailableonLostで取得します

    private void connectSystemWifi(String ssid, String pwd) {
        if (handler != null) handler.removeCallbacks(runnable);
        if (networkCallback != null) connectivityManager.unregisterNetworkCallback(networkCallback);
        if (wifiManager.isWifiEnabled()) {
            if (isConnected(ssid)) {
                if (bindNetwork(cameraNet(connectivityManager))) {
                   // ネットワーク接続成功
                   :
                } else {
                   // ネットワーク接続失敗
                   :
                }
            } else {
                WifiNetworkSpecifier specifier;
                specifier = new WifiNetworkSpecifier.Builder()
                        .setSsid(ssid)
                        .setWpa2Passphrase(pwd)
                        .build();
                NetworkRequest request = new NetworkRequest.Builder()
                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                        .setNetworkSpecifier(specifier)
                        .build();
                networkCallback = new ConnectivityManager.NetworkCallback() {
                    @Override
                    public void onAvailable(@NonNull Network network) {
                        super.onAvailable(network);
                        if (bindNetwork(cameraNet(connectivityManager))) {
                            // ネットワーク接続成功
                            :
                        } else {
                            //  ネットワーク接続失敗
                            :
                        }
                    }
                    @Override
                    public void onUnavailable() {
                        super.onUnavailable();
                        // ネットワークが使用できない
                        :
                    }
                    @Override
                    public void onLost(@NonNull Network network) {
                        super.onLost(network);
                        // 接続が切れた 
                        :
                    }
                };
                connectivityManager.requestNetwork(request, networkCallback, TIMEOUT);
            }
        } else {
      // Wi-Fiが使用不可
           :
        }
    }
    private boolean isConnected(String ssid) {
        String connect = ssid(wifi);
        if (connect != null && connect.startsWith("\"") && connect.endsWith("\"")) {
            connect = connect.substring(1, connect.length() - 1);
        }
        return connect != null && connect.endsWith(ssid);
    }
    private String ssid(String ssid) {
        if (ssid != null && ssid.startsWith("\"") && ssid.endsWith("\"")) {
            ssid = ssid.substring(1, ssid.length() - 1);
        }
        return ssid;
    }
    private boolean bindNetwork(Network network) {
        boolean result = false;
        if (network != null) {
            result = connectivityManager.bindProcessToNetwork(network);
        }
        return result;
    }
    private Network cameraNet(ConnectivityManager connectivityManager) {
        for (Network network : connectivityManager.getAllNetworks()) {
            NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
            if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                WifiInfo info = (WifiInfo) capabilities.getTransportInfo();
                if (info != null) {
                    String address1 = parseIpAddress(info.getIpAddress());
                    String address2 = parseIpAddress(wifiManager.getConnectionInfo().getIpAddress());
                    if (TextUtils.equals(address1, address2)) {
                        return network;
                    }
                } else {
                    return network;
                }
            }
        }
        return null;
    }
    private String parseIpAddress(int ip) {
        return  ((ip) & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + ((ip >> 24) & 0xFF);
    }

WifiInfoを使用して、ネット-ワークアドレスを取得、接続判定を行います。
Wi-Fiネットワークのセキュリティ対策でAndroid13以降でWifiInfoが取得できなくなっています。
このためWifiInfoが取得できない場合は現在接続中のWi-Fiネットワークを返却しています。

終了処理

終了処理でネットワーク接続を元の接続に戻します。
ConnectivityManagerbindProcessToNetworknullを設定すれば、ネットワーク接続が元の接続に復帰します。

    @O@Override
    public void onDestroy() {
        if (connectivityManager != null) {
            connectivityManager.bindProcessToNetwork(null);
            if (networkCallback != null) connectivityManager.unregisterNetworkCallback(networkCallback);
        }
        super.onDestroy();
    }

今回は、ここまでです。

Wi-Fiデバイスにネットワーク接続しているAndroidアプリです。

誤字脱字、意味不明でわかりづらい、
もっと詳しく知りたいなどのご意見は、
このページの最後にある
コメントか、
こちらから、お願いいたします♪

ポチッとして頂けると、
次のコンテンツを作成する励みになります♪

ブログランキング・にほんブログ村へ

これからAndroidのアプリ開発やJavaでの開発を始めたい方へ

アプリケーション開発経験がない方や、アプリケーション開発経験がある方でも、JavaやC#などのオブジェクト指向言語が初めての方は、Androidのアプリ開発ができるようになるには、かなりの時間がかかります。
オンラインスクールでの習得を、強くおススメします。

未経験者からプログラマーを目指すのに最適です。まずは無料カウンセリングから♪

ゲーム系に強いスクール、UnityやUnrealEngineを習得するのに最適です。まずは無料オンライン相談から♪

参考になったら、💛をポッチとしてね♪

スポンサーリンク
シェアする
msakiをフォローする
スポンサーリンク

コメント欄

タイトルとURLをコピーしました