Skip to content
This repository was archived by the owner on Jul 2, 2025. It is now read-only.

Commit 34099ec

Browse files
1. Using view model to store the status of fragment.
Stopwatch will keep working when users switch to other App/Interface 2. Add permission request callback. The map view will be refreshed automatically after getting the Location permission
1 parent 8695acd commit 34099ec

File tree

4 files changed

+89
-15
lines changed

4 files changed

+89
-15
lines changed

android/canonical/app/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ dependencies {
3535
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
3636
implementation 'com.google.android.gms:play-services-maps:17.0.0'
3737
implementation 'com.google.android.gms:play-services-location:17.0.0'
38+
implementation "android.arch.lifecycle:extensions:1.1.1"
39+
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
3840
testImplementation 'junit:junit:4.12'
3941
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
4042
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

android/canonical/app/src/main/java/com/google/samples/quickstart/canonical/MainActivity.kt

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
package com.google.samples.quickstart.canonical
22

3+
import android.content.pm.PackageManager
34
import androidx.appcompat.app.AppCompatActivity
45
import android.os.Bundle
5-
import android.view.View
6-
import android.widget.Button
7-
import android.widget.Chronometer
8-
import android.widget.Toast
6+
import android.util.Log
97
import androidx.fragment.app.FragmentTransaction
108
import com.google.android.material.bottomnavigation.BottomNavigationView
11-
import org.jetbrains.annotations.Nullable
9+
import androidx.lifecycle.MutableLiveData
10+
import androidx.lifecycle.ViewModel
11+
12+
class StopwatchView : ViewModel(){
13+
14+
var pauseOffset = MutableLiveData<Long>(0L)
15+
var isWorking = MutableLiveData<Boolean>(false)
16+
var fragmentPauseStartTime = MutableLiveData<Long>(0L)
17+
18+
fun setPauseOffset(pause_offset_value:Long){
19+
pauseOffset.value = pause_offset_value
20+
}
21+
22+
fun setWorkingStatus(working_status:Boolean){
23+
isWorking.value = working_status
24+
}
25+
26+
fun setFragmentPauseStartTime(fragment_pause_start_time:Long){
27+
fragmentPauseStartTime.value = fragment_pause_start_time
28+
}
29+
}
1230

1331
class MainActivity : AppCompatActivity() {
1432

15-
lateinit var runFragment: RunFragment
16-
lateinit var mapsFragment: MapsFragment
17-
lateinit var meFragment: MeFragment
33+
private lateinit var runFragment: RunFragment
34+
private lateinit var mapsFragment: MapsFragment
35+
private lateinit var meFragment: MeFragment
36+
1837

1938
override fun onCreate(savedInstanceState: Bundle?) {
2039
super.onCreate(savedInstanceState)

android/canonical/app/src/main/java/com/google/samples/quickstart/canonical/MapsFragment.kt

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import android.location.Location
88
import androidx.fragment.app.Fragment
99

1010
import android.os.Bundle
11+
import android.util.Log
1112
import android.view.LayoutInflater
1213
import android.view.View
1314
import android.view.ViewGroup
1415
import androidx.core.app.ActivityCompat
16+
import androidx.core.content.ContextCompat.checkSelfPermission
1517
import androidx.fragment.app.FragmentTransaction
1618
import com.google.android.gms.location.FusedLocationProviderClient
1719
import com.google.android.gms.location.LocationServices
@@ -34,13 +36,30 @@ class MapsFragment : Fragment() {
3436
private const val LOCATION_PERMISSION_REQUEST_CODE = 1
3537
}
3638

39+
override fun onRequestPermissionsResult(requestCode: Int,
40+
permissions: Array<String>, grantResults: IntArray) {
41+
when (requestCode) {
42+
LOCATION_PERMISSION_REQUEST_CODE -> {
43+
// If request is cancelled, the result arrays are empty.
44+
if ((grantResults.isNotEmpty() &&
45+
grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
46+
setUpMap()
47+
} else {
48+
// Explain to the user that the feature is unavailable because
49+
// the features requires a permission that the user has denied.
50+
}
51+
return
52+
}
53+
else -> {
54+
// Ignore all other requests.
55+
}
56+
}
57+
}
58+
3759
private fun setUpMap() {
38-
if (ActivityCompat.checkSelfPermission(context as Activity,
60+
if (checkSelfPermission(context as Activity,
3961
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
40-
ActivityCompat.requestPermissions(context as Activity,
41-
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
42-
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
43-
mapFragment?.getMapAsync(callback)
62+
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
4463
return
4564
}
4665

@@ -54,7 +73,6 @@ class MapsFragment : Fragment() {
5473
map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f))
5574
map.addMarker(MarkerOptions().position(currentLatLng).title("My location"))
5675
map.moveCamera(CameraUpdateFactory.newLatLng(currentLatLng))
57-
println("****************** %f %f **************\n".format(location.latitude, location.longitude))
5876
}
5977
}
6078
}

android/canonical/app/src/main/java/com/google/samples/quickstart/canonical/RunFragment.kt

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ package com.google.samples.quickstart.canonical
22

33
import android.os.Bundle
44
import android.os.SystemClock
5+
import android.util.Log
56
import androidx.fragment.app.Fragment
67
import android.view.LayoutInflater
78
import android.view.View
89
import android.view.ViewGroup
910
import android.widget.Button
1011
import android.widget.Chronometer
12+
import androidx.lifecycle.ViewModelProviders
1113
import kotlinx.android.synthetic.main.fragment_run.*
12-
import org.jetbrains.annotations.Nullable
1314

1415
// TODO: Rename parameter arguments, choose names that match
1516
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
@@ -25,17 +26,24 @@ class RunFragment : Fragment() {
2526
// TODO: Rename and change types of parameters
2627
private var param1: String? = null
2728
private var param2: String? = null
29+
30+
private lateinit var stopwatchViewModel: StopwatchView
2831
private var pauseOffset = 0L
2932
private var isWorking = false
33+
private var fragmentPauseStartTime = 0L
3034

3135
private fun startStopTimer(runBtn: Button, chronometer : Chronometer) {
3236
isWorking = if (!isWorking) {
3337
chronometer.base = SystemClock.elapsedRealtime() - pauseOffset
3438
chronometer.start()
39+
chronometer.showContextMenu()
40+
stopwatchViewModel.setWorkingStatus(true)
3541
true
3642
} else {
3743
pauseOffset = SystemClock.elapsedRealtime() - chronometer.base
3844
chronometer.stop()
45+
stopwatchViewModel.setPauseOffset(SystemClock.elapsedRealtime() - chronometer.base)
46+
stopwatchViewModel.setWorkingStatus(false)
3947
false
4048
}
4149
runBtn.setText(if (!isWorking) R.string.start else R.string.stop)
@@ -47,6 +55,14 @@ class RunFragment : Fragment() {
4755
param1 = it.getString(ARG_PARAM1)
4856
param2 = it.getString(ARG_PARAM2)
4957
}
58+
59+
stopwatchViewModel = activity?.run {
60+
ViewModelProviders.of(this)[StopwatchView::class.java]
61+
} ?: throw Exception("Null Activity")
62+
63+
pauseOffset = stopwatchViewModel.pauseOffset.value!!
64+
isWorking = stopwatchViewModel.isWorking.value!!
65+
fragmentPauseStartTime = stopwatchViewModel.fragmentPauseStartTime.value!!
5066
}
5167

5268
override fun onCreateView(
@@ -88,5 +104,24 @@ class RunFragment : Fragment() {
88104

89105
}
90106

107+
override fun onResume() {
108+
super.onResume()
109+
if (isWorking) {
110+
chronometer?.base = fragmentPauseStartTime - pauseOffset
111+
chronometer?.start()
112+
} else {
113+
chronometer?.base = SystemClock.elapsedRealtime() - pauseOffset
114+
chronometer?.stop()
115+
}
116+
}
91117

118+
override fun onPause() {
119+
super.onPause()
120+
if (isWorking) {
121+
pauseOffset = SystemClock.elapsedRealtime() - chronometer.base
122+
fragmentPauseStartTime = SystemClock.elapsedRealtime()
123+
stopwatchViewModel.setPauseOffset(pauseOffset)
124+
stopwatchViewModel.setFragmentPauseStartTime(fragmentPauseStartTime)
125+
}
126+
}
92127
}

0 commit comments

Comments
 (0)