AndroidでWIFI接続が確立されたことを検出するにはどうすればよいですか?


140

WIFI経由のネットワーク接続があることを検出する必要があります。有効なネットワーク接続が確立されたことを確立するために送信されるブロードキャスト。HTTPの有効なネットワーク接続が存在することを確認する必要があります。有効な接続が存在することを確認するために何をリッスンし、どの追加テストを行う必要がありますか。


この質問の一部はここに答えた私が発見されている:stackoverflow.com/questions/4238921/...
Androiderを

1
しかし、これらの条件をチェックするときの問題はまだありますか?
Androider、

1
放送受信機で捕まる可能性のある放送が発生するかどうかについてフィードバックをお願いします。
Androider、

1
android.net.wifi.STATE_CHANGEのような暗黙のブロードキャストレシーバーがマニフェストに登録できなくなったため、Android Oでこれを行うにはどうすればよいですか(developer.android.com/guide/components/…を参照)。アプリケーションアクティビティ(onCreateなど)で登録すると、onStop()で登録解除する必要があり、wifi関連のイベントを受信しなくなります
zafar142003

回答:


126

BroadcastReceiverWiFi接続が確立された場合(または接続が変更された場合)に通知を受け取るように登録できます。

登録BroadcastReceiver

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
registerReceiver(broadcastReceiver, intentFilter);

そして、あなたの中BroadcastReceiverで次のようなことをしてください:

@Override
public void onReceive(Context context, Intent intent) {
    final String action = intent.getAction();
    if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
        if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
            //do stuff
        } else {
            // wifi connection was lost
        }
    }
}

詳細については、BroadcastReceiverおよびのドキュメントを参照してくださいWifiManager

もちろん、この前にデバイスがすでにWiFiに接続されているかどうかを確認する必要があります。

編集:ban-geoengineeringのおかげで、デバイスがすでに接続されているかどうかを確認する方法は次のとおりです:

private boolean isConnectedViaWifi() {
     ConnectivityManager connectivityManager = (ConnectivityManager) appObj.getSystemService(Context.CONNECTIVITY_SERVICE);
     NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);     
     return mWifi.isConnected();
}

1
なぜSUPPLICANT_CONECTION_CHANGE_ACTIONなのですか?JUST CONNECTION_CHANGE放送の変更だと思いました。なぜサプライヤーですか??? 感謝
Androider

2
え?connection_changeというアクションが表示されません...?wifiの状態の変化のみが表示されますが、そのアクションは、wifiが接続されているかどうかではなく、有効化されているかどうか(または無効化/無効化)を示しているだけです...
jpm 2011

9
私にとってWifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTIONは、既知のwifiステーションへの接続が確立または失われた場合に機能しません。ただし、WifiManager.NETWORK_STATE_CHANGED_ACTIONは機能します。
Yar

1
「android.net.wifi.STATE_CHANGE」がうまくいきました。以下の私の答えを確認してください
M. Usman Khan

1
「もちろん、この前に、デバイスがすでにWiFiに接続されているかどうかを確認してください。」-したがって、初期のWi-Fi状態を取得するには、この方法を使用できます...private boolean isConnectedViaWifi() { ConnectivityManager connectivityManager = (ConnectivityManager) appObj.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); return mWifi.isConnected(); }
ban-geoengineering '

106

私のために働いた最高のもの:

AndroidManifest

<receiver android:name="com.AEDesign.communication.WifiReceiver" >
   <intent-filter android:priority="100">
      <action android:name="android.net.wifi.STATE_CHANGE" />
   </intent-filter>
</receiver>

BroadcastReceiverクラス

public class WifiReceiver extends BroadcastReceiver {

   @Override
   public void onReceive(Context context, Intent intent) {

      NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
      if(info != null && info.isConnected()) {
        // Do your work. 

        // e.g. To check the Network Name or other info:
        WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        String ssid = wifiInfo.getSSID();
      }
   }
}

許可

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

1
これは特にwifi状態の変更に最適な答えだと思います。おかげで
ミケル2014

4
後で簡単に参照できるように、ハードコードされたアクションはWifiManager.NETWORK_STATE_CHANGED_ACTIONです。
Anonsage 2014年

3
if(info!= null && info.isConnected())=スパゲッティなし。
gswierczynski 2015

1
メインアクティビティでブロードキャストを送信するためにコードを記述する必要がありますか?
Nisari Balakrishnan

1
android.net.wifi.STATE_CHANGEのような暗黙のブロードキャストレシーバーがマニフェストに登録できなくなったため、Android Oでこれを行うにはどうすればよいですか(developer.android.com/guide/components/…を参照)。アプリケーションアクティビティ(onCreateなど)に登録すると、onStop()で登録を解除する必要があり、WiFi関連のイベントを受信しなくなります。
zafar142003

18

私にとってはWifiManager.NETWORK_STATE_CHANGED_ACTION機能します。

放送受信機を登録します。

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(broadcastReceiver, intentFilter);

そして受け取る:

@Override
public void onReceive(Context context, Intent intent) {

    final String action = intent.getAction();

    if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
        NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        boolean connected = info.isConnected();

        //call your method
    }      
}

1
私にとってもWifiManager.NETWORK_STATE_CHANGED_ACTIONのみが機能しましたが、これだけが機能する理由の説明はありますか?
ベンチク2015年

11

ユーザー@JPMと@usmanによる回答は非常に便利です。それは正常に動作しますが、私の場合、それonReceiveは私の場合には4回複数回来るので、私のコードは複数回実行されます。

私はいくつかの変更を行い、私の要件に従って作成しましたが、今では1回しかありません

これがBroadcastのJavaクラスです。

public class WifiReceiver extends BroadcastReceiver {

String TAG = getClass().getSimpleName();
private Context mContext;

@Override
public void onReceive(Context context, Intent intent) {

    mContext = context;


    if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {

        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI &&
                networkInfo.isConnected()) {
            // Wifi is connected
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            String ssid = wifiInfo.getSSID();

            Log.e(TAG, " -- Wifi connected --- " + " SSID " + ssid );

        }
    }
    else if (intent.getAction().equalsIgnoreCase(WifiManager.WIFI_STATE_CHANGED_ACTION))
    {
        int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
        if (wifiState == WifiManager.WIFI_STATE_DISABLED)
        {
            Log.e(TAG, " ----- Wifi  Disconnected ----- ");
        }

    }
}
}

AndroidManifest内

<receiver android:name=".util.WifiReceiver" android:enabled="true">
        <intent-filter>
            <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
        </intent-filter>
    </receiver>


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

1
wifiStateとは
2016

1
また、wifiStateとは何か、それがどのように生成されたかを知りたい
Evan Parsons

1
@behelitの「wifiState」が編集された回答に表示されます。
Yog Guru、2016

8

あなたはできますが、ユーザーを毎回尋ねるの正常な動作をオーバーライドする選択肢を与える場合は無線LAN接続を開始します。

私は3つの方法を使用することを選択します...

public boolean isOnline() 
{
 ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
 NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
 return (networkInfo != null && networkInfo.isConnected());
}  

これは、WifiまたはCellDataのいずれかにインターネット接続があるかどうかをすばやく確認するためのものです。ここから、実行するアクションを選択できます。機内モードかどうかも確認する必要があります。

別のスレッド。変数IpAddressを= ""に設定し、有効なIPアドレスが得られるまでポーリングします。

  WifiManager wifi;
  wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
  WifiInfo wifiInfo = wifi.getConnectionInfo();
  int ipAddress = wifiInfo.getIpAddress();
  String ip = null;
  ip = String.format("%d.%d.%d.%d",
  (ipAddress & 0xff),
  (ipAddress >> 8 & 0xff),
  (ipAddress >> 16 & 0xff),
  (ipAddress >> 24 & 0xff));
  Log.e(" >>IP number Begin ",ip);

別のコードスニペット...オンになっていない場合はオンにします(ユーザーの事前の許可を得て)

   if(wifi.isWifiEnabled()!=true)wifi.setWifiEnabled(true);  

7

WIFI接続状態を検出するために、ConnectivityManagerクラスのCONNECTIVITY_ACTIONを使用しました。

    IntentFilter filter=new IntentFilter();
    filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    registerReceiver(receiver, filter);

BroadCastReceiverから:

    if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
        int networkType = intent.getIntExtra(
                android.net.ConnectivityManager.EXTRA_NETWORK_TYPE, -1);
        if (ConnectivityManager.TYPE_WIFI == networkType) {
            NetworkInfo networkInfo = (NetworkInfo) intent
                    .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            if (networkInfo != null) {
                if (networkInfo.isConnected()) {

                    // TODO: wifi is connected
                } else {
                    // TODO: wifi is not connected
                }
            }
        }

    }

ps:私にとってはうまくいきます:)


1
fyi、Android 6では、有効なセルデータ接続がある場合、wifi状態の変更はCONNECTIVITY_ACTIONをトリガーしません。彼らがした唯一の理由は、接続状態が影響を受けていたということですが、今はそうではありません。
Bruce

5

このコードはまったく許可を必要としません。Wi-Fiネットワーク接続状態の変更のみに制限されます(他のネットワークは考慮されません)。受信機は、静的にAndroidManifest.xmlファイルに公開され、それがシステムによって呼び出されるようにエクスポートする必要はありませんprotected broadcastNETWORK_STATE_CHANGED_ACTIONすべてのネットワーク接続状態の変更で、。

AndroidManifest:

<receiver
    android:name=".WifiReceiver"
    android:enabled="true"
    android:exported="false">

    <intent-filter>
        <!--protected-broadcast: Special broadcast that only the system can send-->
        <!--Corresponds to: android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION-->
        <action android:name="android.net.wifi.STATE_CHANGE" />
    </intent-filter>

</receiver>

BroadcastReceiverクラス:

public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
/*
 Tested (I didn't test with the WPS "Wi-Fi Protected Setup" standard):
 In API15 (ICE_CREAM_SANDWICH) this method is called when the new Wi-Fi network state is:
 DISCONNECTED, OBTAINING_IPADDR, CONNECTED or SCANNING

 In API19 (KITKAT) this method is called when the new Wi-Fi network state is:
 DISCONNECTED (twice), OBTAINING_IPADDR, VERIFYING_POOR_LINK, CAPTIVE_PORTAL_CHECK
 or CONNECTED

 (Those states can be obtained as NetworkInfo.DetailedState objects by calling
 the NetworkInfo object method: "networkInfo.getDetailedState()")
*/
    /*
     * NetworkInfo object associated with the Wi-Fi network.
     * It won't be null when "android.net.wifi.STATE_CHANGE" action intent arrives.
     */
    NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

    if (networkInfo != null && networkInfo.isConnected()) {
        // TODO: Place the work here, like retrieving the access point's SSID

        /*
         * WifiInfo object giving information about the access point we are connected to.
         * It shouldn't be null when the new Wi-Fi network state is CONNECTED, but it got
         * null sometimes when connecting to a "virtualized Wi-Fi router" in API15.
         */
        WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
        String ssid = wifiInfo.getSSID();
    }
}
}

権限:

None

1
<API 26を実行しているデバイスで動作します。@ Ishamが提案したように、アクションはAndroid Oではサポートされなくなりました
tiagocarvalho92 '14

3

これは、Wifiに接続したときに通信のみを許可するというユーザー設定を考慮した私のコードの例です。

私はIntentServiceものをダウンロードしようとする前に内部からこのコードを呼び出しています。

NetworkInfoだろうnullいかなる種類のネットワーク接続が存在しない場合。

private boolean canConnect()
{
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    boolean canConnect = false;
    boolean wifiOnly = SharedPreferencesUtils.wifiOnly();

    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if(networkInfo != null)
    {
        if(networkInfo.isConnected())
        {
            if((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) ||
               (networkInfo.getType() != ConnectivityManager.TYPE_WIFI && !wifiOnly))
            {
                canConnect = true;
            }
        }
    }

    return canConnect;
}

3

Android Oは、wifiの状態変更の暗黙的なブロードキャストを受信する可能性を削除しました。そのため、アプリが閉じていると、それらを受け取ることができません。新しいものWorkManagerは、アプリが閉じられたときに実行する機能を備えているため、少し試してみたところ、非常にうまく機能しているようです。

これを依存関係に追加します。

implementation "android.arch.work:work-runtime:1.0.0-alpha08"

WifiConnectWorker.kt

class WifiConnectWorker : Worker() {

    override fun doWork(): Result {
        Log.i(TAG, "I think we connected to a wifi")
        return Result.SUCCESS
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        val workManager = WorkManager.getInstance()

        // Add constraint to start the worker when connecting to WiFi
        val request = OneTimeWorkRequest.Builder(WifiConnectWorker::class.java)
            .setConstraints(Constraints.Builder()
                .setRequiredNetworkType(UNMETERED)
                .build())
            .build()

        // The worker should be started, even if your app is closed
        workManager.beginUniqueWork("watch_wifi", REPLACE, request).enqueue()
    }
}

これは1回限りの通知の簡単なテストでした。WiFiがオン/オフになったときに常に通知を受け取るには、さらに多くの作業が必要です。

PS:アプリが強制終了されると、ワーカーは起動せずWorkManager、リクエストをキャンセルしているようです。


アプリが強制状態の場合でもワーカーを起動する方法はありますか?ワークマネージャーは、アプリが開いている場合にのみ.setRequiredNetworkType(UNMETERED)を使用します。アプリが強制終了(強制的に閉じた状態)であってもワーカーをトリガーする方法はありますか?暗黙のブロードキャストレシーバーもある程度制限されているためです。最良の代替案は何ですか?
Suresh、

2

私はこのコードを使用しました:

public class MainActivity extends Activity
    {
    .
    .
    .
    @Override
    protected void onCreate(Bundle savedInstanceState)
        {
        super.onCreate(savedInstanceState);
        .
        .
        .
        }

    @Override
    protected void onResume()
        {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        registerReceiver(broadcastReceiver, intentFilter);  
        }

    @Override
    protected void onPause()
        {
        super.onPause();
        unregisterReceiver(broadcastReceiver);
        }

    private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
        {
        @Override
        public void onReceive(Context context, Intent intent)
            {
            final String action = intent.getAction();
            if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION))
                {
                if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false))
                    {
                    // wifi is enabled
                    }
                else
                    {
                    // wifi is disabled
                    }
                }
            }
        };
    }

2

アプリケーションコンテキストを受信するWIFI接続を検出するには、2つの方法があります。

1)私の古い方法

public boolean isConnectedWifi1(Context context) {
    try {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();           
        if (networkInfo != null) {
            NetworkInfo[] netInfo = connectivityManager.getAllNetworkInfo();
            for (NetworkInfo ni : netInfo) {
                if ((ni.getTypeName().equalsIgnoreCase("WIFI"))
                        && ni.isConnected()) {
                    return true;
                }                   
            }
        }
        return false;
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
    }
    return false;
}

2)新しい方法(現在この方法を使用しています):

public boolean isConnectedWifi(Context context) {
         ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
         NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);     
         return networkInfo.isConnected();
}

android.net.wifi.STATE_CHANGEのような暗黙のブロードキャストレシーバーがマニフェストに登録できなくなったため、Android Oでこれを行うにはどうすればよいですか(developer.android.com/guide/components/…を参照)。アプリケーションアクティビティ(onCreateなど)で登録すると、onStop()で登録解除する必要があり、wifi関連のイベントを受信しなくなります
zafar142003


2

1)CONNECTIVITY_ACTION / CONNECTIVITY_CHANGEがAPI 28で廃止され、推奨されていないことを知っていても、ブロードキャストレシーバーアプローチを試しました。また、明示的なレジスタの使用にバインドされており、アプリが実行されている限り待機します。

2)Firebase Dispatcherも試しましたが、機能しますが、アプリが強制終了されません。

3)推奨される方法として、WorkManagerが見つかり、プロセスが強制終了され、内部でregisterNetworkRequest()を使用して実行されることが保証されます。

#3アプローチを支持する最大の証拠は、Androidドキュメント自体によって参照されます。特にバックグラウンドのアプリの場合。

また、ここでは

Android 7.0では、一般的に使用される3つの暗黙的なブロードキャスト(CONNECTIVITY_ACTION、ACTION_NEW_PICTURE、ACTION_NEW_VIDEO)を削除しています。これらは、複数のアプリのバックグラウンドプロセスを一度に起動し、メモリとバッテリーに負担をかける可能性があるためです。アプリがこれらを受信して​​いる場合は、Android 7.0を利用して、代わりにJobSchedulerおよび関連するAPIに移行してください。

これまでのところ、Periodic WorkManagerリクエストを使用すると問題なく動作します。

更新:私はそれについて2シリーズのミディアムポストを書いてしまいました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.