diff --git a/CHANGELOG.md b/CHANGELOG.md index 3baeb09..a3040d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 The changes documented here do not include those from the original repository. +## [2.1.2] + +- Fix: Request `READ_HEALTH_DATA_IN_BACKGROUND` permission for Android 15 when setting a background job (https://outsystemsrd.atlassian.net/browse/RMET-3574). + ## [2.1.1] ### 2024-05-22 diff --git a/hooks/androidCopyPreferencesPermissions.js b/hooks/androidCopyPreferencesPermissions.js index 9b0b363..e7f8cb8 100644 --- a/hooks/androidCopyPreferencesPermissions.js +++ b/hooks/androidCopyPreferencesPermissions.js @@ -276,6 +276,17 @@ function addBackgroundJobPermissionsToManifest(configParser, projectRoot, parser // Parse the XML string const manifestXmlDoc = parser.parseFromString(manifestXmlString, 'text/xml'); + const permissionsXmlFilePath = path.join(projectRoot, 'platforms/android/app/src/main/res/values/health_permissions.xml'); + const permissionsXmlString = fs.readFileSync(permissionsXmlFilePath, 'utf-8'); + + // Parse the XML string + const permissionsXmlDoc = parser.parseFromString(permissionsXmlString, 'text/xml'); + const arrayElement = permissionsXmlDoc.getElementsByTagName('array')[0]; + + // add permissions necessary on Android 15 (API 35) + addEntryToManifest(manifestXmlDoc, 'android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND') + addEntryToPermissionsXML(permissionsXmlDoc, arrayElement, 'android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND') + // add permissions to XML document addEntryToManifest(manifestXmlDoc, 'android.permission.POST_NOTIFICATIONS') addEntryToManifest(manifestXmlDoc, 'android.permission.ACTIVITY_RECOGNITION') @@ -285,12 +296,14 @@ function addBackgroundJobPermissionsToManifest(configParser, projectRoot, parser addEntryToManifest(manifestXmlDoc, 'android.permission.HIGH_SAMPLING_RATE_SENSORS') addEntryToManifest(manifestXmlDoc, 'android.permission.SCHEDULE_EXACT_ALARM') - // serialize the updated XML document back to string + // serialize the updated XML documents back to strings const serializer = new XMLSerializer(); const updatedManifestXmlString = serializer.serializeToString(manifestXmlDoc); + const updatedPermissionsXmlString = serializer.serializeToString(permissionsXmlDoc); - // write the updated XML string back to the same file + // write the updated XML strings back to the same files fs.writeFileSync(manifestFilePath, updatedManifestXmlString, 'utf-8'); + fs.writeFileSync(permissionsXmlFilePath, updatedPermissionsXmlString, 'utf-8'); } } diff --git a/package.json b/package.json index 24633c2..cce5d5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.outsystems.plugins.healthfitness", - "version": "2.1.1", + "version": "2.1.2", "description": "Health & Fitness cordova plugin for OutSystems applications.", "keywords": [ "ecosystem:cordova", diff --git a/plugin.xml b/plugin.xml index fdd9c80..48970f6 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,5 +1,5 @@ - + HealthFitness Health & Fitness cordova plugin for OutSystems applications. OutSystems Inc diff --git a/src/android/build.gradle b/src/android/build.gradle index a44fb07..4a7c453 100644 --- a/src/android/build.gradle +++ b/src/android/build.gradle @@ -25,7 +25,7 @@ dependencies{ implementation("com.github.outsystems:oscore-android:1.2.0@aar") implementation("com.github.outsystems:oscordova-android:2.0.1@aar") - implementation("com.github.outsystems:oshealthfitness-android:2.1.1@aar") + implementation("com.github.outsystems:oshealthfitness-android:2.1.2@aar") implementation("com.github.outsystems:osnotificationpermissions-android:0.0.4@aar") // activity diff --git a/src/android/com/outsystems/plugins/healthfitness/OSHealthFitness.kt b/src/android/com/outsystems/plugins/healthfitness/OSHealthFitness.kt index 9d787f0..14377dc 100755 --- a/src/android/com/outsystems/plugins/healthfitness/OSHealthFitness.kt +++ b/src/android/com/outsystems/plugins/healthfitness/OSHealthFitness.kt @@ -306,6 +306,19 @@ class OSHealthFitness : CordovaImplementation() { requestBackgroundJobPermissions() } + /** + * Requests permission to read health data in the background for API 35, + * or calls setBackgroundJobWithParameters otherwise + */ + private fun requestReadDataBackgroundPermission() { + if (SDK_INT >= 35) { + setAsActivityResultCallback() + healthConnectViewModel.requestReadDataBackgroundPermission(this.getActivity()) + } else { + setBackgroundJobWithParameters(backgroundParameters) + } + } + /** * Sets a background job by calling the setBackgroundJob method of the ViewModel */ @@ -389,6 +402,30 @@ class OSHealthFitness : CordovaImplementation() { override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { super.onActivityResult(requestCode, resultCode, intent) + + //check if result comes for requesting READ_HEALTH_DATA_IN_BACKGROUND permission + intent?.let { + if (intent.getBooleanExtra(Constants.EXTRA_CONTAINS_READ_DATA_BACKGROUND, false)) { + if (intent.getIntExtra( + Constants.EXTRA_RESULT_PERMISSION_KEY_GLOBAL, + Constants.EXTRA_RESULT_PERMISSION_DENIED + ) == Constants.EXTRA_RESULT_PERMISSION_GRANTED + ) { + setBackgroundJobWithParameters(backgroundParameters) + return + } + sendPluginResult( + null, + Pair( + HealthFitnessError.BACKGROUND_JOB_READ_DATA_PERMISSION_DENIED.code.toString(), + HealthFitnessError.BACKGROUND_JOB_READ_DATA_PERMISSION_DENIED.message + ) + ) + return + } + } + + // if result comes from requesting standard permissions healthConnectViewModel.handleActivityResult(requestCode, resultCode, intent, { sendPluginResult("success", null) @@ -442,7 +479,7 @@ class OSHealthFitness : CordovaImplementation() { return } } - setBackgroundJobWithParameters(backgroundParameters) + requestReadDataBackgroundPermission() } } }