xosski

Google maps api never get lost again

Dec 4th, 2024
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.97 KB | None | 0 0
  1. package ro.upt.sma.context
  2.  
  3. import android.Manifest.permission
  4. import android.app.PendingIntent
  5. import android.content.BroadcastReceiver
  6. import android.content.Context
  7. import android.content.Intent
  8. import android.content.IntentFilter
  9. import android.content.pm.PackageManager
  10. import android.os.Build
  11. import android.os.Bundle
  12. import android.widget.Toast
  13. import androidx.activity.compose.setContent
  14. import androidx.annotation.RequiresApi
  15. import androidx.annotation.StringRes
  16. import androidx.appcompat.app.AppCompatActivity
  17. import androidx.compose.foundation.layout.Column
  18. import androidx.compose.foundation.layout.Row
  19. import androidx.compose.foundation.layout.fillMaxSize
  20. import androidx.compose.foundation.layout.padding
  21. import androidx.compose.material.icons.Icons
  22. import androidx.compose.material.icons.filled.Favorite
  23. import androidx.compose.material3.Card
  24. import androidx.compose.material3.Icon
  25. import androidx.compose.material3.Text
  26. import androidx.compose.runtime.Composable
  27. import androidx.compose.runtime.LaunchedEffect
  28. import androidx.compose.runtime.mutableStateOf
  29. import androidx.compose.ui.Alignment
  30. import androidx.compose.ui.Modifier
  31. import androidx.compose.ui.graphics.Color
  32. import androidx.compose.ui.unit.dp
  33. import androidx.compose.ui.unit.sp
  34. import androidx.core.app.ActivityCompat
  35. import androidx.core.content.ContextCompat
  36. import com.google.android.gms.location.DetectedActivity
  37. import com.google.android.gms.location.LocationCallback
  38. import com.google.android.gms.location.LocationResult
  39. import com.google.android.gms.maps.CameraUpdateFactory
  40. import com.google.android.gms.maps.model.CameraPosition
  41. import com.google.android.gms.maps.model.LatLng
  42. import com.google.maps.android.compose.GoogleMap
  43. import com.google.maps.android.compose.Marker
  44. import com.google.maps.android.compose.MarkerState
  45. import com.google.maps.android.compose.rememberCameraPositionState
  46. import ro.upt.sma.context.activity.ActivityRecognitionHandler
  47. import ro.upt.sma.context.activity.ActivityRecognitionService
  48. import ro.upt.sma.context.location.LocationHandler
  49.  
  50. class ContextActivity : AppCompatActivity() {
  51.  
  52. private val latLngState = mutableStateOf(LatLng(27.986065, 86.922623))
  53. private val activityState = mutableStateOf("Not detected")
  54.  
  55. override fun onCreate(savedInstanceState: Bundle?) {
  56. super.onCreate(savedInstanceState)
  57.  
  58. this.locationHandler = LocationHandler(this)
  59. this.activityRecognitionHandler = ActivityRecognitionHandler(this)
  60.  
  61. setContent { UserContextScreen() }
  62. }
  63.  
  64. @Composable
  65. private fun UserContextScreen() {
  66. Column {
  67. Row(
  68. Modifier.weight(6f)
  69. ) {
  70. MapComposable()
  71. }
  72. Row(
  73. Modifier
  74. .weight(2f)
  75. .align(Alignment.CenterHorizontally)
  76. .padding(16.dp)
  77. ) {
  78. LocationComposable()
  79. }
  80. Row(
  81. Modifier
  82. .weight(2f)
  83. .align(Alignment.CenterHorizontally)
  84. ) {
  85. ActivityComposable()
  86. }
  87. }
  88. }
  89.  
  90. @Composable
  91. private fun MapComposable() {
  92. val cameraPositionState = rememberCameraPositionState {
  93. position = CameraPosition.fromLatLngZoom(latLngState.value, 10f)
  94. }
  95. LaunchedEffect(latLngState.value) {
  96. cameraPositionState.animate(
  97. update = CameraUpdateFactory.newCameraPosition(
  98. CameraPosition(latLngState.value, 15f, 0f, 0f)
  99. ),
  100. durationMs = 1000
  101. )
  102. }
  103. GoogleMap(
  104. modifier = Modifier.fillMaxSize(),
  105. cameraPositionState = cameraPositionState
  106. ) {
  107. // TODO 1: Create a marker and set its position from [latLngState].
  108. Marker(
  109. state = MarkerState(position = latLngState.value),
  110. title = "Current Location",
  111. snippet = "Lat: ${latLngState.value.latitude}, Lng: ${latLngState.value.longitude}"
  112. )
  113. }
  114. }
  115.  
  116. @Composable
  117. private fun LocationComposable() {
  118. Text(text = "Lat = ${latLngState.value.latitude}, Lng = ${latLngState.value.longitude}")
  119. }
  120.  
  121. @Composable
  122. private fun ActivityComposable() {
  123. Card(
  124. modifier = Modifier
  125. .fillMaxSize()
  126. .padding(16.dp)
  127. ) {
  128. Icon(
  129. imageVector = Icons.Default.Favorite,
  130. tint = Color.Red,
  131. contentDescription = "Activity Icon",
  132. modifier = Modifier
  133. .align(Alignment.CenterHorizontally)
  134. .padding(8.dp)
  135. )
  136. Text(
  137. text = activityState.value,
  138. fontSize = 24.sp,
  139. modifier = Modifier.align(Alignment.CenterHorizontally)
  140. )
  141. }
  142. }
  143.  
  144. @RequiresApi(Build.VERSION_CODES.TIRAMISU)
  145. override fun onResume() {
  146. super.onResume()
  147.  
  148. if (!isLocationPermissionGranted) {
  149. ActivityCompat.requestPermissions(
  150. this,
  151. arrayOf(permission.ACCESS_FINE_LOCATION),
  152. LOCATION_PERMISSION_REQUEST_ID
  153. )
  154. }
  155.  
  156. if (!isActivityPermissionGranted) {
  157. ActivityCompat.requestPermissions(
  158. this,
  159. arrayOf(permission.ACTIVITY_RECOGNITION),
  160. ACTIVITY_PERMISSION_REQUEST_ID
  161. )
  162. }
  163.  
  164. setupLocation()
  165.  
  166. // TODO 5: Uncomment the line below.
  167. setupActivityRecognition()
  168. }
  169.  
  170. override fun onPause() {
  171. super.onPause()
  172.  
  173. if (locationCallback != null) {
  174. locationHandler.unregisterLocationListener(locationCallback!!)
  175. }
  176. if (activityPendingIntent != null) {
  177. activityRecognitionHandler.unregisterPendingIntent(activityPendingIntent!!)
  178. }
  179. if (activityRecognitionReceiver != null) {
  180. unregisterReceiver(activityRecognitionReceiver)
  181. }
  182. }
  183.  
  184. override fun onRequestPermissionsResult(
  185. requestCode: Int,
  186. permissions: Array<String>,
  187. grantResults: IntArray
  188. ) {
  189. super.onRequestPermissionsResult(requestCode, permissions, grantResults)
  190.  
  191. when (requestCode) {
  192. LOCATION_PERMISSION_REQUEST_ID -> {
  193. checkAndShowToast(grantResults, R.string.toast_location_permission)
  194. }
  195.  
  196. ACTIVITY_PERMISSION_REQUEST_ID -> {
  197. checkAndShowToast(grantResults, R.string.toast_activity_permission)
  198. }
  199. }
  200. }
  201.  
  202. private fun checkAndShowToast(grantResults: IntArray, @StringRes toastResId: Int) {
  203. if (grantResults.isNotEmpty() && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
  204. Toast.makeText(this, toastResId, Toast.LENGTH_SHORT)
  205. .show()
  206. }
  207. }
  208.  
  209.  
  210. private fun setupLocation() {
  211. this.locationCallback = object : LocationCallback() {
  212. override fun onLocationResult(locationResult: LocationResult) {
  213. locationResult.lastLocation?.let {
  214. latLngState.value = LatLng(it.latitude, it.longitude)
  215. }
  216. }
  217. }
  218. locationHandler.registerLocationListener(locationCallback!!)
  219. }
  220.  
  221. @RequiresApi(Build.VERSION_CODES.TIRAMISU)
  222. private fun setupActivityRecognition() {
  223. this.activityPendingIntent = activityRecognitionHandler.registerPendingIntent()
  224.  
  225. this.activityRecognitionReceiver = object : BroadcastReceiver() {
  226. override fun onReceive(context: Context, intent: Intent) {
  227. // TODO 6: Extract activity type from intent extras and use it to invoke [updateActivityCard].
  228. // Take a close look at [ActivityRecognitionService] to see how intent extras are formed.
  229. updateActivityCard(intent.getIntExtra(ActivityRecognitionService.ACTIVITY_EXTRA, DetectedActivity.UNKNOWN))
  230. }
  231. }
  232.  
  233. // TODO 7: Register the created receiver only for ActivityRecognitionService.INTENT_ACTION.
  234. registerReceiver(activityRecognitionReceiver, IntentFilter(ActivityRecognitionService.INTENT_ACTION), RECEIVER_NOT_EXPORTED)
  235. }
  236.  
  237. private fun updateActivityCard(activityType: Int) {
  238. val activityResId: Int = when (activityType) {
  239. DetectedActivity.IN_VEHICLE -> R.string.activity_in_vehicle
  240. DetectedActivity.ON_BICYCLE -> R.string.activity_on_bicycle
  241. DetectedActivity.ON_FOOT -> R.string.activity_on_foot
  242. DetectedActivity.RUNNING -> R.string.activity_running
  243. DetectedActivity.WALKING -> R.string.activity_walking
  244. DetectedActivity.TILTING -> R.string.activity_tilting
  245. DetectedActivity.STILL -> R.string.activity_still
  246. else -> R.string.activity_unknown
  247. }
  248.  
  249. activityState.value = getString(activityResId)
  250. }
  251.  
  252. private lateinit var locationHandler: LocationHandler
  253. private lateinit var activityRecognitionHandler: ActivityRecognitionHandler
  254. private var locationCallback: LocationCallback? = null
  255. private var activityPendingIntent: PendingIntent? = null
  256. private var activityRecognitionReceiver: BroadcastReceiver? = null
  257.  
  258. private val isLocationPermissionGranted: Boolean
  259. get() = ContextCompat.checkSelfPermission(
  260. this,
  261. permission.ACCESS_FINE_LOCATION
  262. ) == PackageManager.PERMISSION_GRANTED
  263.  
  264. private val isActivityPermissionGranted: Boolean
  265. get() = ContextCompat.checkSelfPermission(
  266. this,
  267. permission.ACTIVITY_RECOGNITION
  268. ) == PackageManager.PERMISSION_GRANTED
  269.  
  270. companion object {
  271. private const val LOCATION_PERMISSION_REQUEST_ID = 111
  272. private const val ACTIVITY_PERMISSION_REQUEST_ID = 113
  273. }
  274.  
  275. }
  276.  
Add Comment
Please, Sign In to add comment