개발을 하다보면 특정 어플의 목적에 따라 와이파이(Wi-Fi)의 상태를 감지해야 할 경우가 있습니다.
그것도 실시간으로 !!!
단순히 어플 시작할 때라던가, 특정 버튼을 눌렀을 때 와이파이의 상태를 체크하는 방법은 간단합니다.
01.private boolean isWifiConnected()02.{03. ConnectivityManager connMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);04. if (connMgr != null)05. {06. NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();07. if ( (networkInfo != null) && (networkInfo.isAvailable() == true) )08. {09. if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI)10. {11. if ( (networkInfo.getState() == State.CONNECTED) 12. || (networkInfo.getState() == State.CONNECTING) ) 13. {14. return true;15. }16. }17. }18. }19. 20. return false;21.}
위와 같이 특정 상태에서 와이파이의 연결 상태를 측정할 수 있습니다.
하지만, 이 방식은 위의 저 함수가 호출되었을 때만 값을 불러올 수 있다는 단점이 있습니다.
실시간으로 와이파이 상태가 바뀌는 것을 감지할 수 없다는 것이죠.
그래서, 네트워크 상태를 실시간으로 체크하기 위해서 SnowWiFiMonitor 라는 클래스를 한 번 만들어 보겠습니다.
안드로이드 운영체제로부터 상태 변화 메세지를 받기 위해서는 BroadcastReceiver를 상속 받습니다.
코드는 대략 다음과 같습니다.
001.package snowdeer.wifi.monitor;002. 003.import android.content.BroadcastReceiver;004.import android.content.Context;005.import android.content.Intent;006.import android.net.ConnectivityManager;007.import android.net.NetworkInfo;008.import android.net.wifi.WifiManager;009. 010.public class SnowWiFiMonitor extends BroadcastReceiver 011.{012. public final static int WIFI_STATE_DISABLED = 0x00;013. public final static int WIFI_STATE_DISABLING = WIFI_STATE_DISABLED + 1;014. public final static int WIFI_STATE_ENABLED = WIFI_STATE_DISABLING + 1;015. public final static int WIFI_STATE_ENABLING = WIFI_STATE_ENABLED + 1;016. public final static int WIFI_STATE_UNKNOWN = WIFI_STATE_ENABLING + 1;017. public final static int NETWORK_STATE_CONNECTED = WIFI_STATE_UNKNOWN + 1;018. public final static int NETWORK_STATE_CONNECTING = NETWORK_STATE_CONNECTED + 1;019. public final static int NETWORK_STATE_DISCONNECTED = NETWORK_STATE_CONNECTING + 1;020. public final static int NETWORK_STATE_DISCONNECTING = NETWORK_STATE_DISCONNECTED + 1;021. public final static int NETWORK_STATE_SUSPENDED = NETWORK_STATE_DISCONNECTING + 1;022. public final static int NETWORK_STATE_UNKNOWN = NETWORK_STATE_SUSPENDED + 1;023. 024. public interface OnChangeNetworkStatusListener025. {026. public void OnChanged(int status);027. }028. 029. private WifiManager m_WifiManager = null;030. private ConnectivityManager m_ConnManager = null;031. private OnChangeNetworkStatusListener m_OnChangeNetworkStatusListener = null;032. 033. public SnowWiFiMonitor(Context context) 034. {035. m_WifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);036. m_ConnManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);037. }038. 039. public void setOnChangeNetworkStatusListener(OnChangeNetworkStatusListener listener)040. {041. m_OnChangeNetworkStatusListener = listener;042. }043. 044. @Override045. public void onReceive(Context context, Intent intent)046. {047. if (m_OnChangeNetworkStatusListener == null)048. {049. return;050. }051. 052. String strAction = intent.getAction();053. 054. if (strAction.equals(WifiManager.WIFI_STATE_CHANGED_ACTION))055. {056. switch(m_WifiManager.getWifiState())057. {058. case WifiManager.WIFI_STATE_DISABLED:059. m_OnChangeNetworkStatusListener.OnChanged(WIFI_STATE_DISABLED);060. break;061. 062. case WifiManager.WIFI_STATE_DISABLING:063. m_OnChangeNetworkStatusListener.OnChanged(WIFI_STATE_DISABLING);064. break;065. 066. case WifiManager.WIFI_STATE_ENABLED:067. m_OnChangeNetworkStatusListener.OnChanged(WIFI_STATE_ENABLED);068. break;069. 070. case WifiManager.WIFI_STATE_ENABLING:071. m_OnChangeNetworkStatusListener.OnChanged(WIFI_STATE_ENABLING);072. break;073. 074. case WifiManager.WIFI_STATE_UNKNOWN:075. m_OnChangeNetworkStatusListener.OnChanged(WIFI_STATE_UNKNOWN);076. break;077. }078. }079. else if (strAction.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION))080. {081. NetworkInfo networkInfo = m_ConnManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);082. if ( (networkInfo != null) && (networkInfo.isAvailable() == true) )083. {084. if (networkInfo.getState() == NetworkInfo.State.CONNECTED)085. {086. m_OnChangeNetworkStatusListener.OnChanged(NETWORK_STATE_CONNECTED);087. }088. else if (networkInfo.getState() == NetworkInfo.State.CONNECTING)089. {090. m_OnChangeNetworkStatusListener.OnChanged(NETWORK_STATE_CONNECTING);091. }092. else if (networkInfo.getState() == NetworkInfo.State.DISCONNECTED)093. {094. m_OnChangeNetworkStatusListener.OnChanged(NETWORK_STATE_DISCONNECTED);095. }096. else if (networkInfo.getState() == NetworkInfo.State.DISCONNECTING)097. {098. m_OnChangeNetworkStatusListener.OnChanged(NETWORK_STATE_DISCONNECTING);099. }100. else if (networkInfo.getState() == NetworkInfo.State.SUSPENDED)101. {102. m_OnChangeNetworkStatusListener.OnChanged(NETWORK_STATE_SUSPENDED);103. }104. else if (networkInfo.getState() == NetworkInfo.State.UNKNOWN)105. {106. m_OnChangeNetworkStatusListener.OnChanged(NETWORK_STATE_UNKNOWN);107. }108. }109. }110. }111.}
암튼, 대충 이런 형태의 클래스를 하나 만들어놓고, 사용하면 됩니다.
메인 Activity에서 위의 클래스를 불러와서 사용하는 예제는 다음과 같습니다.
01.package snowdeer.wifi.monitor;02. 03.import android.app.Activity;04.import android.content.IntentFilter;05.import android.net.wifi.WifiManager;06.import android.os.Bundle;07.import android.util.Log;08. 09.public class ActSnowWiFiMonitor extends Activity 10.{11. private SnowWiFiMonitor m_SnowWifiMonitor = null; 12. 13. @Override14. public void onCreate(Bundle savedInstanceState) 15. {16. super.onCreate(savedInstanceState);17. setContentView(R.layout.main);18. 19. m_SnowWifiMonitor = new SnowWiFiMonitor(this);20. m_SnowWifiMonitor.setOnChangeNetworkStatusListener(SnowChangedListener);21. 22. //registerReceiver(m_SnowWifiMonitor, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));23. registerReceiver(m_SnowWifiMonitor, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));24. }25. 26. @Override27. protected void onDestroy() 28. {29. super.onDestroy();30. 31. unregisterReceiver(m_SnowWifiMonitor);32. }33. 34. SnowWiFiMonitor.OnChangeNetworkStatusListener SnowChangedListener 35. = new SnowWiFiMonitor.OnChangeNetworkStatusListener()36. {37. @Override38. public void OnChanged(int status) 39. {40. switch(status)41. {42. case SnowWiFiMonitor.WIFI_STATE_DISABLED:43. Log.i("", "[WifiMonitor] WIFI_STATE_DISABLED");44. break;45. 46. case SnowWiFiMonitor.WIFI_STATE_DISABLING:47. Log.i("", "[WifiMonitor] WIFI_STATE_DISABLING");48. break;49. 50. case SnowWiFiMonitor.WIFI_STATE_ENABLED:51. Log.i("", "[WifiMonitor] WIFI_STATE_ENABLED");52. break;53. 54. case SnowWiFiMonitor.WIFI_STATE_ENABLING:55. Log.i("", "[WifiMonitor] WIFI_STATE_ENABLING");56. break;57. 58. case SnowWiFiMonitor.WIFI_STATE_UNKNOWN:59. Log.i("", "[WifiMonitor] WIFI_STATE_UNKNOWN");60. break;61. 62. case SnowWiFiMonitor.NETWORK_STATE_CONNECTED:63. Log.i("", "[WifiMonitor] NETWORK_STATE_CONNECTED");64. break;65. 66. case SnowWiFiMonitor.NETWORK_STATE_CONNECTING:67. Log.i("", "[WifiMonitor] NETWORK_STATE_CONNECTING");68. break;69. 70. case SnowWiFiMonitor.NETWORK_STATE_DISCONNECTED:71. Log.i("", "[WifiMonitor] NETWORK_STATE_DISCONNECTED");72. break;73. 74. case SnowWiFiMonitor.NETWORK_STATE_DISCONNECTING:75. Log.i("", "[WifiMonitor] NETWORK_STATE_DISCONNECTING");76. break;77. 78. case SnowWiFiMonitor.NETWORK_STATE_SUSPENDED:79. Log.i("", "[WifiMonitor] NETWORK_STATE_SUSPENDED");80. break;81. 82. case SnowWiFiMonitor.NETWORK_STATE_UNKNOWN:83. Log.i("", "[WifiMonitor] WIFI_STATE_DISABLED");84. break;85. 86. }87. }88. };
앗!! 그리고 주의하셔야 할 점은 AndroidManifest.xml 파일에서 권한 설정을 미리 해둬야 한다는 점이겠죠?
<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.UPDATE_DEVICE_STATS"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
- 감사합니다. 도움이 되는 정말 멋진 글이네요. 그리고 질문 있는데요. interface 부분 SnowWiFiMonitor 클래스에서 implement로 상속받으면서 메소드를 구현하면 안되나요?
Messiah 2012/05/02 15:28 댓글주소 수정/삭제 댓글쓰기
NETWORK_STATE_CHANGED_ACTION 리시브 받으시려면 이 소스에서 조금 수정하셔야합니다.
WifiManger 클래스에는 wifi 상태 저 5가지만 체크할수 있습니다.
따라서 NETWORK_STATE_CHANGED_ACTION은 리시브를 제대로 받을수 없는 것이지요.
주석처리된 registerReceiver 주석푸시고. ConnectivityManager 를 이용하여 wifi 접속 이벤트 리시브가 오는 것을
onReceive() 메소드에서 처리 해주시면 됩니다. 저는 그렇게 소스 변경하여서 사용하였습니다.