티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
Broadcast receiver for checking internet connection in android app
Android 앱에서 인터넷 연결을 확인하기 위한 브로드캐스트 리시버
문제 내용
I am developing an android broadcast receiver for checking internet connection.
저는 인터넷 연결을 확인하기 위한 안드로이드 브로드캐스트 리시버를 개발하고 있습니다.
The problem is that my broadcast receiver is being called two times. I want it to get called only when the network is available. If it is unavailable, I don't want notified.
문제는 내 브로드캐스트 리시버가 두 번 호출되고 있다는 것입니다. 저는 그것이 네트워크가 가능할 때만 호출되기를 원합니다. 만약 그것이 불가능하다면, 저는 알림을 원하지 않습니다.
This is the broadcast receiver
이것은 브로드캐스트 리시버입니다.
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable() || mobile.isAvailable()) {
// Do something
Log.d("Network Available ", "Flag No 1");
}
}
}
This is the manifest.xml
이것은 manifest.xml입니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastreceiverforinternetconnection"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
</application>
</manifest>
높은 점수를 받은 Solution
Answer to your first question: Your broadcast receiver is being called two times because
첫 번째 질문에 대한 답변: 당신의 브로드캐스트 리시버는 두 번 호출됩니다. 왜냐하면
You have added two <intent-filter>
두 개의 인텐트 필터를 추가했습니다.
- Change in network connection :
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
- Change in WiFi state:
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
1. 네트워크 연결 변경:
2. WiFi 상태 변경:
Just use one:<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
.
하나만 사용: .
It will respond to only one action instead of two. See here for more information.
두 개가 아닌 하나의 액션에만 응답합니다. 자세한 내용은 여기를 참조하십시오.
Answer to your second question (you want receiver to call only one time if internet connection available):
두 번째 질문에 대한 대답(인터넷 연결이 가능한 경우 리시버가 한 번만 알림 받기를 원할 경우):
Your code is perfect; you notify only when internet is available.
당신의 코드는 완벽합니다. 인터넷을 사용할 수 있는 경우에만 알림을 보냅니다.
UPDATE
수정
You can use this method to check your connectivity if you want just to check whether mobile is connected with the internet or not.
모바일이 인터넷에 연결되어 있는지 여부만 확인하려면 이 방법을 사용하여 연결 상태를 확인할 수 있습니다.
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
}
가장 최근 달린 Solution
Warning: Declaring a broadcastreceiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general, apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager.
경고: android.net.conn에 대한 브로드캐스트 리시버를 선언하는 중입니다. N 이상을 대상으로 하는 앱에서는 CONNECTIVE_CHANGE가 더 이상 사용되지 않습니다. 일반적으로 앱은 이 브로드캐스트에 의존하지 말고 작업 스케줄러 또는 GCM 네트워크 관리자를 사용해야 합니다.
As CONNECTIVITY_CHANGE
is deprecated then we should use another way of doing the same stuff
CONNECTIVITY_CHANGE가 더 이상 사용되지 않으므로 동일한 작업을 수행하는 다른 방법을 사용해야 합니다.
Following NetworkConnectionLiveData
will handle all the OS Version till now and also if target SDK is less than Build.VERSION_CODES.LOLLIPOP
then only we can use broadcastReceiver
다음 NetworkConnectionLiveData는 지금까지의 모든 OS 버전을 처리하며 대상 SDK가 Build.VERSION_CODES.LOLLIPOP 미만인 경우에만 broadcastReceiver를 사용할 수 있습니다
Best Part is this class uses LiveData
so no need to register any receiver use LiveData
and it will handle all the things
가장 좋은 점은 이 클래스가 LiveData를 사용하므로 리시버를 등록할 필요가 없으며 모든 것을 처리한다는 것입니다.
class NetworkConnectionLiveData(val context: Context) : LiveData<Boolean>() {
private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback
override fun onActive() {
super.onActive()
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityManagerCallback())
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest()
else -> {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"))
}
}
}
}
override fun onInactive() {
super.onInactive()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
} else {
context.unregisterReceiver(networkReceiver)
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun lollipopNetworkAvailableRequest() {
val builder = NetworkRequest.Builder()
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI)
connectivityManager.registerNetworkCallback(builder.build(), getConnectivityManagerCallback())
}
private fun getConnectivityManagerCallback(): ConnectivityManager.NetworkCallback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network?) {
postValue(true)
}
override fun onLost(network: Network?) {
postValue(false)
}
}
return connectivityManagerCallback
} else {
throw IllegalAccessError("Should not happened")
}
}
private val networkReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
updateConnection()
}
}
private fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
postValue(activeNetwork?.isConnected == true)
}
}
Use of the LiveData into any class:
모든 클래스에 LiveData 사용:
NetworkConnectionLiveData(context ?: return)
.observe(viewLifecycleOwner, Observer { isConnected ->
if (!isConnected) {
// Internet Not Available
return@Observer
}
// Internet Available
})
출처 : https://stackoverflow.com/questions/15698790/broadcast-receiver-for-checking-internet-connection-in-android-app
'개발 > 안드로이드' 카테고리의 다른 글
WebView에 핀치 줌 ON/OFF 하기 (0) | 2022.12.12 |
---|---|
'android.view.InflateException Error inflating class android.webkit.WebView' 오류 수정하기 (0) | 2022.12.12 |
안드로이드에서 ImageView에 tint(색조)를 프로그래밍 방식으로 설정하기 (0) | 2022.12.11 |
findViewByID가 null을 반환할 때 고려해 볼 점 (0) | 2022.12.11 |
텍스트뷰 내부의 하이퍼링크 클릭 이벤트 받기 (0) | 2022.12.11 |