From d8890c5902aad730fd3486751b432334d0a5ca71 Mon Sep 17 00:00:00 2001 From: DoDoBest Date: Fri, 3 May 2024 15:05:13 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20MissionFragment=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/stop/ui/mission/MissionFragment.kt | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt b/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt index 28a400a..1209ff2 100644 --- a/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt +++ b/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt @@ -325,20 +325,27 @@ class MissionFragment : Fragment(), MissionHandler { lateinit var beforeLocation: Location viewLifecycleOwner.lifecycleScope.launch { missionViewModel.userLocations.collectIndexed { index, userLocation -> - if (index == 1) { + if (userLocation.isEmpty()) { + return@collectIndexed + } + val location = userLocation.last() + if (index == 0) { initMarker(userLocation) - beforeLocation = userLocation.last() - } else if (index > 1) { + beforeLocation = location + } else if (index >= 1 && userLocation.isNotEmpty()) { drawNowLocationLine( - TMapPoint(userLocation.last().latitude, userLocation.last().longitude), + TMapPoint(location.latitude, location.longitude), TMapPoint(beforeLocation.latitude, beforeLocation.longitude) ) - personCurrentLocation = userLocation.last() + personCurrentLocation = location if (tMap.isTracking) { - tMap.tMapView.setCenterPoint(userLocation.last().latitude, userLocation.last().longitude) + tMap.tMapView.setCenterPoint( + location.latitude, + location.longitude + ) } - beforeLocation = userLocation.last() - arriveDestination(userLocation.last().latitude, userLocation.last().longitude) + beforeLocation = location + arriveDestination(location.latitude, location.longitude) } } } From bdac60acc43a1c218cd0bb3bdd32af961c23c7d5 Mon Sep 17 00:00:00 2001 From: DoDoBest Date: Fri, 3 May 2024 15:07:50 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EA=B6=8C=ED=95=9C=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/stop/permission/PermissionManager.kt | 92 +++++++++++++++++++ presentation/src/main/res/values/strings.xml | 5 + 2 files changed, 97 insertions(+) create mode 100644 presentation/src/main/java/com/stop/permission/PermissionManager.kt diff --git a/presentation/src/main/java/com/stop/permission/PermissionManager.kt b/presentation/src/main/java/com/stop/permission/PermissionManager.kt new file mode 100644 index 0000000..46101e6 --- /dev/null +++ b/presentation/src/main/java/com/stop/permission/PermissionManager.kt @@ -0,0 +1,92 @@ +package com.stop.permission + +import android.Manifest +import android.content.DialogInterface +import android.content.Intent +import android.net.Uri +import android.provider.Settings +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.Fragment +import com.stop.R + +class PermissionManager(fragment: Fragment) { + + private val locationPartialPermissionDialog: AlertDialog.Builder by lazy { + val context = fragment.requireContext() + AlertDialog.Builder(context) + .setTitle(context.getString(R.string.location_permission_dialog_title)) + .setMessage(context.getString(R.string.location_partial_permission_dialog_message)) + .setNegativeButton(context.getString(R.string.deny)) { _: DialogInterface, _: Int -> + } + .setPositiveButton(context.getString(R.string.allow)) { _, _ -> + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.parse("package:" + context.packageName) + } + context.startActivity(intent) + } + } + private val locationPermissionDeniedDialog: AlertDialog.Builder by lazy { + val context = fragment.requireContext() + AlertDialog.Builder(context) + .setTitle(context.getString(R.string.location_permission_dialog_title)) + .setMessage(context.getString(R.string.location_permission_denied_dialog_message)) + .setNegativeButton(context.getString(R.string.deny)) { _: DialogInterface, _: Int -> + } + .setPositiveButton(context.getString(R.string.allow)) { _, _ -> + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.parse("package:" + context.packageName) + } + context.startActivity(intent) + } + } + + private var onGranted: () -> Unit = {} + private var isShowDialog = false + private var isOkayPartialGranted = false + + private val locationPermissionRequest = fragment.registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { permissions -> + when { + permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> { + // Precise location access granted. + onGranted() + } + + permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> { + // Only approximate location access granted. + if (isOkayPartialGranted) { + onGranted() + } + if (isShowDialog) { + locationPartialPermissionDialog.show() + } + } + + else -> { + if (isShowDialog) { + locationPermissionDeniedDialog.show() + } + } + } + } + + fun getLocationPermission( + onGranted: () -> Unit, + isOkayPartialGranted: Boolean, + isShowDialog: Boolean, + ) { + this.onGranted = onGranted + this.isOkayPartialGranted = isOkayPartialGranted + this.isShowDialog = isShowDialog + locationPermissionRequest.launch(LOCATION_PERMISSIONS) + } + + companion object { + private val LOCATION_PERMISSIONS = arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION + ) + } +} \ No newline at end of file diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index cd04a2a..1818170 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -88,4 +88,9 @@ 분 전 옵션 설정 진행중인 미션이 있습니다 + 위치 권한 안내 + 정확한 위치 탐색을 위해 정확한 위치 사용 권한이 필요합니다. + 거부 + 허용 + 위치 탐색을 위해 위치 사용 권한이 필요합니다. \ No newline at end of file From 9e41eb75e302c955d88a47d567a4c162064143f5 Mon Sep 17 00:00:00 2001 From: DoDoBest Date: Fri, 3 May 2024 16:51:05 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=EC=A7=80=EB=8F=84=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC,=20?= =?UTF-8?q?=EB=B0=B1=EA=B7=B8=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EA=B6=8C=ED=95=9C=20=EC=82=AD=EC=A0=9C,=20MissionF?= =?UTF-8?q?ragment=20=EC=9E=98=EB=AA=BB=EB=90=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- presentation/src/main/AndroidManifest.xml | 1 - .../main/java/com/stop/ui/map/MapFragment.kt | 111 +++++++------- .../com/stop/ui/mission/MissionFragment.kt | 142 ++++++++---------- .../com/stop/ui/mission/MissionHandler.kt | 11 -- .../ui/placesearch/PlaceSearchViewModel.kt | 17 ++- .../ui/routedetail/RouteDetailFragment.kt | 46 ++++-- .../stop/ui/routedetail/RouteDetailHandler.kt | 9 -- .../java/com/stop/ui/{map => tmap}/MapTMap.kt | 9 +- .../stop/ui/{mission => tmap}/MissionTMap.kt | 7 +- .../{routedetail => tmap}/RouteDetailTMap.kt | 18 ++- .../java/com/stop/ui/{util => tmap}/TMap.kt | 56 +++---- .../MapHandler.kt => tmap/TMapHandler.kt} | 7 +- .../src/main/java/com/stop/ui/util/Handler.kt | 4 - 13 files changed, 202 insertions(+), 236 deletions(-) delete mode 100644 presentation/src/main/java/com/stop/ui/mission/MissionHandler.kt delete mode 100644 presentation/src/main/java/com/stop/ui/routedetail/RouteDetailHandler.kt rename presentation/src/main/java/com/stop/ui/{map => tmap}/MapTMap.kt (92%) rename presentation/src/main/java/com/stop/ui/{mission => tmap}/MissionTMap.kt (93%) rename presentation/src/main/java/com/stop/ui/{routedetail => tmap}/RouteDetailTMap.kt (86%) rename presentation/src/main/java/com/stop/ui/{util => tmap}/TMap.kt (67%) rename presentation/src/main/java/com/stop/ui/{map/MapHandler.kt => tmap/TMapHandler.kt} (74%) delete mode 100644 presentation/src/main/java/com/stop/ui/util/Handler.kt diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index 00f5086..feca033 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -9,7 +9,6 @@ - diff --git a/presentation/src/main/java/com/stop/ui/map/MapFragment.kt b/presentation/src/main/java/com/stop/ui/map/MapFragment.kt index ac4f48f..e51a460 100644 --- a/presentation/src/main/java/com/stop/ui/map/MapFragment.kt +++ b/presentation/src/main/java/com/stop/ui/map/MapFragment.kt @@ -1,6 +1,5 @@ package com.stop.ui.map -import android.Manifest.permission import android.app.NotificationManager import android.content.BroadcastReceiver import android.content.Context @@ -11,7 +10,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.activity.result.contract.ActivityResultContracts import androidx.core.os.bundleOf import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -30,6 +28,7 @@ import com.stop.databinding.FragmentMapBinding import com.stop.model.alarm.AlarmStatus import com.stop.model.map.Location import com.stop.model.mission.MissionStatus +import com.stop.permission.PermissionManager import com.stop.ui.alarmsetting.AlarmSettingFragment import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_MAP_CODE import com.stop.ui.alarmsetting.AlarmSettingViewModel @@ -37,10 +36,12 @@ import com.stop.ui.alarmstart.SoundService import com.stop.ui.mission.MissionService import com.stop.ui.mission.MissionViewModel import com.stop.ui.placesearch.PlaceSearchViewModel +import com.stop.ui.tmap.MapTMap +import com.stop.ui.tmap.TMapHandler import com.stop.ui.util.Marker import kotlinx.coroutines.launch -class MapFragment : Fragment(), MapHandler { +class MapFragment : Fragment() { private var _binding: FragmentMapBinding? = null private val binding: FragmentMapBinding @@ -50,10 +51,49 @@ class MapFragment : Fragment(), MapHandler { private val placeSearchViewModel: PlaceSearchViewModel by activityViewModels() private val missionViewModel: MissionViewModel by viewModels() + private lateinit var permissionManager: PermissionManager + private val mapHandler = object : TMapHandler { + override fun alertTMapReady() { + requestLocationPermission() + + tMap.initListener() + initAfterTMapReady() + } + + override fun setOnLocationChangeListener(location: android.location.Location) { + placeSearchViewModel.currentLocation = Location(location.latitude, location.longitude) + } + + override fun setOnDisableScrollWIthZoomLevelListener() { + if (binding.homePanel.layoutPanel.visibility == View.VISIBLE) { + binding.homePanel.layoutPanel.visibility = View.GONE + tMap.tMapView.removeTMapMarkerItem(Marker.PLACE_MARKER) + } else { + setViewVisibility() + mapUIVisibility = mapUIVisibility.xor(View.GONE) + } + } + + override fun setPanel(tMapPoint: TMapPoint, isClickedFromPlaceSearch: Boolean) { + placeSearchViewModel.getGeoLocationInfo( + tMapPoint.latitude, + tMapPoint.longitude, + isClickedFromPlaceSearch + ) + } + } + private lateinit var missionServiceIntent: Intent private lateinit var tMap: MapTMap private var mapUIVisibility = View.GONE + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + tMap = MapTMap(requireActivity(), mapHandler) + permissionManager = PermissionManager(this) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -129,17 +169,8 @@ class MapFragment : Fragment(), MapHandler { } private fun initTMap() { - placeSearchViewModel.tMap?.let { - tMap = it - tMap.setHandler(this) - initAfterTMapReady() - } ?: run { - tMap = MapTMap(requireActivity(), this) - tMap.init() - placeSearchViewModel.tMap = tMap - } - binding.layoutContainer.addView(tMap.tMapView) + initAfterTMapReady() } private fun initBottomSheetBehavior() { @@ -224,11 +255,13 @@ class MapFragment : Fragment(), MapHandler { } } - override fun alertTMapReady() { - requestPermissionsLauncher.launch(PERMISSIONS) - - tMap.initListener() - initAfterTMapReady() + private fun requestLocationPermission(isShowDialog: Boolean = false) { + val onGranted = tMap::setTrackingMode + permissionManager.getLocationPermission( + onGranted = onGranted, + isOkayPartialGranted = true, + isShowDialog = isShowDialog, + ) } private fun initAfterTMapReady() { @@ -244,7 +277,7 @@ class MapFragment : Fragment(), MapHandler { } binding.layoutCurrent.setOnClickListener { - requestPermissionsLauncher.launch(PERMISSIONS) + requestLocationPermission(isShowDialog = true) tMap.isTracking = true tMap.tMapView.setCenterPoint( @@ -294,7 +327,7 @@ class MapFragment : Fragment(), MapHandler { true ) tMap.addMarker(Marker.PLACE_MARKER, Marker.PLACE_MARKER_IMG, clickTMapPoint) - setPanel(clickTMapPoint, true) + mapHandler.setPanel(clickTMapPoint, true) } } } @@ -314,33 +347,11 @@ class MapFragment : Fragment(), MapHandler { currentTMapPoint.longitude ) tMap.addMarker(Marker.PLACE_MARKER, Marker.PLACE_MARKER_IMG, currentTMapPoint) - setPanel(currentTMapPoint, false) + mapHandler.setPanel(currentTMapPoint, false) } } } - override fun setPanel(tMapPoint: TMapPoint, isClickedFromPlaceSearch: Boolean) { - placeSearchViewModel.getGeoLocationInfo( - tMapPoint.latitude, - tMapPoint.longitude, - isClickedFromPlaceSearch - ) - } - - override fun setOnLocationChangeListener(location: android.location.Location) { - placeSearchViewModel.currentLocation = Location(location.latitude, location.longitude) - } - - override fun setOnDisableScrollWIthZoomLevelListener() { - if (binding.homePanel.layoutPanel.visibility == View.VISIBLE) { - binding.homePanel.layoutPanel.visibility = View.GONE - tMap.tMapView.removeTMapMarkerItem(Marker.PLACE_MARKER) - } else { - setViewVisibility() - mapUIVisibility = mapUIVisibility.xor(View.GONE) - } - } - private fun setViewVisibility() { with(binding) { textViewSearch.visibility = mapUIVisibility @@ -375,14 +386,6 @@ class MapFragment : Fragment(), MapHandler { super.onDestroyView() } - private val requestPermissionsLauncher = registerForActivityResult( - ActivityResultContracts.RequestMultiplePermissions() - ) { permissions -> - if (permissions.entries.any { it.value }) { - tMap.setTrackingMode() - } - } - fun setMissionStart() { Intent(requireContext(), AlarmActivity::class.java).apply { putExtra("MISSION_CODE", MissionService.MISSION_CODE) @@ -391,10 +394,4 @@ class MapFragment : Fragment(), MapHandler { startActivity(this) } } - - companion object { - private val PERMISSIONS = - arrayOf(permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION) - } - } \ No newline at end of file diff --git a/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt b/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt index 1209ff2..37a1fba 100644 --- a/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt +++ b/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt @@ -1,10 +1,10 @@ package com.stop.ui.mission -import android.Manifest import android.animation.Animator -import android.app.AlertDialog -import android.content.* -import android.content.pm.PackageManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter import android.os.Build import android.os.Bundle import android.view.LayoutInflater @@ -12,8 +12,6 @@ import android.view.View import android.view.ViewGroup import androidx.activity.OnBackPressedCallback import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels @@ -25,21 +23,23 @@ import com.stop.R import com.stop.databinding.FragmentMissionBinding import com.stop.domain.model.route.tmap.custom.Place import com.stop.domain.model.route.tmap.custom.WalkRoute -import com.stop.util.isMoreThanOreo -import com.stop.util.isMoreThanQ import com.stop.model.alarm.AlarmStatus import com.stop.model.map.Location import com.stop.model.mission.MissionStatus +import com.stop.permission.PermissionManager import com.stop.ui.alarmsetting.AlarmSettingViewModel import com.stop.ui.mission.MissionService.Companion.MISSION_LAST_TIME import com.stop.ui.mission.MissionService.Companion.MISSION_LOCATIONS import com.stop.ui.mission.MissionService.Companion.MISSION_OVER import com.stop.ui.mission.MissionService.Companion.MISSION_TIME_OVER +import com.stop.ui.tmap.MissionTMap +import com.stop.ui.tmap.TMapHandler import com.stop.ui.util.Marker +import com.stop.util.isMoreThanOreo import kotlinx.coroutines.flow.collectIndexed import kotlinx.coroutines.launch -class MissionFragment : Fragment(), MissionHandler { +class MissionFragment : Fragment() { private var _binding: FragmentMissionBinding? = null private val binding: FragmentMissionBinding @@ -54,6 +54,32 @@ class MissionFragment : Fragment(), MissionHandler { private lateinit var userInfoReceiver: BroadcastReceiver private lateinit var timeReceiver: BroadcastReceiver + private val permissionManager = PermissionManager(this) + + private val mapHandler = object : TMapHandler { + override fun alertTMapReady() { +// permissionManager.getLocationPermission( +// onGranted = , +// isOkayPartialGranted = true, +// isShowDialog = true, +// ) + getAlarmInfo() + alarmSettingViewModel.alarmStatus.value = AlarmStatus.MISSION + drawPersonLine() + setOnEnableScrollWithZoomLevelListener() + } + + override fun setOnLocationChangeListener(location: android.location.Location) { + } + + override fun setOnDisableScrollWIthZoomLevelListener() { + } + + override fun setPanel(tMapPoint: TMapPoint, isClickedFromPlaceSearch: Boolean) { + } + + } + var personCurrentLocation = Location(37.553836, 126.969652) var firstTime = 0 @@ -171,7 +197,7 @@ class MissionFragment : Fragment(), MissionHandler { setTimer() initTMap() setMissionOver() - checkLocationPermission() + requestLocationPermission(false) setObserve() setListener() } @@ -202,7 +228,10 @@ class MissionFragment : Fragment(), MissionHandler { } private fun setTimer() { - missionServiceIntent.putExtra(MISSION_LAST_TIME, alarmSettingViewModel.alarmItem.value?.lastTime) + missionServiceIntent.putExtra( + MISSION_LAST_TIME, + alarmSettingViewModel.alarmItem.value?.lastTime + ) if (isMoreThanOreo()) { requireActivity().startForegroundService(missionServiceIntent) } else { @@ -213,8 +242,7 @@ class MissionFragment : Fragment(), MissionHandler { } private fun initTMap() { - tMap = MissionTMap(requireActivity(), this) - tMap.init() + tMap = MissionTMap(requireActivity(), mapHandler) binding.constraintLayoutContainer.addView(tMap.tMapView) } @@ -249,16 +277,15 @@ class MissionFragment : Fragment(), MissionHandler { } } - private fun checkLocationPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission( - requireActivity(), - Manifest.permission.ACCESS_BACKGROUND_LOCATION - ) - ) { - setPermissionDialog(requireActivity()) - } - } + private fun requestLocationPermission( + isShowDialog: Boolean = false, + onGranted: (() -> Unit) = { } + ) { + permissionManager.getLocationPermission( + onGranted = onGranted, + isOkayPartialGranted = true, + isShowDialog = isShowDialog, + ) } fun setCompassMode() { @@ -266,14 +293,16 @@ class MissionFragment : Fragment(), MissionHandler { } fun setPersonCurrent() { - tMap.tMapView.setCenterPoint( - personCurrentLocation.latitude, - personCurrentLocation.longitude, - true - ) + requestLocationPermission(true) { + tMap.tMapView.setCenterPoint( + personCurrentLocation.latitude, + personCurrentLocation.longitude, + true + ) - tMap.isTracking = true - tMap.tMapView.zoomLevel = 16 + tMap.isTracking = true + tMap.tMapView.zoomLevel = 16 + } } fun setZoomOut() { @@ -298,14 +327,7 @@ class MissionFragment : Fragment(), MissionHandler { missionViewModel.missionStatus.value = MissionStatus.OVER } - override fun alertTMapReady() { - requestPermissionsLauncher.launch(PERMISSIONS) - getAlarmInfo() - alarmSettingViewModel.alarmStatus.value = AlarmStatus.MISSION - drawPersonLine() - } - - override fun setOnEnableScrollWithZoomLevelListener() { + private fun setOnEnableScrollWithZoomLevelListener() { tMap.apply { tMapView.setOnEnableScrollWithZoomLevelListener { _, _ -> isTracking = false @@ -322,20 +344,17 @@ class MissionFragment : Fragment(), MissionHandler { } private fun drawPersonLine() { - lateinit var beforeLocation: Location + var beforeLocation: Location? = null viewLifecycleOwner.lifecycleScope.launch { missionViewModel.userLocations.collectIndexed { index, userLocation -> if (userLocation.isEmpty()) { return@collectIndexed } val location = userLocation.last() - if (index == 0) { - initMarker(userLocation) - beforeLocation = location - } else if (index >= 1 && userLocation.isNotEmpty()) { + beforeLocation?.let { drawNowLocationLine( TMapPoint(location.latitude, location.longitude), - TMapPoint(beforeLocation.latitude, beforeLocation.longitude) + TMapPoint(it.latitude, it.longitude) ) personCurrentLocation = location if (tMap.isTracking) { @@ -346,6 +365,9 @@ class MissionFragment : Fragment(), MissionHandler { } beforeLocation = location arriveDestination(location.latitude, location.longitude) + } ?: run { + initMarker(userLocation) + beforeLocation = location } } } @@ -448,35 +470,6 @@ class MissionFragment : Fragment(), MissionHandler { } } - private fun setPermissionDialog(context: Context) { - if (isMoreThanQ()) { - val builder = AlertDialog.Builder(context) - builder.setTitle("백그라운드 위치 권한을 위해 항상 허용으로 설정해주세요.") - - val listener = DialogInterface.OnClickListener { _, p1 -> - when (p1) { - DialogInterface.BUTTON_POSITIVE -> - setBackgroundPermission() - } - } - builder.setPositiveButton("네", listener) - builder.setNegativeButton("아니오", null) - - builder.show() - } - } - - private fun setBackgroundPermission() { - if (isMoreThanQ()) { - ActivityCompat.requestPermissions( - requireActivity(), - arrayOf( - Manifest.permission.ACCESS_BACKGROUND_LOCATION, - ), 2 - ) - } - } - override fun onDestroyView() { _binding = null @@ -494,9 +487,6 @@ class MissionFragment : Fragment(), MissionHandler { companion object { private var PERSON_LINE_NUM = 0 - - private val PERMISSIONS = - arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/stop/ui/mission/MissionHandler.kt b/presentation/src/main/java/com/stop/ui/mission/MissionHandler.kt deleted file mode 100644 index 28f2eb2..0000000 --- a/presentation/src/main/java/com/stop/ui/mission/MissionHandler.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.stop.ui.mission - -import com.stop.ui.util.Handler - -interface MissionHandler : Handler { - - fun alertTMapReady() - - fun setOnEnableScrollWithZoomLevelListener() - -} diff --git a/presentation/src/main/java/com/stop/ui/placesearch/PlaceSearchViewModel.kt b/presentation/src/main/java/com/stop/ui/placesearch/PlaceSearchViewModel.kt index 736d6e4..eb7212e 100644 --- a/presentation/src/main/java/com/stop/ui/placesearch/PlaceSearchViewModel.kt +++ b/presentation/src/main/java/com/stop/ui/placesearch/PlaceSearchViewModel.kt @@ -16,11 +16,14 @@ import com.stop.domain.usecase.nearplace.InsertRecentPlaceSearchUseCase import com.stop.model.Event import com.stop.model.map.Location import com.stop.model.route.Coordinate -import com.stop.ui.map.MapTMap import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.math.round @@ -64,12 +67,14 @@ class PlaceSearchViewModel @Inject constructor( val distance: LiveData get() = _distance - val recentPlaceSearch: StateFlow> = getRecentPlaceSearchUseCase().stateIn( - scope = viewModelScope, started = SharingStarted.WhileSubscribed(), initialValue = emptyList() - ) + val recentPlaceSearch: StateFlow> = + getRecentPlaceSearchUseCase().stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(), + initialValue = emptyList() + ) // 기본 주소로 서울역 주소 지정 - var tMap: MapTMap? = null var currentLocation = Location(37.553836, 126.969652) var clickedPlaceName = "" var panelInfo: com.stop.model.route.Place? = null diff --git a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailFragment.kt b/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailFragment.kt index bc8ea25..28fee16 100644 --- a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailFragment.kt +++ b/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailFragment.kt @@ -1,5 +1,6 @@ package com.stop.ui.routedetail +import android.location.Location import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -8,21 +9,37 @@ import androidx.core.view.GravityCompat import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import androidx.navigation.navGraphViewModels +import com.skt.tmap.TMapPoint import com.stop.R import com.stop.databinding.FragmentRouteDetailBinding import com.stop.domain.model.route.tmap.custom.Coordinate import com.stop.ui.route.RouteResultViewModel +import com.stop.ui.tmap.RouteDetailTMap +import com.stop.ui.tmap.TMapHandler import com.stop.ui.util.DrawerStringUtils import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class RouteDetailFragment : Fragment(), RouteDetailHandler { +class RouteDetailFragment : Fragment() { private var _binding: FragmentRouteDetailBinding? = null private val binding: FragmentRouteDetailBinding get() = _binding!! private val routeResultViewModel: RouteResultViewModel by navGraphViewModels(R.id.route_nav_graph) + private val mapHandler = object : TMapHandler { + override fun alertTMapReady() { + routeResultViewModel.itinerary.value?.let { + tMap.drawRoutes(it.routes) + } + } + + override fun setOnLocationChangeListener(location: Location) {} + + override fun setOnDisableScrollWIthZoomLevelListener() {} + + override fun setPanel(tMapPoint: TMapPoint, isClickedFromPlaceSearch: Boolean) {} + } private lateinit var tMap: RouteDetailTMap @@ -45,8 +62,7 @@ class RouteDetailFragment : Fragment(), RouteDetailHandler { } private fun initTMap() { - tMap = RouteDetailTMap(requireActivity(), this) - tMap.init() + tMap = RouteDetailTMap(requireActivity(), mapHandler) binding.layoutContainer.addView(tMap.tMapView) } @@ -92,20 +108,20 @@ class RouteDetailFragment : Fragment(), RouteDetailHandler { binding.textViewDestination.text = it.name } routeResultViewModel.itinerary.observe(viewLifecycleOwner) { - binding.routeDetailDrawer.textViewTime.text = DrawerStringUtils.getTimeString(it.totalTime) - binding.routeDetailDrawer.textViewInformation.text = DrawerStringUtils.getTopInformationString(it) + binding.routeDetailDrawer.textViewTime.text = + DrawerStringUtils.getTimeString(it.totalTime) + binding.routeDetailDrawer.textViewInformation.text = + DrawerStringUtils.getTopInformationString(it) } routeResultViewModel.isLastTimeAvailable.observe(viewLifecycleOwner) { - binding.routeDetailDrawer.viewAlarm.visibility = if (it) View.VISIBLE else View.INVISIBLE - binding.routeDetailDrawer.viewAlarm2.visibility = if (it) View.INVISIBLE else View.VISIBLE - binding.routeDetailDrawer.constraintLayoutAlertCantDo.visibility = if (it) View.VISIBLE else View.INVISIBLE - binding.routeDetailDrawer.textViewAlarmTextCantSet.visibility = if (it) View.INVISIBLE else View.VISIBLE - } - } - - override fun alertTMapReady() { - routeResultViewModel.itinerary.value?.let { - tMap.drawRoutes(it.routes) + binding.routeDetailDrawer.viewAlarm.visibility = + if (it) View.VISIBLE else View.INVISIBLE + binding.routeDetailDrawer.viewAlarm2.visibility = + if (it) View.INVISIBLE else View.VISIBLE + binding.routeDetailDrawer.constraintLayoutAlertCantDo.visibility = + if (it) View.VISIBLE else View.INVISIBLE + binding.routeDetailDrawer.textViewAlarmTextCantSet.visibility = + if (it) View.INVISIBLE else View.VISIBLE } } diff --git a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailHandler.kt b/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailHandler.kt deleted file mode 100644 index e2a097c..0000000 --- a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailHandler.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.stop.ui.routedetail - -import com.stop.ui.util.Handler - -interface RouteDetailHandler : Handler { - - fun alertTMapReady() - -} \ No newline at end of file diff --git a/presentation/src/main/java/com/stop/ui/map/MapTMap.kt b/presentation/src/main/java/com/stop/ui/tmap/MapTMap.kt similarity index 92% rename from presentation/src/main/java/com/stop/ui/map/MapTMap.kt rename to presentation/src/main/java/com/stop/ui/tmap/MapTMap.kt index 39ca747..5a1fb30 100644 --- a/presentation/src/main/java/com/stop/ui/map/MapTMap.kt +++ b/presentation/src/main/java/com/stop/ui/tmap/MapTMap.kt @@ -1,4 +1,4 @@ -package com.stop.ui.map +package com.stop.ui.tmap import android.content.Context import android.graphics.PointF @@ -9,20 +9,15 @@ import com.skt.tmap.overlay.TMapMarkerItem import com.skt.tmap.poi.TMapPOIItem import com.stop.model.map.Location import com.stop.ui.util.Marker -import com.stop.ui.util.TMap class MapTMap( context: Context, - private var handler: MapHandler, + private val handler: TMapHandler, ) : TMap(context, handler) { private val enablePoints = mutableSetOf() private var isLongClick = false - fun setHandler(handler: MapHandler) { - this.handler = handler - } - fun initListener() { tMapView.setOnClickListenerCallback(onClickListenerCallback) tMapView.setOnLongClickListenerCallback(onLongClickListenerCallback) diff --git a/presentation/src/main/java/com/stop/ui/mission/MissionTMap.kt b/presentation/src/main/java/com/stop/ui/tmap/MissionTMap.kt similarity index 93% rename from presentation/src/main/java/com/stop/ui/mission/MissionTMap.kt rename to presentation/src/main/java/com/stop/ui/tmap/MissionTMap.kt index c001547..9d28dbf 100644 --- a/presentation/src/main/java/com/stop/ui/mission/MissionTMap.kt +++ b/presentation/src/main/java/com/stop/ui/tmap/MissionTMap.kt @@ -1,15 +1,14 @@ -package com.stop.ui.mission +package com.stop.ui.tmap import android.content.Context import androidx.core.content.ContextCompat import com.skt.tmap.TMapPoint import com.skt.tmap.overlay.TMapPolyLine import com.stop.domain.model.route.tmap.custom.WalkRoute -import com.stop.ui.util.TMap class MissionTMap( private val context: Context, - handler: MissionHandler, + handler: TMapHandler, ) : TMap(context, handler) { fun drawMoveLine(nowLocation: TMapPoint, beforeLocation: TMapPoint, id: String, color: Int) { @@ -18,7 +17,7 @@ class MissionTMap( lineColor = ContextCompat.getColor(context, color) outLineColor = ContextCompat.getColor(context, color) } - + tMapView.addTMapPolyLine(polyLine) } diff --git a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailTMap.kt b/presentation/src/main/java/com/stop/ui/tmap/RouteDetailTMap.kt similarity index 86% rename from presentation/src/main/java/com/stop/ui/routedetail/RouteDetailTMap.kt rename to presentation/src/main/java/com/stop/ui/tmap/RouteDetailTMap.kt index 9c7a448..e36d5ce 100644 --- a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailTMap.kt +++ b/presentation/src/main/java/com/stop/ui/tmap/RouteDetailTMap.kt @@ -1,4 +1,4 @@ -package com.stop.ui.routedetail +package com.stop.ui.tmap import android.content.Context import android.graphics.Color @@ -6,14 +6,16 @@ import androidx.core.content.ContextCompat import com.skt.tmap.TMapPoint import com.skt.tmap.overlay.TMapPolyLine import com.stop.R -import com.stop.domain.model.route.tmap.custom.* +import com.stop.domain.model.route.tmap.custom.Coordinate +import com.stop.domain.model.route.tmap.custom.Route +import com.stop.domain.model.route.tmap.custom.TransportRoute +import com.stop.domain.model.route.tmap.custom.WalkRoute import com.stop.ui.util.Marker -import com.stop.ui.util.TMap class RouteDetailTMap( private val context: Context, - handler: RouteDetailHandler, -) : TMap(context, handler) { + tMapHandler: TMapHandler, +) : TMap(context, tMapHandler) { private var polyLine = TMapPolyLine() @@ -92,7 +94,11 @@ class RouteDetailTMap( } fun setRouteItemFocus(coordinate: Coordinate) { - tMapView.setCenterPoint(coordinate.latitude.toDouble(), coordinate.longitude.toDouble(), true) + tMapView.setCenterPoint( + coordinate.latitude.toDouble(), + coordinate.longitude.toDouble(), + true + ) tMapView.zoomLevel = 16 } diff --git a/presentation/src/main/java/com/stop/ui/util/TMap.kt b/presentation/src/main/java/com/stop/ui/tmap/TMap.kt similarity index 67% rename from presentation/src/main/java/com/stop/ui/util/TMap.kt rename to presentation/src/main/java/com/stop/ui/tmap/TMap.kt index c5ebd3c..095641b 100644 --- a/presentation/src/main/java/com/stop/ui/util/TMap.kt +++ b/presentation/src/main/java/com/stop/ui/tmap/TMap.kt @@ -1,4 +1,4 @@ -package com.stop.ui.util +package com.stop.ui.tmap import android.content.Context import androidx.core.content.ContextCompat @@ -8,50 +8,29 @@ import com.skt.tmap.TMapPoint import com.skt.tmap.TMapView import com.skt.tmap.overlay.TMapMarkerItem import com.stop.BuildConfig -import com.stop.model.map.Location -import com.stop.ui.map.MapHandler -import com.stop.ui.mission.MissionHandler -import com.stop.ui.routedetail.RouteDetailHandler +import com.stop.ui.util.Marker open class TMap( private val context: Context, - private val handler: Handler + private val tMapHandler: TMapHandler ) { - lateinit var tMapView: TMapView - lateinit var initLocation: Location + val tMapView: TMapView = TMapView(context).apply { + setSKTMapApiKey(BuildConfig.TMAP_APP_KEY) + setOnMapReadyListener { + setVisibleLogo(false) + mapType = TMapView.MapType.DEFAULT + zoomLevel = 16 + + tMapHandler.alertTMapReady() + } + } val latitudes = arrayListOf() val longitudes = arrayListOf() var isTracking = true - fun init() { - tMapView = TMapView(context).apply { - setSKTMapApiKey(BuildConfig.TMAP_APP_KEY) - setOnMapReadyListener { - tMapView.setVisibleLogo(false) - tMapView.mapType = TMapView.MapType.DEFAULT - tMapView.zoomLevel = 16 - - when (this@TMap.handler) { - is MapHandler -> { - (this@TMap.handler).alertTMapReady() - } - is RouteDetailHandler -> { - (this@TMap.handler).alertTMapReady() - } - is MissionHandler -> { - (this@TMap.handler).alertTMapReady() - (this@TMap.handler).setOnEnableScrollWithZoomLevelListener() - } - } - - initLocation = Location(tMapView.locationPoint.latitude, tMapView.locationPoint.longitude) - } - } - } - fun setTrackingMode() { val manager = TMapGpsManager(context).apply { minDistance = 2.5F @@ -68,7 +47,7 @@ open class TMap( if (location != null && checkLocationInTMapLocation(location)) { val nowLocation = TMapPoint(location.latitude, location.longitude) - (handler as MapHandler).setOnLocationChangeListener(location) + tMapHandler.setOnLocationChangeListener(location) addMarker( Marker.PERSON_MARKER, Marker.PERSON_MARKER_IMG, @@ -110,7 +89,12 @@ open class TMap( tMapView.zoomLevel -= 1 } - fun getDistance(startLatitude: Double, startLongitude: Double, endLatitude: Double, endLongitude: Double): Float { + fun getDistance( + startLatitude: Double, + startLongitude: Double, + endLatitude: Double, + endLongitude: Double + ): Float { val startPoint = android.location.Location("Start") val endPoint = android.location.Location("End") diff --git a/presentation/src/main/java/com/stop/ui/map/MapHandler.kt b/presentation/src/main/java/com/stop/ui/tmap/TMapHandler.kt similarity index 74% rename from presentation/src/main/java/com/stop/ui/map/MapHandler.kt rename to presentation/src/main/java/com/stop/ui/tmap/TMapHandler.kt index 167a828..2456457 100644 --- a/presentation/src/main/java/com/stop/ui/map/MapHandler.kt +++ b/presentation/src/main/java/com/stop/ui/tmap/TMapHandler.kt @@ -1,9 +1,8 @@ -package com.stop.ui.map +package com.stop.ui.tmap import com.skt.tmap.TMapPoint -import com.stop.ui.util.Handler -interface MapHandler : Handler { +interface TMapHandler { fun alertTMapReady() @@ -13,4 +12,4 @@ interface MapHandler : Handler { fun setPanel(tMapPoint: TMapPoint, isClickedFromPlaceSearch: Boolean) -} +} \ No newline at end of file diff --git a/presentation/src/main/java/com/stop/ui/util/Handler.kt b/presentation/src/main/java/com/stop/ui/util/Handler.kt deleted file mode 100644 index f72d9b7..0000000 --- a/presentation/src/main/java/com/stop/ui/util/Handler.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.stop.ui.util - -interface Handler { -} \ No newline at end of file From 07fc6078e084c505f1c9810df9d233de368cc56d Mon Sep 17 00:00:00 2001 From: DoDoBest Date: Fri, 3 May 2024 16:55:42 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20=EC=BD=94=EB=93=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/stop/TroubleShooterApplication.kt | 4 +-- .../ui/alarmsetting/AlarmSettingFragment.kt | 11 +++++--- .../ui/alarmsetting/AlarmSettingViewModel.kt | 20 ++++++++++----- .../ui/alarmsetting/LastTimeCheckWorker.kt | 12 ++++----- .../com/stop/ui/alarmstart/AlarmReceiver.kt | 11 +++++--- .../com/stop/ui/alarmstart/SoundService.kt | 18 +++++++++---- .../com/stop/ui/mission/MissionFragment.kt | 17 +++---------- .../com/stop/ui/mission/MissionService.kt | 17 ++++++++++--- .../java/com/stop/ui/route/RouteFragment.kt | 14 +++++++++-- .../com/stop/ui/route/RouteResultViewModel.kt | 6 ++++- .../java/com/stop/ui/route/RouteViewModel.kt | 2 +- .../stop/ui/routedetail/RouteDetailAdapter.kt | 25 ++++++++++++++----- .../stop/ui/util/EditTextExtensionFunction.kt | 4 ++- .../main/java/com/stop/util/AlarmFunctions.kt | 9 ++++--- .../src/main/java/com/stop/util/Context.kt | 20 ++++++++++----- .../main/java/com/stop/util/TimeConverter.kt | 4 ++- 16 files changed, 128 insertions(+), 66 deletions(-) diff --git a/presentation/src/main/java/com/stop/TroubleShooterApplication.kt b/presentation/src/main/java/com/stop/TroubleShooterApplication.kt index d625be3..1526a9e 100644 --- a/presentation/src/main/java/com/stop/TroubleShooterApplication.kt +++ b/presentation/src/main/java/com/stop/TroubleShooterApplication.kt @@ -7,10 +7,10 @@ import dagger.hilt.android.HiltAndroidApp import javax.inject.Inject @HiltAndroidApp -class TroubleShooterApplication : Application(), Configuration.Provider{ +class TroubleShooterApplication : Application(), Configuration.Provider { @Inject - lateinit var workerFactory : HiltWorkerFactory + lateinit var workerFactory: HiltWorkerFactory @Inject override lateinit var workManagerConfiguration: Configuration diff --git a/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingFragment.kt b/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingFragment.kt index 9f6cfd5..1707043 100644 --- a/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingFragment.kt +++ b/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingFragment.kt @@ -45,10 +45,13 @@ class AlarmSettingFragment : Fragment() { private fun initView() { binding.textViewStartPosition.text = routeResultViewModel.origin.value?.name binding.textViewEndPosition.text = routeResultViewModel.destination.value?.name - binding.textViewLastTimeInfo.text = routeResultViewModel.lastTimes.value?.filterNotNull()?.sortedBy { - it.timeToBoard - }?.first()?.timeToBoard - val expectedWalkingTime = (routeResultViewModel.itinerary.value!!.routes.first().sectionTime.div(60)).roundToInt().toString() + "분" + binding.textViewLastTimeInfo.text = + routeResultViewModel.lastTimes.value?.filterNotNull()?.sortedBy { + it.timeToBoard + }?.first()?.timeToBoard + val expectedWalkingTime = + (routeResultViewModel.itinerary.value!!.routes.first().sectionTime.div(60)).roundToInt() + .toString() + "분" binding.textViewWalkTimeInfo.text = expectedWalkingTime with(binding) { diff --git a/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingViewModel.kt b/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingViewModel.kt index e6587a5..b6604f8 100644 --- a/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingViewModel.kt +++ b/presentation/src/main/java/com/stop/ui/alarmsetting/AlarmSettingViewModel.kt @@ -7,24 +7,24 @@ import androidx.lifecycle.viewModelScope import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import androidx.work.workDataOf -import com.stop.util.AlarmFunctions -import com.stop.util.convertTimeMillisToString import com.stop.domain.model.alarm.AlarmUseCaseItem import com.stop.domain.usecase.alarm.DeleteAlarmUseCase import com.stop.domain.usecase.alarm.GetAlarmUseCase import com.stop.domain.usecase.alarm.SaveAlarmUseCase -import com.stop.util.makeFullTime import com.stop.model.alarm.AlarmStatus import com.stop.model.mission.MissionStatus import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_TIME import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.LAST_TIME +import com.stop.util.AlarmFunctions +import com.stop.util.convertTimeMillisToString +import com.stop.util.makeFullTime import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch -import java.util.* +import java.util.UUID import javax.inject.Inject @HiltViewModel @@ -53,7 +53,12 @@ class AlarmSettingViewModel @Inject constructor( fun saveAlarm(alarmUseCaseItem: AlarmUseCaseItem) { viewModelScope.launch(Dispatchers.IO) { - saveAlarmUseCase(alarmUseCaseItem.copy(alarmTime = alarmTime.value ?: 0, alarmMethod = alarmMethod)) + saveAlarmUseCase( + alarmUseCaseItem.copy( + alarmTime = alarmTime.value ?: 0, + alarmMethod = alarmMethod + ) + ) } } @@ -67,9 +72,11 @@ class AlarmSettingViewModel @Inject constructor( MissionStatus.BEFORE -> { alarmStatus.value = AlarmStatus.EXIST } + MissionStatus.ONGOING -> { alarmStatus.value = AlarmStatus.MISSION } + MissionStatus.OVER -> { alarmStatus.value = AlarmStatus.EXIST } @@ -117,7 +124,8 @@ class AlarmSettingViewModel @Inject constructor( fun startCountDownTimer(time: String) { val lastTimeMillis = makeFullTime(time).timeInMillis val nowTimeMillis = System.currentTimeMillis() - var diffTimeMillis = if (lastTimeMillis > nowTimeMillis) lastTimeMillis - nowTimeMillis else 0L + var diffTimeMillis = + if (lastTimeMillis > nowTimeMillis) lastTimeMillis - nowTimeMillis else 0L viewModelScope.launch(Dispatchers.IO) { var oldTimeMillis = System.currentTimeMillis() diff --git a/presentation/src/main/java/com/stop/ui/alarmsetting/LastTimeCheckWorker.kt b/presentation/src/main/java/com/stop/ui/alarmsetting/LastTimeCheckWorker.kt index 5de34ff..195425d 100644 --- a/presentation/src/main/java/com/stop/ui/alarmsetting/LastTimeCheckWorker.kt +++ b/presentation/src/main/java/com/stop/ui/alarmsetting/LastTimeCheckWorker.kt @@ -10,12 +10,12 @@ import androidx.work.ForegroundInfo import androidx.work.WorkManager import androidx.work.WorkerParameters import com.stop.R -import com.stop.util.AlarmFunctions import com.stop.domain.usecase.nearplace.GetNearPlacesUseCase -import com.stop.util.isMoreThanOreo -import com.stop.util.makeFullTime import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_TIME import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.LAST_TIME +import com.stop.util.AlarmFunctions +import com.stop.util.isMoreThanOreo +import com.stop.util.makeFullTime import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.delay @@ -44,7 +44,7 @@ class LastTimeCheckWorker @AssistedInject constructor( return Result.success() } - private fun initData(){ + private fun initData() { lastTime = inputData.getString(LAST_TIME) ?: "" } @@ -83,7 +83,7 @@ class LastTimeCheckWorker @AssistedInject constructor( private suspend fun checkLastTransportTime() { while (isStopped.not()) { - //TODO 막차시간 가져오는 API로 변경 해야합니다. + //TODO 막차시간 가져오는 API로 변경 해야합니다. getNearPlacesUseCase( "아남타워", 126.969652, @@ -92,7 +92,7 @@ class LastTimeCheckWorker @AssistedInject constructor( val resultLastTime = "21:04:00" - if(lastTime != resultLastTime && resultLastTime != null){ + if (lastTime != resultLastTime && resultLastTime != null) { lastTime = resultLastTime alarmFunctions.cancelAlarm() alarmFunctions.callAlarm(resultLastTime, alarmTime) diff --git a/presentation/src/main/java/com/stop/ui/alarmstart/AlarmReceiver.kt b/presentation/src/main/java/com/stop/ui/alarmstart/AlarmReceiver.kt index e1fdb6f..4e2f2cd 100644 --- a/presentation/src/main/java/com/stop/ui/alarmstart/AlarmReceiver.kt +++ b/presentation/src/main/java/com/stop/ui/alarmstart/AlarmReceiver.kt @@ -6,17 +6,18 @@ import android.content.Context import android.content.Intent import com.stop.AlarmActivity import com.stop.R -import com.stop.util.isMoreThanOreo import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_CODE import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_NOTIFICATION_HIGH_ID import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_NOTIFICATION_ID import com.stop.util.getActivityPendingIntent import com.stop.util.getAlarmHighNotification +import com.stop.util.isMoreThanOreo class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { - val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.cancel(ALARM_NOTIFICATION_ID) val content = context.getString(R.string.alarm_content_text) @@ -28,7 +29,8 @@ class AlarmReceiver : BroadcastReceiver() { val alarmStartPendingIntent = context.getActivityPendingIntent( Intent(context, AlarmActivity::class.java).apply { putExtra("ALARM_CODE", ALARM_CODE) - flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP + flags = + Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP }, ALARM_CODE ) @@ -44,7 +46,8 @@ class AlarmReceiver : BroadcastReceiver() { Intent(context, AlarmActivity::class.java).apply { putExtra("ALARM_CODE", ALARM_CODE) - flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP + flags = + Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP context.startActivity(this) } } diff --git a/presentation/src/main/java/com/stop/ui/alarmstart/SoundService.kt b/presentation/src/main/java/com/stop/ui/alarmstart/SoundService.kt index e9ca0b3..1a5c585 100644 --- a/presentation/src/main/java/com/stop/ui/alarmstart/SoundService.kt +++ b/presentation/src/main/java/com/stop/ui/alarmstart/SoundService.kt @@ -5,15 +5,19 @@ import android.content.Context import android.content.Intent import android.media.MediaPlayer import android.media.RingtoneManager -import android.os.* +import android.os.CombinedVibration +import android.os.PowerManager +import android.os.VibrationEffect +import android.os.Vibrator +import android.os.VibratorManager import androidx.lifecycle.LifecycleService import androidx.lifecycle.lifecycleScope import com.stop.domain.usecase.alarm.GetAlarmUseCase +import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_CODE +import com.stop.util.getBroadcastPendingIntent import com.stop.util.isMoreThanOreoUnderRedVelVet import com.stop.util.isMoreThanSnow import com.stop.util.isUnderOreo -import com.stop.ui.alarmsetting.AlarmSettingFragment.Companion.ALARM_CODE -import com.stop.util.getBroadcastPendingIntent import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @@ -37,7 +41,10 @@ class SoundService : LifecycleService() { getAlarmUseCase().collectLatest { alarmData -> alarmData?.let { if (it.alarmMethod) { - mediaPlayer = MediaPlayer.create(this@SoundService, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM)).apply { + mediaPlayer = MediaPlayer.create( + this@SoundService, + RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM) + ).apply { setWakeMode(this@SoundService, PowerManager.PARTIAL_WAKE_LOCK) isLooping = true start() @@ -55,7 +62,8 @@ class SoundService : LifecycleService() { val effect = VibrationEffect.createWaveform(pattern, amplitude, 0) vibrator?.vibrate(effect) } else if (isMoreThanSnow()) { - vibratorManager = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager + vibratorManager = + getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager val effect = VibrationEffect.createWaveform(pattern, amplitude, 0) val combinedVibration = CombinedVibration.createParallel(effect) vibratorManager?.vibrate(combinedVibration) diff --git a/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt b/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt index 37a1fba..df8039c 100644 --- a/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt +++ b/presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt @@ -11,7 +11,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.activity.OnBackPressedCallback -import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels @@ -58,11 +57,9 @@ class MissionFragment : Fragment() { private val mapHandler = object : TMapHandler { override fun alertTMapReady() { -// permissionManager.getLocationPermission( -// onGranted = , -// isOkayPartialGranted = true, -// isShowDialog = true, -// ) + requestLocationPermission(false) { + tMap.isTracking = true + } getAlarmInfo() alarmSettingViewModel.alarmStatus.value = AlarmStatus.MISSION drawPersonLine() @@ -335,14 +332,6 @@ class MissionFragment : Fragment() { } } - private val requestPermissionsLauncher = registerForActivityResult( - ActivityResultContracts.RequestMultiplePermissions() - ) { permissions -> - if (permissions.entries.any { it.value }) { - tMap.isTracking = false - } - } - private fun drawPersonLine() { var beforeLocation: Location? = null viewLifecycleOwner.lifecycleScope.launch { diff --git a/presentation/src/main/java/com/stop/ui/mission/MissionService.kt b/presentation/src/main/java/com/stop/ui/mission/MissionService.kt index 78e92d6..f1fc317 100644 --- a/presentation/src/main/java/com/stop/ui/mission/MissionService.kt +++ b/presentation/src/main/java/com/stop/ui/mission/MissionService.kt @@ -12,8 +12,12 @@ import androidx.core.app.ActivityCompat import androidx.core.app.NotificationCompat import androidx.lifecycle.LifecycleService import androidx.lifecycle.lifecycleScope -import com.google.android.gms.location.* -import com.stop.* +import com.google.android.gms.location.LocationCallback +import com.google.android.gms.location.LocationRequest +import com.google.android.gms.location.LocationResult +import com.google.android.gms.location.LocationServices +import com.google.android.gms.location.Priority +import com.stop.AlarmActivity import com.stop.R import com.stop.model.map.Location import com.stop.util.convertTimeMillisToString @@ -126,7 +130,11 @@ class MissionService : LifecycleService() { } } } - fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()) + fusedLocationClient.requestLocationUpdates( + locationRequest, + locationCallback, + Looper.getMainLooper() + ) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { @@ -142,7 +150,8 @@ class MissionService : LifecycleService() { if (lastTimeString != null) { val lastTimeMillis = makeFullTime(lastTimeString).timeInMillis val nowTimeMillis = System.currentTimeMillis() - var diffTimeMillis = if (lastTimeMillis > nowTimeMillis) lastTimeMillis - nowTimeMillis else 0L + var diffTimeMillis = + if (lastTimeMillis > nowTimeMillis) lastTimeMillis - nowTimeMillis else 0L timer.cancel() timer = lifecycleScope.launch(Dispatchers.IO) { diff --git a/presentation/src/main/java/com/stop/ui/route/RouteFragment.kt b/presentation/src/main/java/com/stop/ui/route/RouteFragment.kt index 58a6ce8..5b9840a 100644 --- a/presentation/src/main/java/com/stop/ui/route/RouteFragment.kt +++ b/presentation/src/main/java/com/stop/ui/route/RouteFragment.kt @@ -149,7 +149,12 @@ class RouteFragment : Fragment() { } else { it.name } - binding.textViewDestination.setTextColor(ContextCompat.getColor(this.requireContext(), R.color.main_dark_grey)) + binding.textViewDestination.setTextColor( + ContextCompat.getColor( + this.requireContext(), + R.color.main_dark_grey + ) + ) } routeViewModel.origin.observe(viewLifecycleOwner) { binding.textViewOrigin.text = if (it.name.isEmpty()) { @@ -157,7 +162,12 @@ class RouteFragment : Fragment() { } else { it.name } - binding.textViewOrigin.setTextColor(ContextCompat.getColor(this.requireContext(), R.color.main_dark_grey)) + binding.textViewOrigin.setTextColor( + ContextCompat.getColor( + this.requireContext(), + R.color.main_dark_grey + ) + ) } // routeViewModel.routeResponse.observe(viewLifecycleOwner) { // if (it == null) { diff --git a/presentation/src/main/java/com/stop/ui/route/RouteResultViewModel.kt b/presentation/src/main/java/com/stop/ui/route/RouteResultViewModel.kt index 7cd8bc2..f46c685 100644 --- a/presentation/src/main/java/com/stop/ui/route/RouteResultViewModel.kt +++ b/presentation/src/main/java/com/stop/ui/route/RouteResultViewModel.kt @@ -10,7 +10,11 @@ import com.stop.domain.model.route.tmap.custom.Itinerary import com.stop.domain.model.route.tmap.custom.MoveType import com.stop.domain.model.route.tmap.custom.Route import com.stop.domain.model.route.tmap.custom.TransportRoute -import com.stop.model.route.* +import com.stop.model.route.Place +import com.stop.model.route.RouteItem +import com.stop.model.route.RouteItemType +import com.stop.model.route.toFirstRouteItem +import com.stop.model.route.toLastRouteItem class RouteResultViewModel : ViewModel() { diff --git a/presentation/src/main/java/com/stop/ui/route/RouteViewModel.kt b/presentation/src/main/java/com/stop/ui/route/RouteViewModel.kt index 6a7249b..47b72c7 100644 --- a/presentation/src/main/java/com/stop/ui/route/RouteViewModel.kt +++ b/presentation/src/main/java/com/stop/ui/route/RouteViewModel.kt @@ -75,7 +75,7 @@ class RouteViewModel @Inject constructor( is SocketTimeoutException -> Event(ErrorType.SOCKET_TIMEOUT_EXCEPTION) is UnknownHostException -> Event(ErrorType.UNKNOWN_HOST_EXCEPTION) else -> Event(ErrorType.UNKNOWN_EXCEPTION) - } + } _errorMessage.postValue(errorMessage) _isLoading.postValue(Event(false)) } diff --git a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailAdapter.kt b/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailAdapter.kt index 5c9f515..6527af1 100644 --- a/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailAdapter.kt +++ b/presentation/src/main/java/com/stop/ui/routedetail/RouteDetailAdapter.kt @@ -4,7 +4,6 @@ import android.content.res.ColorStateList import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.content.ContextCompat import androidx.core.widget.ImageViewCompat import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter @@ -28,7 +27,10 @@ class RouteDetailAdapter( fun bind(routeItem: RouteItem) { binding.textViewName.text = routeItem.name binding.viewCurrentLine.setBackgroundColor(routeItem.currentColor) - ImageViewCompat.setImageTintList(binding.imageViewCurrentLine, ColorStateList.valueOf(routeItem.currentColor)) + ImageViewCompat.setImageTintList( + binding.imageViewCurrentLine, + ColorStateList.valueOf(routeItem.currentColor) + ) } } @@ -37,12 +39,17 @@ class RouteDetailAdapter( ) : RecyclerView.ViewHolder(binding.root) { fun bind(routeItem: RouteItem) { binding.textViewName.text = routeItem.name - binding.textViewInformation.text = DrawerStringUtils.getRouteItemInformationString(routeItem) - binding.textViewLastTime1.visibility = if (routeItem.lastTime != null) View.VISIBLE else View.INVISIBLE + binding.textViewInformation.text = + DrawerStringUtils.getRouteItemInformationString(routeItem) + binding.textViewLastTime1.visibility = + if (routeItem.lastTime != null) View.VISIBLE else View.INVISIBLE binding.textViewLastTime2.text = routeItem.lastTime binding.viewBeforeLine.setBackgroundColor(routeItem.beforeColor) binding.viewCurrentLine.setBackgroundColor(routeItem.currentColor) - ImageViewCompat.setImageTintList(binding.imageViewCurrentLine, ColorStateList.valueOf(routeItem.currentColor)) + ImageViewCompat.setImageTintList( + binding.imageViewCurrentLine, + ColorStateList.valueOf(routeItem.currentColor) + ) binding.imageViewMode.setImageResource(routeItem.mode) } } @@ -53,7 +60,10 @@ class RouteDetailAdapter( fun bind(routeItem: RouteItem) { binding.textViewName.text = routeItem.name binding.viewBeforeLine.setBackgroundColor(routeItem.beforeColor) - ImageViewCompat.setImageTintList(binding.imageViewCurrentLine, ColorStateList.valueOf(routeItem.currentColor)) + ImageViewCompat.setImageTintList( + binding.imageViewCurrentLine, + ColorStateList.valueOf(routeItem.currentColor) + ) } } @@ -65,14 +75,17 @@ class RouteDetailAdapter( binding = ItemRouteFirstBinding.inflate(inflater, parent, false) FirstViewHolder(binding) } + TYPE_PATH -> { binding = ItemRoutePathBinding.inflate(inflater, parent, false) PathViewHolder(binding) } + TYPE_LAST -> { binding = ItemRouteLastBinding.inflate(inflater, parent, false) LastViewHolder(binding) } + else -> throw IllegalArgumentException("Invalid ViewType") } diff --git a/presentation/src/main/java/com/stop/ui/util/EditTextExtensionFunction.kt b/presentation/src/main/java/com/stop/ui/util/EditTextExtensionFunction.kt index 7f5e7b6..81e80f3 100644 --- a/presentation/src/main/java/com/stop/ui/util/EditTextExtensionFunction.kt +++ b/presentation/src/main/java/com/stop/ui/util/EditTextExtensionFunction.kt @@ -11,7 +11,9 @@ import kotlinx.coroutines.flow.onStart fun EditText.textChangesToFlow(): Flow { return callbackFlow { val listener = object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = + Unit + override fun afterTextChanged(s: Editable?) = Unit override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { trySend(text) diff --git a/presentation/src/main/java/com/stop/util/AlarmFunctions.kt b/presentation/src/main/java/com/stop/util/AlarmFunctions.kt index d44b415..ad098cd 100644 --- a/presentation/src/main/java/com/stop/util/AlarmFunctions.kt +++ b/presentation/src/main/java/com/stop/util/AlarmFunctions.kt @@ -16,7 +16,8 @@ class AlarmFunctions( ) { fun callAlarm(lastTime: String, alarmTime: Int) { - val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val alarmSettingPendingIntent = context.getActivityPendingIntent( Intent(context, MainActivity::class.java).apply { @@ -25,7 +26,8 @@ class AlarmFunctions( ALARM_MAP_CODE ) - val content = context.getString(R.string.alarm_last_notification_text, lastTime, alarmTime.toString()) + val content = + context.getString(R.string.alarm_last_notification_text, lastTime, alarmTime.toString()) val alarmSettingNotification = context.getAlarmDefaultNotification( alarmSettingPendingIntent, content @@ -54,7 +56,8 @@ class AlarmFunctions( alarmManager.cancel(alarmReceiverPendingIntent) - val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.cancel(ALARM_NOTIFICATION_ID) } diff --git a/presentation/src/main/java/com/stop/util/Context.kt b/presentation/src/main/java/com/stop/util/Context.kt index 0f9ca74..14c1e0a 100644 --- a/presentation/src/main/java/com/stop/util/Context.kt +++ b/presentation/src/main/java/com/stop/util/Context.kt @@ -39,7 +39,9 @@ fun Context.getAlarmDefaultNotification( createDefaultNotificationChannel(applicationContext, id, name) - return NotificationCompat.Builder(applicationContext, id).setContentTitle(title).setContentText(content).setSmallIcon(R.mipmap.ic_bus).setOngoing(true).setContentIntent(pendingIntent).build() + return NotificationCompat.Builder(applicationContext, id).setContentTitle(title) + .setContentText(content).setSmallIcon(R.mipmap.ic_bus).setOngoing(true) + .setContentIntent(pendingIntent).build() } fun Context.getAlarmHighNotification( @@ -51,13 +53,17 @@ fun Context.getAlarmHighNotification( createHighNotificationChannel(applicationContext, id, name) - return NotificationCompat.Builder(applicationContext, id).setContentTitle(title).setContentText(content).setSmallIcon(R.mipmap.ic_bus).setAutoCancel(true) - .setPriority(NotificationCompat.PRIORITY_HIGH).setCategory(NotificationCompat.CATEGORY_ALARM).setContentIntent(pendingIntent).setFullScreenIntent(pendingIntent, true).build() + return NotificationCompat.Builder(applicationContext, id).setContentTitle(title) + .setContentText(content).setSmallIcon(R.mipmap.ic_bus).setAutoCancel(true) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setCategory(NotificationCompat.CATEGORY_ALARM).setContentIntent(pendingIntent) + .setFullScreenIntent(pendingIntent, true).build() } private fun createDefaultNotificationChannel(context: Context, id: String, name: String) { if (isMoreThanOreo()) { - val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val importance = NotificationManager.IMPORTANCE_DEFAULT NotificationChannel( @@ -70,7 +76,8 @@ private fun createDefaultNotificationChannel(context: Context, id: String, name: private fun createHighNotificationChannel(context: Context, id: String, name: String) { if (isMoreThanOreo()) { - val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val importance = NotificationManager.IMPORTANCE_HIGH NotificationChannel( @@ -83,7 +90,8 @@ private fun createHighNotificationChannel(context: Context, id: String, name: St fun Context.getScreenSize(): Size { return if (isMoreThanRedVelVet()) { - val metrics: WindowMetrics = getSystemService(WindowManager::class.java).currentWindowMetrics + val metrics: WindowMetrics = + getSystemService(WindowManager::class.java).currentWindowMetrics Size(metrics.bounds.width(), metrics.bounds.height()) } else { val display = getSystemService(WindowManager::class.java).defaultDisplay diff --git a/presentation/src/main/java/com/stop/util/TimeConverter.kt b/presentation/src/main/java/com/stop/util/TimeConverter.kt index f6a3468..2324b61 100644 --- a/presentation/src/main/java/com/stop/util/TimeConverter.kt +++ b/presentation/src/main/java/com/stop/util/TimeConverter.kt @@ -2,7 +2,9 @@ package com.stop.util import java.text.ParseException import java.text.SimpleDateFormat -import java.util.* +import java.util.Calendar +import java.util.Date +import java.util.Locale fun makeFullTime(time: String): Calendar { val currentTime = System.currentTimeMillis()