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에 연결되어 있는지 확인해야합니다.

편집 : 금지 지오 엔지니어링 덕분에 장치가 이미 연결되어 있는지 확인하는 방법이 있습니다.

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라는 동작이 보이지 않습니다 ...? Wi-Fi 상태 만 변경되었지만 해당 작업은 Wi-Fi가 연결되어 있는지 여부에 관계없이 Wi-Fi가 활성화되어 있는지 (또는 활성화 / 비활성화되어 있는지) 만 나타냅니다 ...
jpm

9
나를 위해 WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION은 알려진 Wi-Fi 스테이션에 대한 연결이 설정 / 손실 된 경우 작동하지 않습니다. 그러나 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

나를 위해 일한 최고 :

안드로이드

<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 상태 chage에 대한 가장 좋은 대답이라고 생각합니다. 감사합니다
Mikel

4
나중에 쉽게 참조 할 수 있도록 하드 코드 된 조치는 WifiManager.NETWORK_STATE_CHANGED_ACTION 입니다.
Anonsage

3
if (info! = null && info.isConnected ()) = 스파게티 없음
gswierczynski

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 만 효과가 있었지만 왜 이것이 효과가 있는지에 대한 설명이 있습니까?
benchuk 2016 년

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 ----- ");
        }

    }
}
}

Android에서

<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 란 무엇입니까?
behelit

1
wifiState가 무엇이고 어떻게 생성되었는지 알고 싶습니다
Evan Parsons

1
@behelit는 이제 "wifiState"가 편집 된 답변에 있습니다.
Yog Guru

8

사용자에게 매번 묻는 일반적인 동작을 무시하도록 선택하면 Wi-Fi 연결을 시작할 수 있습니다 .

세 가지 방법을 사용하기로 결정했습니다 ...

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

인터넷에 Wi-Fi 또는 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
                }
            }
        }

    }

추신 : 저에게 잘 작동합니다 :)


1
참고로, 유효한 셀 데이터 연결이있을 때 Android 6을 사용하면 wifi 상태가 변경되면 CONNECTIVITY_ACTION이 트리거되지 않습니다. 그들이 한 유일한 이유는 연결 상태가 영향을 받았기 때문입니다.
Bruce

5

이 코드에는 권한이 전혀 필요하지 않습니다. Wi-Fi 네트워크 연결 상태 변경으로 만 제한됩니다 (다른 네트워크는 고려되지 않음). 수신자는 AndroidManifest.xml 파일에 정적으로 게시 되며 모든 네트워크 연결 상태가 변경 될 때마다 시스템 protected broadcast에서 호출되므로 내보낼 필요가 없습니다 NETWORK_STATE_CHANGED_ACTION.

안드로이드

<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는 작업이 더 이상 안드로이드 O에서 지원됩니다 제시하지
tiagocarvalho92

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()
    }
}

이는 일회성 알림에 대한 간단한 테스트 일뿐입니다. WiFi를 켜고 끌 때 항상 알림을 받으려면 더 많은 작업이 필요합니다.

추신 : 앱이 강제 종료 되면 작업자가 시작되지 않고 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 연결을 감지하는 두 가지 방법이 있습니다.

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에서는 CONNECTIVITY_ACTION, ACTION_NEW_PICTURE 및 ACTION_NEW_VIDEO와 같이 일반적으로 사용되는 3 개의 암시 적 브로드 캐스트를 제거합니다. 여러 개의 앱의 백그라운드 프로세스를 한 번에 깨우고 메모리와 배터리에 부담을 줄 수 있기 때문입니다. 앱에서이를 수신하는 경우 Android 7.0을 활용하여 대신 JobScheduler 및 관련 API로 마이그레이션하십시오.

지금까지 Periodic WorkManager 요청을 사용하면 잘 작동합니다.

업데이트 : 나는 그것에 대해 2 시리즈 매체 게시물을 작성 하게되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.