Skip to content

Commit a38d451

Browse files
committed
✨ 네트워크 연결 상태 가져오는 네트워크 콜백 구현
1 parent 4ec59f0 commit a38d451

File tree

3 files changed

+84
-15
lines changed

3 files changed

+84
-15
lines changed

presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartFragment.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,15 @@ internal class RunningStartFragment :
6565
observeState()
6666
}
6767

68+
override fun onDestroyView() {
69+
viewModel.finishObservingNetworkState()
70+
super.onDestroyView()
71+
}
72+
6873
private fun initViews() {
6974
binding.vm = viewModel
75+
binding.executePendingBindings()
76+
7077
if ((viewModel.runningDataManager.runningState.value is RunningState.NotRunning).not()) {
7178
runningActivityLauncher.launch(
7279
Intent(
@@ -78,6 +85,7 @@ internal class RunningStartFragment :
7885
}
7986

8087
private fun observeState() {
88+
viewModel.startObservingNetworkState()
8189
viewLifecycleOwner.repeatWhenUiStarted {
8290
viewModel.runnerCount.collect { runnerCount ->
8391
binding.tvRunnerCountNumber.text = runnerCount.toString()

presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartViewModel.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,34 @@ import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
55
import com.whyranoid.domain.usecase.GetRunnerCountUseCase
66
import com.whyranoid.presentation.util.networkconnection.NetworkConnectionStateHolder
7+
import com.whyranoid.presentation.util.networkconnection.NetworkState
78
import com.whyranoid.runningdata.RunningDataManager
89
import dagger.hilt.android.lifecycle.HiltViewModel
10+
import kotlinx.coroutines.FlowPreview
911
import kotlinx.coroutines.flow.MutableSharedFlow
12+
import kotlinx.coroutines.flow.SharingStarted
1013
import kotlinx.coroutines.flow.asSharedFlow
14+
import kotlinx.coroutines.flow.debounce
15+
import kotlinx.coroutines.flow.stateIn
1116
import kotlinx.coroutines.launch
1217
import javax.inject.Inject
1318

1419
@HiltViewModel
1520
class RunningStartViewModel @Inject constructor(
1621
getRunnerCountUseCase: GetRunnerCountUseCase,
17-
networkConnectionStateHolder: NetworkConnectionStateHolder
22+
private val networkConnectionStateHolder: NetworkConnectionStateHolder
1823
) : ViewModel() {
1924

2025
val runningDataManager = RunningDataManager.getInstance()
2126

22-
val networkState = networkConnectionStateHolder.networkState
27+
@OptIn(FlowPreview::class)
28+
val networkState = networkConnectionStateHolder.networkConnectionState
29+
.debounce(500)
30+
.stateIn(
31+
scope = viewModelScope,
32+
started = SharingStarted.WhileSubscribed(5000),
33+
initialValue = NetworkState.UnInitialized
34+
)
2335

2436
val runnerCount = getRunnerCountUseCase()
2537

@@ -37,4 +49,12 @@ class RunningStartViewModel @Inject constructor(
3749
_eventFlow.emit(event)
3850
}
3951
}
52+
53+
fun startObservingNetworkState() {
54+
networkConnectionStateHolder.startObservingState()
55+
}
56+
57+
fun finishObservingNetworkState() {
58+
networkConnectionStateHolder.finishObservingState()
59+
}
4060
}

presentation/src/main/java/com/whyranoid/presentation/util/networkconnection/NetworkConnectionStateHolder.kt

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,68 @@ import android.content.Context
55
import android.content.Intent
66
import android.content.IntentFilter
77
import android.net.ConnectivityManager
8+
import android.net.ConnectivityManager.NetworkCallback
9+
import android.net.Network
10+
import android.net.NetworkCapabilities
11+
import android.os.Build
812
import kotlinx.coroutines.flow.MutableStateFlow
913
import kotlinx.coroutines.flow.StateFlow
10-
import kotlinx.coroutines.flow.asStateFlow
1114

12-
class NetworkConnectionStateHolder(context: Context) {
15+
class NetworkConnectionStateHolder(private val context: Context) {
1316

14-
private val _networkState = MutableStateFlow<NetworkState>(NetworkState.UnInitialized)
15-
val networkState: StateFlow<NetworkState> get() = _networkState.asStateFlow()
17+
private val _networkConnectionState = MutableStateFlow<NetworkState>(NetworkState.UnInitialized)
18+
val networkConnectionState: StateFlow<NetworkState> = _networkConnectionState
1619

17-
private val networkReceiver = object : BroadcastReceiver() {
18-
override fun onReceive(context: Context, intent: Intent) {
19-
_networkState.value =
20-
if (context.isConnected) NetworkState.Connection else NetworkState.DisConnection
20+
private val connectivityManager =
21+
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
22+
private val connectivityCallback = object : NetworkCallback() {
23+
override fun onAvailable(network: Network) {
24+
emitNetworkConnectionState(NetworkState.Connection)
25+
}
26+
27+
override fun onLost(network: Network) {
28+
emitNetworkConnectionState(NetworkState.DisConnection)
29+
}
30+
}
31+
private val connectivityReceiver = object : BroadcastReceiver() {
32+
override fun onReceive(context: Context?, intent: Intent?) {
33+
if (context != null && context.isConnected) {
34+
emitNetworkConnectionState(NetworkState.Connection)
35+
} else {
36+
emitNetworkConnectionState(NetworkState.DisConnection)
37+
}
38+
}
39+
}
40+
41+
fun startObservingState() {
42+
val networkCapabilities =
43+
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
44+
if (networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true) {
45+
emitNetworkConnectionState(NetworkState.Connection)
46+
} else {
47+
emitNetworkConnectionState(NetworkState.DisConnection)
48+
}
49+
50+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
51+
connectivityManager.registerDefaultNetworkCallback(connectivityCallback)
52+
} else {
53+
context.registerReceiver(
54+
connectivityReceiver,
55+
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
56+
)
57+
}
58+
}
59+
60+
fun finishObservingState() {
61+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
62+
connectivityManager.unregisterNetworkCallback(connectivityCallback)
63+
} else {
64+
context.unregisterReceiver(connectivityReceiver)
2165
}
2266
}
2367

24-
init {
25-
context.registerReceiver(
26-
networkReceiver,
27-
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
28-
)
68+
private fun emitNetworkConnectionState(currentState: NetworkState) {
69+
_networkConnectionState.value = currentState
2970
}
3071
}
3172

0 commit comments

Comments
 (0)