mirror of
https://github.com/cagnulein/qdomyos-zwift.git
synced 2026-02-18 00:17:41 +01:00
Compare commits
10 Commits
Computrain
...
Google-And
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e346809270 | ||
|
|
fc68dec7ba | ||
|
|
4acb5029b6 | ||
|
|
71b4894e2d | ||
|
|
ac874bd682 | ||
|
|
8143ca110d | ||
|
|
e2d62099c3 | ||
|
|
d028fa4aa4 | ||
|
|
861e01c3f8 | ||
|
|
46d259994b |
@@ -112,14 +112,51 @@
|
||||
|
||||
<activity android:name="org.cagnulen.qdomyoszwift.MyActivity" />
|
||||
|
||||
<!-- =============================================
|
||||
Health Connect
|
||||
=============================================
|
||||
|
||||
For supported versions through Android 13, create an activity to show the rationale
|
||||
of Health Connect permissions once users click the privacy policy link. -->
|
||||
<activity
|
||||
android:name=".PermissionsRationaleActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- For versions starting Android 14, create an activity alias to show the rationale
|
||||
of Health Connect permissions once users click the privacy policy link. -->
|
||||
<activity-alias
|
||||
android:name="ViewPermissionUsageActivity"
|
||||
android:exported="true"
|
||||
android:targetActivity=".PermissionsRationaleActivity"
|
||||
android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
|
||||
<category android:name="android.intent.category.HEALTH_PERMISSIONS" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
<!-- =============================================
|
||||
End Health Connect
|
||||
============================================= -->
|
||||
|
||||
|
||||
<receiver android:name=".MediaButtonReceiver" android:exported="true" android:permission="android.permission.MODIFY_AUDIO_SETTINGS">
|
||||
<intent-filter>
|
||||
<action android:name="android.media.VOLUME_CHANGED_ACTION" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
|
||||
</application>
|
||||
|
||||
<!-- Check if Health Connect is installed -->
|
||||
<queries>
|
||||
<package android:name="com.google.android.apps.healthdata" />
|
||||
</queries>
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
@@ -140,4 +177,21 @@
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_HEART_RATE"/>
|
||||
<uses-permission android:name="android.permission.health.READ_STEPS"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_STEPS"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_ACTIVE_CALORIES_BURNED"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_EXERCISE"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_DISTANCE"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_ELEVATION_GAINED"/>
|
||||
<uses-permission android:name="android.permission.health.READ_HEIGHT"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_POWER"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_SPEED"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_TOTAL_CALORIES_BURNED"/>
|
||||
<uses-permission android:name="android.permission.health.READ_WEIGHT"/>
|
||||
<uses-permission android:name="android.permission.health.WRITE_WEIGHT"/>
|
||||
<uses-permission android:name="android.permission.health.READ_VO2_MAX"/>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -52,6 +52,11 @@ dependencies {
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
implementation files('libs/usb-serial-for-android-3.8.1.aar')
|
||||
androidTestImplementation "com.android.support:support-annotations:28.0.0"
|
||||
|
||||
implementation "androidx.health.connect:connect-client:1.1.0-alpha03"
|
||||
implementation "androidx.activity:activity:1.2.0"
|
||||
implementation 'org.jetbrains.kotlin:kotlin-reflect'
|
||||
|
||||
implementation 'com.google.android.gms:play-services-wearable:+'
|
||||
|
||||
implementation 'com.jakewharton.timber:timber:5.0.1'
|
||||
@@ -128,7 +133,8 @@ android {
|
||||
defaultConfig {
|
||||
resConfig "en"
|
||||
compileSdkVersion 33
|
||||
minSdkVersion = 21
|
||||
|
||||
minSdkVersion = 26
|
||||
targetSdkVersion = 34
|
||||
}
|
||||
|
||||
|
||||
127
src/android/src/HealthConnect.java
Normal file
127
src/android/src/HealthConnect.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package org.cagnulen.qdomyoszwift;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
import android.os.Looper;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.IntentFilter;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.health.connect.client.HealthConnectClient;
|
||||
import androidx.health.connect.client.PermissionController;
|
||||
import androidx.health.connect.client.permission.HealthPermission;
|
||||
import androidx.health.connect.client.records.*;
|
||||
import androidx.health.connect.client.request.*;
|
||||
import androidx.health.connect.client.time.*;
|
||||
import kotlin.jvm.JvmClassMappingKt;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class HealthConnect {
|
||||
|
||||
private static final Set<HealthPermission> PERMISSIONS = new HashSet<>();
|
||||
private ActivityResultLauncher<Set<HealthPermission>> requestPermissions;
|
||||
private static HealthConnectClient healthConnectClient;
|
||||
private static final int PERMISSION_REQUEST_CODE = 123; // Define your request code
|
||||
|
||||
private static void checkAndRun(Context context) {
|
||||
int availabilityStatus = HealthConnectClient.getSdkStatus(context, "com.google.android.apps.healthdata");
|
||||
if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
|
||||
return; // early return as there is no viable integration
|
||||
}
|
||||
if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
|
||||
String uriString = "market://details?id=com.google.android.apps.healthdata&url=healthconnect%3A%2F%2Fonboarding";
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setPackage("com.android.vending");
|
||||
intent.setData(Uri.parse(uriString));
|
||||
intent.putExtra("overlay", true);
|
||||
intent.putExtra("callerId", context.getPackageName());
|
||||
context.startActivity(intent);
|
||||
return;
|
||||
}
|
||||
|
||||
healthConnectClient = HealthConnectClient.getOrCreate(context);
|
||||
// Issue operations with healthConnectClient
|
||||
|
||||
PERMISSIONS.add(HealthPermission.getReadPermission(kotlin.jvm.JvmClassMappingKt.getKotlinClass(StepsRecord.class)));
|
||||
PERMISSIONS.add(HealthPermission.getWritePermission(kotlin.jvm.JvmClassMappingKt.getKotlinClass(StepsRecord.class)));
|
||||
PERMISSIONS.add(HealthPermission.getReadPermission(kotlin.jvm.JvmClassMappingKt.getKotlinClass(HeartRateRecord.class)));
|
||||
PERMISSIONS.add(HealthPermission.getWritePermission(kotlin.jvm.JvmClassMappingKt.getKotlinClass(HeartRateRecord.class)));
|
||||
|
||||
checkPermissionsAndRun(context);
|
||||
}
|
||||
|
||||
private void handlePermissionsResult(Boolean granted) {
|
||||
if (granted) {
|
||||
// Permissions successfully granted
|
||||
} else {
|
||||
// Lack of required permissions
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPermissionsAndRun(Context context) {
|
||||
permissionController = HealthConnectClient.getOrCreate(context).getPermissionController();
|
||||
Set<HealthPermission> granted = permissionController.getGrantedPermissions();
|
||||
if (granted.containsAll(PERMISSIONS)) {
|
||||
// Permissions already granted; proceed with inserting or reading data
|
||||
} else {
|
||||
Intent intent = permissionController.createPermissionRequestIntent(PERMISSIONS);
|
||||
startActivityForResult(intent, PERMISSION_REQUEST_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == PERMISSION_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
// Permissions successfully granted
|
||||
} else {
|
||||
// Lack of required permissions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void readStepsByTimeRange(HealthConnectClient healthConnectClient, Instant startTime, Instant endTime) {
|
||||
try {
|
||||
ReadRecordsRequest request = new ReadRecordsRequest(
|
||||
StepsRecord.class,
|
||||
new TimeRangeFilter.between(startTime, endTime)
|
||||
);
|
||||
ReadRecordsResponse response = healthConnectClient.readRecords(request);
|
||||
for (StepsRecord stepRecord : response.getRecords()) {
|
||||
// Process each step record
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Run error handling here.
|
||||
}
|
||||
}
|
||||
|
||||
public static void init(Context c) {
|
||||
checkAndRun(c);
|
||||
readStepsByTimeRange(healthConnectClient, Instant.now(), Instant.now());
|
||||
}
|
||||
}
|
||||
@@ -837,6 +837,7 @@ DISTFILES += \
|
||||
$$PWD/android/src/CSafeRowerUSBHID.java \
|
||||
$$PWD/android/src/ContentHelper.java \
|
||||
$$PWD/android/src/Garmin.java \
|
||||
$$PWD/android/src/HealthConnect.java \
|
||||
$$PWD/android/src/HidBridge.java \
|
||||
$$PWD/android/src/IQMessageReceiverWrapper.java \
|
||||
$$PWD/android/src/LocationHelper.java \
|
||||
|
||||
Reference in New Issue
Block a user