פיתוח חוויות אימון באמצעות Health Connect

המדריך הזה תואם לגרסה 1.1.0 של Health Connect ואילך.

אם אתם רוצים לפתח חוויית אימון באפליקציה, אתם יכולים להשתמש ב-Health Connect כדי לבצע פעולות כמו:

  • כתיבה של נתוני אימונים
  • כתיבה של נתוני מסלולי האימון
  • כתיבה של מדדי אימון כמו דופק, מהירות ומרחק
  • קריאת נתוני אימון מאפליקציות אחרות

במדריך הזה מוסבר איך ליצור את התכונות האלה לאימונים, כולל סוגי נתונים, הפעלה ברקע, הרשאות, תהליכי עבודה מומלצים ושיטות מומלצות.

סקירה כללית: יצירת כלי מקיף למעקב אחרי אימוני כושר

כדי ליצור חוויית מעקב מקיפה אחרי אימונים באמצעות Health Connect, צריך לבצע את השלבים העיקריים הבאים:

  • להטמיע הרשאות בצורה נכונה בהתאם למדיניות בנושא הרשאות גישה לנתוני בריאות.
  • הקלטת סשנים באמצעות ExerciseSessionRecord.
  • כתיבת נתוני אימון באופן עקבי במהלך הסשן.
  • ניהול נכון של ההפעלה ברקע כדי לוודא שהנתונים נאספים באופן רציף.
  • קריאת נתוני אימון כדי לסכם ולנתח את האימון אחרי שהוא מסתיים.

תהליך העבודה הזה מאפשר יכולת פעולה הדדית עם אפליקציות אחרות של Health Connect ומאמת את הגישה לנתונים בשליטת המשתמש.

לפני שמתחילים

לפני שמטמיעים תכונות של אימונים:

מושגים מרכזיים

אפליקציית Health Connect מייצגת את נתוני האימון באמצעות כמה רכיבי ליבה. ExerciseSessionRecord משמש כרשומה המרכזית של אימון, ומכיל פרטים כמו זמני ההתחלה או הסיום וסוג האימון. במהלך סשן, אפשר לתעד סוגי נתונים שונים כמו HeartRateRecord או SpeedRecord. בפעילויות בחוץ, ExerciseRoute שומר את נתוני ה-GPS שמקושרים לסשן המתאים.

סשנים של פעילות גופנית

‫ExerciseSessionRecord הוא הרשומה המרכזית של נתוני האימון, שמייצגת אימון אחד. כל רשומה מכילה:

  • startTime
  • endTime
  • exerciseType
  • מטא-נתונים אופציונליים של הסשן (כותרת, הערות)

ExerciseSessionRecord יכול להכיל גם מסלולי אימון, הקפות וקטעים כחלק מהנתונים שלו. בנוסף, אפשר לתעד סוגי נתונים אחרים כמו HeartRateRecord או SpeedRecord במהלך סשן ולשייך אותם אליו.

סוגי נתונים משויכים

נתונים שמשויכים לאימונים מיוצגים על ידי סוגי רשומות נפרדים. סוגים נפוצים:

  • ‫HeartRateRecord: מייצג סדרה של מדידות דופק.
  • ‫SpeedRecord: מייצג סדרה של מדידות מהירות.
  • ‫DistanceRecord: מייצג את המרחק שעברתם בין קריאות.
  • ‫TotalCaloriesBurnedRecord: מייצג את סך הקלוריות שנשרפו בין הקריאות.
  • ‫ElevationGainedRecord: מייצג את סה"כ העלייה בין הקריאות.
  • ‫StepsCadenceRecord: מייצג את קצב הצעדים בין הקריאות.
  • ‫PowerRecord: מייצג את תפוקת הכוח בין קריאות, נפוץ בפעילויות כמו רכיבה על אופניים.

לרשימה המלאה של סוגי הנתונים, קראו את המאמר סוגי הנתונים ב-Health Connect.

מסלולי אימונים

אפשר לשייך מסלול לאימונים בחוץ באמצעות ExerciseRoute. מסלולים מורכבים מאובייקטים מסוג ExerciseRoute.Location ברצף, שכל אחד מהם מכיל:

  • קו רוחב וקו אורך
  • גובה (אופציונלי)
  • כיוון אופציונלי
  • מידע על הדיוק
  • חותמת זמן

קישור מסלולי סשנים

ExerciseRoute מכיל את נתוני המיקום הרציפים של אימון. הוא לא נחשב לרשומה עצמאית ב-Health Connect. במקום זאת, אתם מספקים נתוני ExerciseRoute כשאתם מוסיפים או מעדכנים ExerciseSessionRecord.

שיקולי פיתוח

אפליקציות למעקב אחרי אימונים צריכות לפעול לעיתים קרובות למשך פרקי זמן ארוכים, בדרך כלל ברקע כשהמסך כבוי. כשמפתחים תכונות לאימונים, חשוב להביא בחשבון את אופן הניהול של ההפעלה ברקע ולבקש את ההרשאות הנדרשות לנתוני האימון.

הרצה ברקע

אפליקציות לאימוני כושר פועלות בדרך כלל כשהמסך כבוי. במצב כזה, צריך להשתמש ב:

  • שירותים שפועלים בחזית לדגימת מיקום וחיישנים
  • ‫WorkManager לכתיבה מושהית או לסנכרון
  • אסטרטגיות של קיבוץ נתונים לכתיבת רשומות רגילות

כדי לשמור על רציפות, צריך להשתמש במזהה סשן עקבי בכל פעולות הכתיבה.

הרשאות

האפליקציה צריכה לבקש את ההרשאות הרלוונטיות של Health Connect לפני שהיא קוראת או כותבת נתוני אימון. הרשאות נפוצות לאימונים כוללות סשנים של אימונים, מסלולי אימונים ומדדים כמו דופק או מהירות. המצב הזה כולל את האפשרויות הבאות:

  • אימונים: הרשאות קריאה וכתיבה של ExerciseSessionRecord.
  • מסלולי אימון: הרשאות קריאה וכתיבה של נתונים באפליקציית ExerciseRoute.
  • דופק: הרשאות קריאה וכתיבה של HeartRateRecord.
  • מהירות: הרשאות קריאה וכתיבה של SpeedRecord.
  • מרחק: הרשאות קריאה וכתיבה של DistanceRecord.
  • קלוריות: הרשאות קריאה וכתיבה של TotalCaloriesBurnedRecord.
  • סה"כ עלייה: הרשאות קריאה וכתיבה של ElevationGainedRecord.
  • קצב הצעדים: הרשאות קריאה וכתיבה של StepsCadenceRecord.
  • הרשאות מתקדמות: הרשאות קריאה וכתיבה ב-PowerRecord.
  • שלבים: הרשאות קריאה וכתיבה של StepsRecord.

בדוגמה הבאה מוצגת בקשה לכמה הרשאות לאימון כושר שכולל נתונים על מסלול, דופק, מרחק, קלוריות, מהירות וצעדים:

אחרי שיוצרים מופע של לקוח, האפליקציה צריכה לבקש הרשאות מהמשתמש. המשתמשים חייבים להיות מסוגלים להעניק או לדחות הרשאות בכל שלב. כדי לעשות זאת, יוצרים קבוצת הרשאות לסוגי הנתונים הנדרשים. קודם צריך לוודא שההרשאות בקבוצה מוצהרות במניפסט של Android.

val permissions =
    setOf(
        HealthPermission.getReadPermission(ExerciseSessionRecord::class),
        HealthPermission.getWritePermission(ExerciseSessionRecord::class),
        HealthPermission.getReadPermission(HeartRateRecord::class),
        HealthPermission.getWritePermission(HeartRateRecord::class),
        HealthPermission.getReadPermission(SpeedRecord::class),
        HealthPermission.getWritePermission(SpeedRecord::class),
        HealthPermission.getReadPermission(DistanceRecord::class),
        HealthPermission.getWritePermission(DistanceRecord::class),
        HealthPermission.getReadPermission(TotalCaloriesBurnedRecord::class),
        HealthPermission.getWritePermission(TotalCaloriesBurnedRecord::class),
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class)
    )
אפשר להשתמש ב-getGrantedPermissions כדי לבדוק אם האפליקציה כבר קיבלה את ההרשאות הנדרשות. אם לא, משתמשים ב-createRequestPermissionResultContract כדי לבקש את ההרשאות האלה. הפעולה הזו תציג את מסך ההרשאות של Health Connect.
val permissions = setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class),
        HealthPermission.getReadPermission(HeartRateRecord::class),
        HealthPermission.getWritePermission(HeartRateRecord::class)
    )

val requestPermissionsLauncher = rememberLauncherForActivityResult(
    contract = PermissionController.createRequestPermissionResultContract()
) { grantedPermissions ->
    if (grantedPermissions.containsAll(permissions)) {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") }
    } else {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") }
    }
}
המשתמשים יכולים לתת או לבטל הרשאות בכל שלב, ולכן האפליקציה צריכה לבדוק אם ההרשאות ניתנו בכל פעם לפני שהיא משתמשת בהן, ולטפל במקרים שבהם הרשאה כלשהי בוטלה.

כדי לבקש הרשאות, צריך להפעיל את הפונקציה checkPermissionsAndRun:

if (!granted.containsAll(permissions)) {
    // Check if required permissions are not granted, and return
    return emptySet()
}
// Permissions already granted; proceed with inserting or reading data

אם אתם צריכים לבקש הרשאות רק לסוג נתונים אחד, כמו דופק, צריך לכלול רק את סוג הנתונים הזה בקבוצת ההרשאות:

הגישה לדופק מוגנת על ידי ההרשאות הבאות:

  • android.permission.health.READ_HEART_RATE
  • android.permission.health.WRITE_HEART_RATE

כדי להוסיף לאפליקציה אפשרות של דופק, צריך קודם לבקש הרשאות לסוג הנתונים HeartRateRecord.

זו ההרשאה שצריך להצהיר עליה כדי שיהיה אפשר לכתוב דופק:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_HEART_RATE" />
...
</application>

כדי לקרוא את נתוני הדופק, צריך לבקש את ההרשאות הבאות:

<application>
  <uses-permission
android:name="android.permission.health.READ_HEART_RATE" />
...
</application>

הטמעה של סשן אימון

בקטע הזה מתואר תהליך העבודה המומלץ לתיעוד נתוני אימון.

התחלת הסשן

כדי ליצור אימון חדש:

  1. יוצרים מזהה סשן ייחודי: מוודאים שהמזהה הזה יציב. אם תהליך האפליקציה נסגר ומופעל מחדש, אתם צריכים להיות מסוגלים להמשיך להשתמש באותו מזהה כדי למנוע סשנים מקוטעים.
  2. כדי למנוע כפילויות במהלך ניסיונות סנכרון חוזרים, צריך להגדיר metadata.clientRecordId.
  3. כתוב ExerciseSessionRecord: כלול את שעת ההתחלה.
  4. התחלת איסוף של סוג הנתונים ונתוני ה-GPS: צריך להתחיל את האיסוף רק אחרי שרשומת הסשן אותחלה בהצלחה.

דוגמה:

val sessionClientId = UUID.randomUUID().toString()
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime)

val session =   ExerciseSessionRecord(
    startTime = startTime,
    startZoneOffset = zoneOffset,
    endTime = startTime.plusSeconds(3600),
    endZoneOffset = zoneOffset,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    metadata = Metadata.activelyRecorded(clientRecordId = sessionClientId, device = Device(type = Device.TYPE_PHONE)),
)

healthConnectClient.insertRecords(listOf(session))

תיעוד מסלולי האימון

מידע נוסף על קריאת נתונים גולמיים

כשאתם מתעדים מסלול אימון, כדאי לשלוח את הנתונים באצווה. כלומר, במקום לשמור כל נקודת GPS בנפרד בזמן אמת, אתם אוספים קבוצה של נקודות ושומרים את כולן בבת אחת בקריאה אחת.

זה חשוב כי בכל פעם שהאפליקציה קוראת או כותבת ב-Health Connect, היא משתמשת בכמות קטנה של סוללה וכוח עיבוד.

הקוד הבא מראה איך לתעד בקבוצות:

// 1. Create a list to hold your route locations
val routeLocations = mutableListOf<ExerciseRoute.Location>()

// 2. Add points to your list as the exercise happens
routeLocations.add(
    ExerciseRoute.Location(
        time = Instant.now(),
        latitude = 37.7749,
        longitude = -122.4194
    )
)

// ... keep adding points over a period of time ...

// 3. Save the whole list at once (Batching)
val session = ExerciseSessionRecord(
    startTime = startTime,
    endTime = endTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    // We pass the whole list here
    exerciseRoute = ExerciseRoute(routeLocations)
)

healthConnectClient.insertRecords(listOf(session))

סיום סשן

אחרי שמפסיקים את איסוף הנתונים:

  • עדכון הרשומה: האפליקציה מעדכנת את ExerciseSessionRecord באמצעות endTime.
  • סיום הנתונים: אפשר לחשב ערכי סיכום (כמו המרחק הכולל או הקצב הממוצע) ולכתוב אותם כרשומות נוספות.
val finishedSession = session.copy(endTime = Instant.now())
healthConnectClient.updateRecords(listOf(finishedSession))

קריאת נתוני אימון

אפליקציות יכולות לקרוא אימונים ואת הנתונים שמשויכים אליהם כדי לסכם את הפעילות, לספק תובנות לגבי הבריאות או לסנכרן נתונים עם שרת חיצוני. לדוגמה, אתם יכולים לקרוא ExerciseSessionRecord ואז לשלוח שאילתה לגבי HeartRateRecord או DistanceRecord שהתרחשו באותו פרק זמן.

אם אתם צריכים לסנכרן נתוני אימון עם שרת בק-אנד, או לעדכן את מאגר הנתונים של האפליקציה באמצעות Health Connect, השתמשו ב-ChangeLogs. כך אפשר לאחזר רשימה של רשומות שנוספו, עודכנו או נמחקו מאז נקודת זמן מסוימת, וזה יעיל יותר ממעקב ידני אחרי שינויים או מקריאה חוזרת של כל הנתונים. מידע נוסף זמין במאמר סנכרון נתונים עם Health Connect.

קריאת נתוני הסשנים

כדי לקרוא אימונים, משתמשים ב-ReadRecordsRequest עם הסוג ExerciseSessionRecord. בדרך כלל מסננים את הנתונים האלה לפי טווח זמן ספציפי.

suspend fun readExerciseSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response = healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = ExerciseSessionRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )

    for (exerciseRecord in response.records) {
        // Process each session
        val exerciseType = exerciseRecord.exerciseType
        val notes = exerciseRecord.notes
    }
}

קריאת הנתונים של מסלולי האימון

למרות שנתוני ExerciseRoute נכתבים כחלק מסשן אימון, צריך לקרוא אותם בנפרד. משתמשים ב-method‏ getExerciseRoute() עם מזהה הסשן כדי לקרוא את נתוני המסלול שלו:

suspend fun readExerciseRoute(
    healthConnectClient: HealthConnectClient,
    exerciseSessionRecord: ExerciseSessionRecord
) {
    // Check if the session has a route
    val route = healthConnectClient.getExerciseRoute(
        exerciseSessionRecordId = exerciseSessionRecord.metadata.id
    )

    when (route) {
        is ExerciseRouteResponse.Success -> {
            val locations = route.exerciseRoute.locations
            for (location in locations) {
                // Use latitude, longitude, and altitude
            }
        }
        is ExerciseRouteResponse.NoData -> {
            // Handle case where no route exists
        }
        is ExerciseRouteResponse.ConsentRequired -> {
            // Handle case where permissions are missing
        }
    }
}

סוגי נתונים לקריאה

כדי לקרוא נתונים ספציפיים ברמת פירוט גבוהה (כמו דופק) שנמדדו במהלך סשן, משתמשים ב-startTime וב-endTime של הסשן כדי לסנן את הבקשה לסוג הנתונים הזה.

suspend fun readHeartRateData(
    healthConnectClient: HealthConnectClient,
    exerciseSession: ExerciseSessionRecord
) {
    val response = healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = HeartRateRecord::class,
            timeRangeFilter = TimeRangeFilter.between(
                exerciseSession.startTime,
                exerciseSession.endTime
            )
        )
    )

    for (heartRateRecord in response.records) {
        for (sample in heartRateRecord.samples) {
            val bpm = sample.beatsPerMinute
        }
    }
}

שיטות מומלצות

כדי לשפר את מהימנות הנתונים ואת חוויית המשתמש, כדאי לפעול לפי ההנחיות הבאות:

  • כתיבה לעיתים קרובות במהלך מעקב אחר פעילות: במעקב אחר פעילות, כותבים נתונים כשהם זמינים או במרווח זמן מקסימלי של 15 דקות.
  • שימוש ב-WorkManager לסנכרון ברקע: משתמשים ב-WorkManager לכתיבה מושהית. כדי לשמור על איזון בין נתונים בזמן אמת לבין יעילות הסוללה, מומלץ להגדיר מרווח של 15 דקות.
  • בקשות כתיבה באצווה: אל תכתבו כל אירוע חיישן בנפרד. חלקו את הבקשות שלכם. אפליקציית Health Connect מטפלת בעד 1,000 רשומות לכל בקשת כתיבה.
  • שמירה על מזהי סשנים קבועים וייחודיים: השתמשו במזהים עקביים לסשנים. אם סשן נערך או מתעדכן, השימוש באותו מזהה מונע ממנו להיחשב כסשן חדש ונפרד.
  • השתמשו באצווה גם לסוגי נתונים וגם לנקודות במסלול: כדי לצמצם את התקורה של הקלט/פלט ולשמור על חיי הסוללה, קבצו את הנקודות על הגרף לקריאה אחת של insertRecords במקום לכתוב כל נקודה בנפרד.
  • הימנעו מכתיבת נתונים כפולים: השתמשו במזהי לקוח: כשיוצרים רשומות, הגדירו metadata.clientRecordId. אפליקציית Health Connect משתמשת במזהה הזה כדי לזהות רשומות ייחודיות. אם תנסו לכתוב רשומה עם clientRecordId שכבר קיים, מערכת Health Connect תתעלם מהכפילות או תעדכן את הרשומה הקיימת במקום ליצור רשומה חדשה. הגדרת metadata.clientRecordId היא הדרך היעילה ביותר למנוע כפילויות במהלך ניסיונות סנכרון חוזרים או התקנות מחדש של האפליקציה.
    val record = StepsRecord(
        count = 100,
        startTime = startTime,
        endTime = endTime,
        startZoneOffset = ZoneOffset.UTC,
        endZoneOffset = ZoneOffset.UTC,
        metadata = Metadata(
            // Use a unique ID from your own database
            clientRecordId = "daily_steps_2023_10_27_user_123"
        )
    )
  • בדיקת נתונים קיימים: לפני הסנכרון, שלחו שאילתה לגבי טווח התאריכים כדי לבדוק אם כבר קיימות רשומות מהאפליקציה שלכם.
  • אימות הדיוק של ה-GPS: מסננים דגימות GPS עם דיוק נמוך (לדוגמה, נקודות עם רדיוס דיוק אופקי גבוה) לפני שכותבים ל-ExerciseRoute כדי לוודא שהמפה נראית נקייה ומקצועית.
  • מוודאים שאין חפיפה בין חותמות הזמן: מוודאים שסשן חדש לא מתחיל לפני שהסשן הקודם מסתיים. סשנים חופפים יכולים לגרום להתנגשויות בלוחות הבקרה של הכושר ובחישובי הסיכום.
  • לספק הסברים ברורים לבקשת ההרשאה: השתמשו בתהליך של Permission.createIntent כדי להסביר למה האפליקציה צריכה גישה לנתוני בריאות וכושר, לדוגמה: "כדי לעקוב אחרי דפוסי לחץ הדם ולספק תובנות".
  • תמיכה בהשהיה ובהמשך: ודאו שהאפליקציה מטפלת בהשהיות בצורה נכונה. כשהמשתמש עוצר, האפליקציה צריכה להפסיק לאסוף נקודות בנתיב וסוגי נתונים כדי שהקצב הממוצע ומשך הזמן יישארו מדויקים.
  • בדיקת סשנים ארוכים: עוקבים אחרי צריכת הסוללה במהלך סשנים שנמשכים כמה שעות כדי לוודא שמרווח הזמן של איסוף הנתונים והשימוש בחיישנים לא מרוקנים את הסוללה של המכשיר.
  • התאמת חותמות הזמן לקצב החיישנים: כדי לשמור על רמת דיוק גבוהה של הנתונים, כדאי להתאים את חותמות הזמן של הרשומות לתדירות בפועל של החיישנים.

בדיקה

כדי לוודא שהנתונים נכונים ושחוויית המשתמש איכותית, כדאי לפעול לפי אסטרטגיות הבדיקה האלה ולעיין במסמכים הרשמיים בנושא בדיקת תרחישי השימוש המובילים.

כלי אימות

  • ‫Health Connect Toolbox: אפליקציה נלווית שמאפשרת לבדוק רשומות באופן ידני, למחוק נתוני בדיקה ולדמות שינויים במסד הנתונים. זו הדרך הכי טובה לוודא שהרשומות נשמרות בצורה נכונה.
  • בדיקת יחידה באמצעות FakeHealthConnectClient: משתמשים בספריית הבדיקות כדי לוודא שהאפליקציה מטפלת במקרי קצה, כמו ביטול הרשאות או חריגות ב-API, בלי צורך במכשיר פיזי.

רשימת משימות לבדיקת איכות

ארכיטקטורה אופיינית

הטמעה של אימון כוללת בדרך כלל:

רכיב מנהל/ת
בקרת סשנים מצב הסשן
טיימר
לוגיקת אצווה
בקרים של סוגי נתונים
דגימת מיקום
שכבת המאגר (כוללת את הפעולות של Health Connect): הוספת סשן
הוספת סוגי נתונים
הוספת נקודות במסלול
קריאת סיכומי סשנים
שכבת ממשק המשתמש (תצוגות): משך הזמן
סוגי נתונים בזמן אמת
תצוגה מקדימה של המפה
חישובי זמני ביניים
מעקב GPS בזמן אמת

פתרון בעיות

תיאור הבעיה גורם אפשרי רזולוציה
המסלול לא משויך לסשן מזהה הסשן או טווח התאריכים לא תואמים. מוודאים שטווח הזמן שצוין ב-ExerciseRoute נמצא כולו בתוך משך הזמן של ExerciseSessionRecord. אם אתם מתייחסים לסשן מאוחר יותר, ודאו שאתם משתמשים במזהים עקביים. מידע נוסף על הקלטת מסלולי אימון
סוגי נתונים חסרים (לדוגמה, דופק) חסרות הרשאות כתיבה או שמסנני הזמן שגויים. ודאו שביקשתם את ההרשאה לסוג הנתונים הספציפי ושהמשתמש נתן אותה. מוודאים שהערך של ReadRecordsRequest ב-TimeRangeFilter תואם לסשן. למידע נוסף על הרשאות
הסשן לא נכתב חותמות זמן חופפות. יכול להיות שאפליקציית Health Connect תדחה רשומות שחופפות לנתונים קיימים מאותה אפליקציה. צריך לוודא שהשדה startTime של סשן חדש מופיע אחרי השדה endTime של הסשן הקודם.
לא תועדו נתוני GPS השירות שפועל בחזית הופסק או לא היה פעיל. כדי לאסוף נתונים כשהמסך כבוי, צריך להשתמש בשירות שפועל בחזית עם המאפיין foregroundServiceType="health" או מאפיין המיקום.
מופיעות רשומות כפולות חסר clientRecordId. מקצים clientRecordId ייחודי ב-Metadata של כל רשומה. כך Health Connect יכולה למנוע כפילויות אם אותם נתונים נכתבים פעמיים במהלך ניסיון חוזר לסנכרון. לשיטות המומלצות

שלבים נפוצים לניפוי באגים

בודקים את מצב ההרשאה. תמיד צריך להפעיל את getPermissionStatus() לפני שמנסים לבצע פעולת קריאה או כתיבה. המשתמשים יכולים לבטל את ההרשאות בהגדרות המערכת בכל שלב.
מאמתים את מצב ההפעלה. אם האפליקציה לא אוספת נתונים ברקע, צריך לוודא שהצהרת על ההרשאות הנכונות בקובץ AndroidManifest.xml ושהמשתמש לא העביר את האפליקציה למצב "מוגבלת על ידי הסוללה".