Google Fit Data - android

Hi guys I have a problem using the Google Fit Api. I only receive activity data in specific situations.
I'm using the RxFit library (but I had the same behaviour using the default implementation). When I try this on my own phone (Nexus 5X) with my own account it works perfectly fine. If I try a different account on my phone I receive a success response, but no actual activity data. Same goes for other device and other account. And with my own account on the other device it does not work either. The same behaviour occurs when using the emulator.
My implementation:
fun requestActivities(): Single<DataReadResult> {
val fit = RxFit(context, arrayOf(Fitness.HISTORY_API), arrayOf(Scope(Scopes.FITNESS_ACTIVITY_READ)))
val dataReadRequest = buildRequest(getStartEndTime())
return fit.history().read(dataReadRequest).doOnSuccess { storeDatapoints(it) }
}
private fun storeDatapoints(data: DataReadResult) {
val idlist = activityRepository.all().map { it.activityId }
val activities = data.buckets
.flatMap { it.dataSets }
.flatMap { it.dataPoints }
.filter { point ->
//https://developers.google.com/fit/rest/v1/reference/activity-types
val activity = point.getValue(Field.FIELD_ACTIVITY).asInt()
return#filter activity != 0 && activity != 3 //&& !(109..112).contains(activity)
}
.map { point ->
PersistentExerciseActivity(
activityId = point.timestampNanos.toString(),
date = Instant(point.getTimestamp(TimeUnit.MILLISECONDS)).toDateTime().toLocalDateTime(),
duration = point.getValue(Field.FIELD_DURATION).asInt() / 1000 / 60,
activity = point.getValue(Field.FIELD_ACTIVITY).asActivity(),
apiId = null
)
}
.filter { !idlist.contains(it.activityId) }
activityRepository.store(activities)
}
private fun getStartEndTime(): Pair<Long, Long> {
val cal = Calendar.getInstance()
val now = Date()
cal.time = now
cal.set(Calendar.HOUR_OF_DAY, 0)
cal.set(Calendar.MINUTE, 0)
cal.set(Calendar.MILLISECOND, 0)
cal.set(Calendar.SECOND, 0)
val endTime = cal.timeInMillis
cal.add(Calendar.WEEK_OF_YEAR, -1)
val startTime = cal.timeInMillis
return Pair(startTime, endTime)
}
private fun buildRequest(startEndTime: Pair<Long, Long>): DataReadRequest {
return DataReadRequest.Builder()
.aggregate(DataType.TYPE_ACTIVITY_SEGMENT, DataType.AGGREGATE_ACTIVITY_SUMMARY)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startEndTime.first, startEndTime.second, TimeUnit.MILLISECONDS)
.enableServerQueries()
.build()
}
Does anyone have some ideas what would be causing this?
Kind regards,
Bryan

Related

Get app usage from yesterday with UsageStatsManager

I tried to get the app usage from previous day 0 o'clock to today 0 o'clock.
Here is my Code:
val midnight = LocalTime.MIDNIGHT
val today = LocalDate.now()
val todayMidnight = LocalDateTime.of(today, midnight)
val todayMidnightMillis = toMillis(todayMidnight)
val yesterdayMidnightMillis = toMillis(todayMidnight.minusDays(1))
val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
val queryUsageStatsMap = usageStatsManager.queryAndAggregateUsageStats(yesterdayMidnightMillis, todayMidnightMillis)
val appInfoMap = getNonSystemAppsList()
for (packageName in appInfoMap) {
val usageStats = queryUsageStatsMap.get(packageName.key)
if (usageStats != null) {
if (usageStats.totalTimeVisible > 0) {
val name = usageStats.packageName
val hours = TimeUnit.MILLISECONDS.toHours(usageStats.totalTimeVisible) % 24
val minutes = TimeUnit.MILLISECONDS.toMinutes(usageStats.totalTimeVisible) % 60
val seconds = TimeUnit.MILLISECONDS.toSeconds(usageStats.totalTimeVisible) % 60
//insert into database
}
}
}
private fun toMillis(dateTime: LocalDateTime): Long {
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
}
For example:
yesterdayMidnightMillis = 1673996400000 (18.01.2023-00:00)
todayMidnightMillis = 1674082800000 (19.01.2023-00:00)
For example, when I call this method(19.01.2023-15:00), the method gives me an app usage of 10 min. If I wait a minute and call the method again, the method gives me an app usage of 11 min.
Since I am not in the specified time interval during this time, the app usage must not increase.

I want weekly Sleep data from google fit

I am not getting weekly data from google fit (Yes, There is data in google fit which I have track using watch), but Yes I am getting today's date data.
I am attaching code snippet.
Start date = "2022-09-13T00:00:00Z"
End date = "2022-09-20T23:59:59Z"
private fun readSleepSessions(startTime : Long , endTime : Long) {
val client = Fitness.getSessionsClient(requireContext(), getGoogleAccount())
val sessionReadRequest = SessionReadRequest.Builder()
.read(DataType.TYPE_SLEEP_SEGMENT)
.includeSleepSessions()
.readSessionsFromAllApps()
.enableServerQueries()
.setTimeInterval(1663027200000, 1663718399000, TimeUnit.MILLISECONDS)
.build()
client.readSession(sessionReadRequest)
.addOnSuccessListener {
Log.d(TAG, "readSleepSessions: $sessionReadRequest")
dumpSleepSessions(it)
}
.addOnFailureListener {
Log.e("MainScreen", "Unable to read sleep sessions", it)
}
}
private fun dumpSleepSessions(response: SessionReadResponse) {
if (response.sessions.isNotEmpty()){
for (session in response.sessions) {
dumpSleepSession(session, response.getDataSet(session))
Log.d(TAG, "dumpSleepSessions: ${response.sessions}")
}
}else{
Log.d(TAG, "dumpSleepSessionsResponse: ${response.status}")
}
}
private fun dumpSleepSession(session: Session, dataSets: List<DataSet>) {
dumpSleepSessionMetadata(session)
dumpSleepDataSets(dataSets)
}
private fun dumpSleepDataSets(dataSets: List<DataSet>) {
for (dataSet in dataSets) {
for (dataPoint in dataSet.dataPoints) {
val sleepStageOrdinal = dataPoint.getValue(Field.FIELD_SLEEP_SEGMENT_TYPE).asInt()
val sleepStage = sleepTargetName[sleepStageOrdinal]
val durationMillis =
dataPoint.getEndTime(TimeUnit.MILLISECONDS) - dataPoint.getStartTime(TimeUnit.MILLISECONDS)
val duration = TimeUnit.MILLISECONDS.toMinutes(durationMillis)
Log.d(TAG, "\t$sleepStage: $duration (minutes)")
}
}

Adding Retrofit callback to unit test

I am trying to to a fairly simple unit test with mockito but having some trouble with the callback. I have been exploring several alternatives and a few seem good including co-routines and the do answer methods with mockito. I have not been able to figure out a good solution yet, any ideas ?
Here is my test ;
//Test for add 5 minutes
#Test
public void testWithArgumentWithDummyReturnObject() throws ParseException {
ParkingMeter testZone = new ParkingMeter();
testZone.setZoneId("21788");
testZone.setMeterName("Train Lot");
Date startDate = dateFormat.parse("09/10/2018 1:00 PM");
Date endDate = dateFormat.parse("09/10/2018 1:05 PM");
Date expectedOutputDate = dateFormat.parse("09/10/2018 1:05 PM");
CurrentSessionsResponse fakeResponse = new CurrentSessionsResponse();
CurrentSession fakeSession = new CurrentSession("fake","","");
fakeSession.zone = "Fake 1";
ArrayList<CurrentSession> sessionlist = new ArrayList<>();
sessionlist.add(fakeSession);
fakeResponse.parkingSessions = sessionlist;
MockRepository mockRepo = mock(MockRepository.class);
doReturn(fakeResponse).when(mockRepo).getCurrentSessions();
ExtendedVariableRateUtil variableRateUtil = new ExtendedVariableRateUtil();
variableRateUtil.init(testZone,"", 360, mockRepo);
variableRateUtil.setTime(5);
assertThat(variableRateUtil.getDidJump(), is(false));
assertThat(variableRateUtil.getCurrentCustomerTime(), is(expectedOutputDate));
}
Here is the relevant method in the class that is under test:
fun init(zone: ParkingMeter, plateNumber: String, extendedVariableRateMaxDayMinutes: Int, repository: ParkSmarterRepository) {
this.selectedZone = zone
this.plateNumber = plateNumber
this.extendedVariableRateMaxDayMinutes = extendedVariableRateMaxDayMinutes
if (selectedZone.maxTime < extendedVariableRateMaxDayMinutes * 24 * 60) {
//extendedVariableRateMaxDayJump = selectedZone.maxTime!
}
repository.getCurrentSessions { list, message ->
if (list?.size!! > 0) {
list.forEach {
if (it.zoneID == selectedZone.ZoneId && it.vehicle == plateNumber) {
isNewSession = false
var startDate = it.startTime
var endDate = it.endTime
} else {
isNewSession = true
}
}
}
setCurrentCustomerTime()
}
}
The callback function from retrofit:
fun getCurrentSessions(callback: (currentSessions: List<CurrentSession>?, message: String?) -> Unit) {
val call = ParkSmarter.apiInterface.getCurrentSessions()
call.enqueue(object : Callback<CurrentSessionsResponse> {
override fun onResponse(call: Call<CurrentSessionsResponse>, responseParkSmarter: Response<CurrentSessionsResponse>?) {
try {
callback(responseParkSmarter?.body()?.parkingSessions, responseParkSmarter?.body()?.psResponse?.Message)
} catch (ex: Exception) {
ex.printStackTrace()
}
}
override fun onFailure(call: Call<CurrentSessionsResponse>, t: Throwable?) {
callback(null, "Network Error")
}
})
}
and the retrofit call
#Headers(HEADERS)
#GET("/api/ParkingSession")
Call<CurrentSessionsResponse> getCurrentSessions();

Google Fit Api Android getting daily steps by hour and total time of exercise

I am currently working on an android project, which has to collect daily info from google fit api. I have searched a lot, but I have not found answers for 2 questions:
How to get steps bu hours with array. For example from 1pm to 2pm I have walked 100 steps, from 2pm to 3pm 200 steps.
How to get the total amount of time that the user exercised that day.
Thank you very much in advance)
For your first part of point.
If you form a data read request with proper segmented start and end time alongside bucket and aggregation functionality you can retrieve data buckets of each hour.
Below is the code that I am using to retrieve hourly data for any given start and end date.
fun getReadDataRequestBuilderAggregated(startDate: Date, endDate: Date): DataReadRequest? {
val cal = Calendar.getInstance()
cal.time = startDate.setDayStartTime()
var startTime = cal.timeInMillis
cal.time = endDate.setDayEndTime()
var endTime = cal.timeInMillis
return if (startTime>endTime) {
null
} else {
return DataReadRequest.Builder()
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
.bucketByTime(1, TimeUnit.HOURS)
.enableServerQueries()
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS).build()
}
}
private fun Date.setDayEndTime(): Date {
val currentTime = Calendar.getInstance().apply {
time = this#setDayEndTime
}
currentTime.set(Calendar.HOUR_OF_DAY, 23)
currentTime.set(Calendar.MINUTE, 59)
currentTime.set(Calendar.SECOND, 59)
return currentTime.time
}
private fun Date.setDayStartTime(): Date {
val currentTime = Calendar.getInstance().apply {
time = this#setDayStartTime
}
currentTime.set(Calendar.HOUR_OF_DAY, 0)
currentTime.set(Calendar.MINUTE, 0)
currentTime.set(Calendar.SECOND, 0)
currentTime.set(Calendar.MILLISECOND,0)
return currentTime.time
}

Why value of CALORIES_EXPENDED of API not equal value of Google Fit App?

This code get calo in day:
val cal = Calendar.getInstance()
cal.time = Date()
val endTime = cal.timeInMillis
cal.add(Calendar.DAY_OF_YEAR, -1)
val startTime = cal.timeInMillis
val readRequest = DataReadRequest.Builder()
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.bucketByTime(1, TimeUnit.DAYS)
.build()
Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
.readData(readRequest)
.addOnSuccessListener { dataReadResponse ->
// For the sake of the sample, we'll print the data so we can see what we just
// added. In general, logging fitness information should be avoided for privacy
// reasons.
printData(dataReadResponse)
}
.addOnFailureListener { e -> Log.e(TAG, "onFailure()", e) }
.addOnCompleteListener(OnCompleteListener {
Log.d(TAG, "onComplete()")
})
Value return:Field Calories Value= 11332.985.
But in Google Fit App display value = 6.164 Cal.
Why value of CALORIES_EXPENDED of API not equal value of Google Fit App?

Categories

Resources