1 /**
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * ```
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  * ```
10  *
11  * Unless required by applicable law or agreed to in writing, software distributed under the License
12  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13  * or implied. See the License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.android.healthconnect.testapps.toolbox.ui
17 
18 import android.app.Activity
19 import android.content.Intent
20 import android.health.connect.HealthConnectManager
21 import android.health.connect.HealthConnectManager.EXTRA_EXERCISE_ROUTE
22 import android.health.connect.datatypes.ExerciseRoute
23 import android.health.connect.datatypes.ExerciseSessionRecord
24 import android.os.Bundle
25 import android.util.Log
26 import android.view.LayoutInflater
27 import android.view.View
28 import android.view.ViewGroup
29 import android.widget.Toast
30 import androidx.appcompat.app.AlertDialog
31 import androidx.fragment.app.Fragment
32 import androidx.fragment.app.viewModels
33 import androidx.recyclerview.widget.RecyclerView
34 import com.android.healthconnect.testapps.toolbox.R
35 import com.android.healthconnect.testapps.toolbox.adapters.TextViewListAdapter
36 import com.android.healthconnect.testapps.toolbox.adapters.TextViewListViewHolder
37 import com.android.healthconnect.testapps.toolbox.viewmodels.RouteRequestViewModel
38 
39 class RouteRequestFragment : Fragment() {
40 
41     private val TAG = RouteRequestFragment::class.java.simpleName
42     private val ROUTE_REQUEST_CODE = 1
43     private val routeRequestViewModel: RouteRequestViewModel by viewModels()
44 
45     override fun onCreateView(
46         inflater: LayoutInflater,
47         container: ViewGroup?,
48         savedInstanceState: Bundle?,
49     ): View {
50         return inflater.inflate(R.layout.fragment_route_request, container, false)
51     }
52 
53     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
54         routeRequestViewModel.readExerciseSessionRecords(requireContext())
55 
56         routeRequestViewModel.exerciseSessionRecords.observe(viewLifecycleOwner) {
57             result: Result<List<ExerciseSessionRecord>> ->
58             result.onFailure {
59                 Log.e(TAG, "Read records error", it)
60                 Toast.makeText(
61                         requireContext(),
62                         "Read records error: ${it.javaClass.simpleName}",
63                         Toast.LENGTH_SHORT)
64                     .show()
65             }
66 
67             result.onSuccess {
68                 val recyclerView: RecyclerView = view.findViewById(R.id.list_recycler_view)
69                 recyclerView.adapter =
70                     TextViewListAdapter(it) { viewHolder: TextViewListViewHolder, position: Int ->
71                         onBindViewHolderCallback(viewHolder, it[position])
72                     }
73             }
74         }
75     }
76 
77     private fun onBindViewHolderCallback(
78         viewHolder: TextViewListViewHolder,
79         record: ExerciseSessionRecord
80     ) {
81         val textView = viewHolder.textView
82         textView.text =
83             "ExerciseSession\n" +
84                 "Title: ${record.title}\n" +
85                 "Start time: ${record.startTime}\n" +
86                 "End time: ${record.endTime}\n" +
87                 "Package: ${record.metadata.dataOrigin.packageName}\n" +
88                 "Route: ${record.route != null}\n" +
89                 "Has route: ${record.hasRoute()}\n" +
90                 "Id: ${record.metadata.id}"
91 
92         textView.setOnClickListener {
93             val intent =
94                 Intent(HealthConnectManager.ACTION_REQUEST_EXERCISE_ROUTE).apply {
95                     putExtra(HealthConnectManager.EXTRA_SESSION_ID, record.metadata.id)
96                 }
97             startActivityForResult(intent, ROUTE_REQUEST_CODE)
98         }
99     }
100 
101     // public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
102     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
103         if (requestCode != ROUTE_REQUEST_CODE) {
104             return
105         }
106 
107         if (resultCode != Activity.RESULT_OK) {
108             Toast.makeText(requireContext(), "Route request cancelled", Toast.LENGTH_SHORT).show()
109             return
110         }
111 
112         val route = data?.getParcelableExtra(EXTRA_EXERCISE_ROUTE, ExerciseRoute::class.java)
113 
114         if (route == null || route.routeLocations.isEmpty()) {
115             Toast.makeText(requireContext(), "Null or empty route", Toast.LENGTH_SHORT).show()
116             return
117         }
118 
119         val message =
120             route!!
121                 .routeLocations
122                 .map {
123                     "Time: ${it.time}\n" +
124                         "Latitude: ${it.latitude}\n" +
125                         "Longitude: ${it.longitude}\n" +
126                         "Altitude: ${it.altitude}\n" +
127                         "H accuracy: ${it.horizontalAccuracy}\n" +
128                         "V accuracy: ${it.verticalAccuracy}\n"
129                 }
130                 .joinToString("\n")
131 
132         val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
133         builder.setTitle("Exercise route")
134         builder.setMessage(message)
135         builder.setPositiveButton(android.R.string.ok) { _, _ -> }
136 
137         val alertDialog: AlertDialog = builder.create()
138         alertDialog.show()
139     }
140 }
141