Skip to main content

Install on Android

This guide walks through adding AFCore to your Android project, configuring required dependencies, and preparing for Play Store review.


Minimum Requirements

RequirementVersion
Android StudioKoala (2024.1) or later
JDK17
Gradle (AGP)9.0.0 or later
Kotlin2.3.10 or later
minSdk26 (Android 8.0)
compileSdk / targetSdk36
Google Play ServicesRequired (Location, Activity Recognition)

Add the SDK (GitHub Packages)

AFCore is distributed via GitHub Packages. You need a GitHub Personal Access Token (classic) with the read:packages scope.

Step 1 -- Store credentials securely

Create a github.properties file in your project root (add it to .gitignore):

gpr.usr=YOUR_GITHUB_USERNAME
gpr.key=YOUR_PERSONAL_ACCESS_TOKEN

Step 2 -- Add the repository

settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/AdvantaHealth/AFCore")
credentials {
username = providers.gradleProperty("gpr.usr").orNull
?: System.getenv("GPR_USER")
password = providers.gradleProperty("gpr.key").orNull
?: System.getenv("GPR_API_KEY")
}
}
google()
mavenCentral()
}
}

Step 3 -- Add the dependency

app/build.gradle.kts
dependencies {
implementation("com.advantahealth:core-android:1.7.1")
}

In CI/CD environments, use environment variables (GPR_USER, GPR_API_KEY) instead of the properties file. Never commit tokens to version control.


Initialize AFCore

Initialize AFCore once in your Application.onCreate() or your dependency injection entry point:

import android.app.Application
import android.util.Log
import com.advantahealth.api.AFCore
import com.advantahealth.api.AFCoreConfig
import com.advantahealth.api.AFLogLevel

class App : Application() {
override fun onCreate() {
super.onCreate()

val config = AFCoreConfig.builder()
.baseUrl("https://api.example.com")
.clientId("your-client-id")
.clientSecret("your-client-secret")
.enableLogging(true)
.logLevel(AFLogLevel.VERBOSE)
.build()

val initialized = AFCore.initialize(config)
if (initialized) {
Log.d("AFCore", "Initialization succeeded")
} else {
Log.e("AFCore", "Initialization failed")
}
}
}

Replace baseUrl, clientId, and clientSecret with the values provided by your Account Manager. Use the QA URL during development and switch to Production before release.


Geofencing and Proximity (Background Location)

If your app uses geofencing or Bluetooth beacon proximity, you must declare and request background location access.

Manifest permissions

AFCore's library manifest already declares the required permissions and components. They merge into your app automatically. This includes:

  • Location and background location permissions
  • The AFGeofenceBootReceiver (re-registers geofences after device reboot)
  • The AFGeofenceBroadcastReceiver (processes geofence transition events)
  • WorkManager configuration for periodic health data sync

If you want to remove a permission your app does not need, use the tools:node="remove" attribute:

AndroidManifest.xml
<!-- Example: remove BLE permission if your app does not use beacon proximity -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
tools:node="remove" />

Background Survival

AFCore automatically handles app restarts and device reboots for both geofencing and step sync:

  • Geofencing: A boot receiver re-registers geofences with Google Play Services after reboot. A broadcast receiver processes geofence transitions even when the app is not running.
  • Step sync: WorkManager persists scheduled work across reboots. The periodic sync worker restarts automatically after reboot.
  • AFCore re-initialization: Both components use a persisted boot config to re-initialize AFCore when the app is launched in the background by the system. No additional setup is required from the consumer app.

Play Console -- Data Safety

  1. Declare background location use in App Content > Sensitive Permissions.
  2. Provide a clear in-app disclosure explaining why background location is needed.
  3. Request background location only after the user opts into geofencing features.
  4. Test on real devices -- OEM battery optimizations can affect geofence reliability.

Health Tracking (Health Connect)

AFCore bundles the Health Connect client library and declares the required permissions. Your app must declare intent filters so Health Connect can route permission screens:

AndroidManifest.xml
<application>
<!-- Required by Health Connect for permission rationale and usage screens -->
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
<category android:name="android.intent.category.HEALTH_PERMISSIONS" />
</intent-filter>
</activity>
</application>

Play Console -- Data Safety

  • Declare Health data (fitness) as Collected (read-only) and Not shared (unless your app explicitly shares it).
  • Link your Privacy Policy and explain how fitness data is used and retained.

Push Notifications

Your app handles its own Firebase / APNs setup and obtains device tokens independently. Share the token with AFCore so the backend can deliver push notifications.

// Register / refresh token
val fcmToken = FirebaseMessaging.getInstance().token.await()
val deviceId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
AFCore.messaging().updateToken(fcmToken, deviceId)

// On logout
AFCore.messaging().deleteToken(deviceId)

Refer to the AFCore API Reference for details on messaging().updateToken() and messaging().deleteToken().