עבודה עם ביקורים

סשנים מייצגים מרווח זמן שבמהלכו משתמשים לבצע פעילות כושר. sessions API מאפשר לאפליקציה ליצור סשנים ב- חנות הכושר.

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

אתה יכול גם להכניס פעילות לחנות הכושר לאחר פעילות כושר מסתיים או כשמייבאים נתונים וסשנים מחוץ ל-Google Fit.

יצירת סשנים בזמן אמת

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

  1. הרשמה לנתוני כושר גופני באמצעות RecordingClient.subscribe .

  2. להתחיל סשן באמצעות SessionsClient.startSession כשהמשתמש מתחיל את פעילות הכושר.

  3. להפסיק את הסשן באמצעות SessionsClient.stopSession כשהמשתמש מסיים את פעילות הכושר.

  4. ביטול הרישום לנתוני הכושר שכבר לא מעוניינים להשתמש RecordingClient.unsubscribe .

התחלת סשן

כדי להתחיל סשן באפליקציה, צריך להשתמש בשיטה SessionsClient.startSession:

Kotlin

// 1. Subscribe to fitness data
// 2. Create a session object
// (provide a name, identifier, description, activity and start time)
val session = Session.Builder()
    .setName(sessionName)
    .setIdentifier("UniqueIdentifierHere")
    .setDescription("Morning run")
    .setActivity(FitnessActivities.RUNNING)
    .setStartTime(startTime, TimeUnit.MILLISECONDS)
    .build()

// 3. Use the Sessions client to start a session:
Fitness.getSessionsClient(this, googleSigninAccount)
    .startSession(session)
    .addOnSuccessListener {
        Log.i(TAG, "Session started successfully!")
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "There was an error starting the session", e)
    }

Java

// 1. Subscribe to fitness data
// 2. Create a session object
// (provide a name, identifier, description, activity and start time)
Session session = new Session.Builder()
        .setName(sessionName)
        .setIdentifier("UniqueIdentifierHere")
        .setDescription("Morning run")
        .setActivity(FitnessActivities.RUNNING)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .build();

// 3. Use the Sessions client to start a session:
Fitness.getSessionsClient(this, googleSigninAccount)
        .startSession(session)
        .addOnSuccessListener(unused ->
                Log.i(TAG, "Session started successfully!"))
        .addOnFailureListener(e ->
                Log.w(TAG, "There was an error starting the session", e));

איך מפסיקים סשן

כדי להפסיק סשן באפליקציה, צריך להשתמש בשיטה SessionsClient.stopSession:

Kotlin

// Invoke the SessionsClient with the session identifier
Fitness.getSessionsClient(this, googleSigninAccount)
    .stopSession(session.getIdentifier())
    .addOnSuccessListener {
        Log.i(TAG, "Session stopped successfully!")

        // Now unsubscribe from the fitness data (see
        // Recording Fitness data)
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "There was an error stopping the session", e)
    }

Java

// Invoke the SessionsClient with the session identifier
Fitness.getSessionsClient(this, googleSigninAccount)
        .stopSession(session.getIdentifier())
        .addOnSuccessListener (unused -> {
            Log.i(TAG, "Session stopped successfully!");
            // Now unsubscribe from the fitness data (see
            // Recording Fitness data)
        })
        .addOnFailureListener(e ->
                Log.w(TAG, "There was an error stopping the session", e));

הסשן שמתקבל כולל את הפרמטרים הבאים:

  • שעת ההתחלה: השעה שבה האפליקציה התקשרה לSessionsClient.startSession .

  • שעת סיום: השעה שבה האפליקציה התקשרה לSessionsClient.stopSession .

  • שם: השם באובייקט Session שאליו מעבירים SessionsClient.startSession.

הוספת פעילויות בחנות הכושר

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

  1. יצירת אובייקט Session שמציין מרווח זמן ופריטים אחרים שנדרשים מידע.

  2. לכתוב SessionInsertRequest עם הסשן.

  3. אפשר גם להוסיף מערכי נתונים ונקודות על הגרף.

  4. מוסיפים את הסשן באמצעות SessionsClient.insertSession .

הוספת סשן

כדי להוסיף נתוני כושר גופני שמכילים מטא נתונים של הפעלה, לכושר של המשתמש היסטוריה, קודם יוצרים מכונה של SessionInsertRequest:

Kotlin

// Create a session with metadata about the activity.
val session = Session.Builder()
    .setName(SAMPLE_SESSION_NAME)
    .setIdentifier("UniqueIdentifierHere")
    .setDescription("Long run around Shoreline Park")

    .setActivity(FitnessActivities.RUNNING)
    .setStartTime(startTime, TimeUnit.MILLISECONDS)
    .setEndTime(endTime, TimeUnit.MILLISECONDS)
    .build()

// Build a session insert request
val insertRequest = SessionInsertRequest.Builder()
    .setSession(session)
    // Optionally add DataSets for this session.
    .addDataSet(dataset)
    .build()

Java

// Create a session with metadata about the activity.
Session session = new Session.Builder()
        .setName(SAMPLE_SESSION_NAME)
        .setIdentifier("UniqueIdentifierHere")
        .setDescription("Long run around Shoreline Park")

        .setActivity(FitnessActivities.RUNNING)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .setEndTime(endTime, TimeUnit.MILLISECONDS)
        .build();

// Build a session insert request
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
        .setSession(session)
        // Optionally add DataSets for this session.
        .addDataSet(dataset)
        .build();

הכיתה SessionInsertRequest מציעה שיטות נוחות להוספת נתונים להיסטוריית הכושר וליצור מפגש באותה שיחה SessionsClient.insertSession. מערכי הנתונים, אם יש כאלה, נוספים כאילו קראנו HistoryClient.insertData תחילה, ואז נוצר הסשן.

Kotlin

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .insertSession(insertRequest)
    .addOnSuccessListener {
        Log.i(TAG, "Session insert was successful!")
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "There was a problem inserting the session: ", e)
    }

Java

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
        .insertSession(insertRequest)
        .addOnSuccessListener (unused ->
                Log.i(TAG, "Session insert was successful!"))
        .addOnFailureListener(e ->
        Log.w(TAG, "There was a problem inserting the session: ", e));

הוספת פלחי פעילות

הנתונים של מקטע פעילות ב-Google Fit מציינים את פעילות הכושר הגופני של המשתמשים בפרק זמן נתון. הנתונים של פלח הפעילות הם מסוג com.google.activity.segment (TYPE_ACTIVITY_SEGMENT) היא שימושית במיוחד כדי לתמוך בהפסקות במהלך אימוני כושר.

לדוגמה, אם אתם יוצרים סשן ריצה של 30 דקות עם Session.Builder.setActivity() אבל המשתמש לוקח הפסקה של 10 דקות ביניהן, האפליקציה מראים באופן שגוי שהמשתמש פעל במשך 30 דקות. בתנאי שהאפליקציה יכולה לזהות אם המשתמש היה הולך או רץ, הנתונים של פלחי הפעילות מאפשרים האפליקציה מציינת שהמשתמש רץ במשך 10 דקות, הלך 10 דקות ואז רץ למשך 10 דקות נוספות. גם אפליקציות אחרות יכולות לדווח על הפעילות בצורה נכונה על ידי בחינת הנתונים של פלחי הפעילות שהזנתם.

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

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

Kotlin

// Create a DataSet of ActivitySegments to indicate the runner walked for
// 10 minutes in the middle of a run.
val activitySegmentDataSource = DataSource.Builder()
    .setAppPackageName(this.packageName)
    .setDataType(DataType.TYPE_ACTIVITY_SEGMENT)
    .setStreamName(SAMPLE_SESSION_NAME + "-activity segments")
    .setType(DataSource.TYPE_RAW)
    .build()

val firstRunningDp = DataPoint.builder(activitySegmentDataSource)
    .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
    .setTimeInterval(startTime, startWalkTime, TimeUnit.MILLISECONDS)
    .build()

val walkingDp = DataPoint.builder(activitySegmentDataSource)
    .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.WALKING)
    .setTimeInterval(startWalkTime, endWalkTime, TimeUnit.MILLISECONDS)
    .build()

val secondRunningDp = DataPoint.builder(activitySegmentDataSource)
    .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
    .setTimeInterval(endWalkTime, endTime, TimeUnit.MILLISECONDS)
    .build()

val activitySegments = DataSet.builder(activitySegmentDataSource)
    .addAll(listOf(firstRunningDp, walkingDp, secondRunningDp))
    .build()

// Create a session with metadata about the activity.
val session = Session.Builder()
    .setName(SAMPLE_SESSION_NAME)
    .setDescription("Long run around Shoreline Park")
    .setIdentifier("UniqueIdentifierHere")
    .setActivity(FitnessActivities.RUNNING)
    .setStartTime(startTime, TimeUnit.MILLISECONDS)
    .setEndTime(endTime, TimeUnit.MILLISECONDS)
    .build()

// Build a session insert request
val insertRequest = SessionInsertRequest.Builder()
    .setSession(session)
    .addDataSet(activitySegments)
    .build()

Java

// Create a DataSet of ActivitySegments to indicate the runner walked for
// 10 minutes in the middle of a run.
DataSource activitySegmentDataSource = new DataSource.Builder()
        .setAppPackageName(getPackageName())
        .setDataType(DataType.TYPE_ACTIVITY_SEGMENT)
        .setStreamName(SAMPLE_SESSION_NAME + "-activity segments")
        .setType(DataSource.TYPE_RAW)
        .build();

DataPoint firstRunningDp = DataPoint.builder(activitySegmentDataSource)
        .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
        .setTimeInterval(startTime, startWalkTime, TimeUnit.MILLISECONDS)
        .build();

DataPoint walkingDp = DataPoint.builder(activitySegmentDataSource)
        .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.WALKING)
        .setTimeInterval(startWalkTime, endWalkTime, TimeUnit.MILLISECONDS)
        .build();

DataPoint secondRunningDp = DataPoint.builder(activitySegmentDataSource)
        .setActivityField(Field.FIELD_ACTIVITY, FitnessActivities.RUNNING)
        .setTimeInterval(endWalkTime, endTime, TimeUnit.MILLISECONDS)
        .build();

DataSet activitySegments = DataSet.builder(activitySegmentDataSource)
        .addAll(Arrays.asList(firstRunningDp, walkingDp, secondRunningDp))
        .build();

// Create a session with metadata about the activity.
Session session = new Session.Builder()
        .setName(SAMPLE_SESSION_NAME)
        .setDescription("Long run around Shoreline Park")
        .setIdentifier("UniqueIdentifierHere")
        .setActivity(FitnessActivities.RUNNING)
        .setStartTime(startTime, TimeUnit.MILLISECONDS)
        .setEndTime(endTime, TimeUnit.MILLISECONDS)
        .build();

// Build a session insert request
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
        .setSession(session)
        .addDataSet(activitySegments)
        .build();

קריאת נתוני כושר באמצעות סשנים

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

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

Kotlin

// Use a start time of 1 week ago and an end time of now.
val endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
val startTime = endTime.minusWeeks(1)

// Build a session read request
val readRequest = SessionReadRequest.Builder()
    .setTimeInterval(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS)
    .read(DataType.TYPE_SPEED)
    .setSessionName(SAMPLE_SESSION_NAME)
    .build()

Java

// Use a start time of 1 week ago and an end time of now.
ZonedDateTime endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
ZonedDateTime startTime = endTime.minusWeeks(1)

// Build a session read request
SessionReadRequest readRequest = new SessionReadRequest.Builder()
        .setTimeInterval(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.SECONDS)
        .read(DataType.TYPE_SPEED)
        .setSessionName(SAMPLE_SESSION_NAME)
        .build();

ואז משתמשים SessionsClient.readSession method:

Kotlin

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
    .readSession(readRequest)
    .addOnSuccessListener { response ->
        // Get a list of the sessions that match the criteria to check the result.
        val sessions = response.sessions
        Log.i(TAG, "Number of returned sessions is: ${sessions.size}")
        for (session in sessions) {
            // Process the session
            dumpSession(session)

            // Process the data sets for this session
            val dataSets = response.getDataSet(session)
            for (dataSet in dataSets) {
                // ...
            }
        }
    }
    .addOnFailureListener { e ->
        Log.w(TAG,"Failed to read session", e)
    }

Java

Fitness.getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
        .readSession(readRequest)
        .addOnSuccessListener(response -> {
            // Get a list of the sessions that match the criteria to check the
            // result.
            List<Session> sessions = response.getSessions();
            Log.i(TAG, "Number of returned sessions is: ${sessions.size}");
            for (Session session : sessions) {
                // Process the session
                dumpSession(session);

                // Process the data sets for this session
                List<DataSet> dataSets = response.getDataSet(session);
                for (DataSet dataSet : dataSets) {
                    // ...
                }
            }
        })
        .addOnFailureListener(e ->
                Log.w(TAG,"Failed to read session", e));

קריאת נתוני השינה באמצעות סשנים

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

כדי לכלול סשנים של שינה, includeSleepSessions במהלך הפיתוח של SessionReadRequest. כדי לכלול גם פעילויות וגם סשנים, משתמשים גם ב-includeSleepSessions וגם includeActivitySessions.

הצגת סשנים באפליקציות אחרות

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

כדי ליצור כוונה להציג נתוני סשן באפליקציה אחרת, צריך להשתמש ב SessionsApi.ViewIntentBuilder class:

Kotlin

// Pass your activity object to the constructor
val intent = SessionsApi.ViewIntentBuilder(this)
    .setPreferredApplication("com.example.someapp") // optional
    .setSession(session)
    .build()

// Invoke the intent
startActivity(intent)

Java

// Pass your activity object to the constructor
Intent intent = new SessionsApi.ViewIntentBuilder(this)
        .setPreferredApplication("com.example.someapp") // optional
        .setSession(session)
        .build();

// Invoke the intent
startActivity(intent);

קבלת כוונות מאפליקציות אחרות

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

<intent-filter>
    <action android:name="vnd.google.fitness.VIEW"/>
    <data android:mimeType="vnd.google.fitness.session/running"/>
</intent-filter>

כל אובייקט Intent שהאפליקציה שלך מקבלת מ-Google Fit הוא רק אחד פעילות, אבל אפשר לסנן לפי כמה סוגי MIME במסנן Intent אחד. מסנן Intent של האפליקציה צריך לכלול את כל הפעילויות שהאפליקציה נתמך.

הכוונות לגבי כושר גופני כוללות את התוספות הבאות:

  • vnd.google.gms.fitness.start_time
  • vnd.google.gms.fitness.end_time
  • vnd.google.gms.fitness.session

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

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    val supportedType = Session.getMimeType(FitnessActivities.RUNNING)

    if (Intent.ACTION_VIEW == intent.action && supportedType == intent.type) {
        // Get the intent extras
        val startTime = Fitness.getStartTime(intent, TimeUnit.MILLISECONDS);
        val endTime = Fitness.getEndTime(intent, TimeUnit.MILLISECONDS)
        val session = Session.extract(intent)
    }
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    String supportedType = Session.getMimeType(FitnessActivities.RUNNING);

    if (Intent.ACTION_VIEW.equals(getIntent().getAction()) && supportedType.equals(getIntent().getType())) {
        // Get the intent extras
        long startTime = Fitness.getStartTime(getIntent(), TimeUnit.MILLISECONDS);
        long endTime = Fitness.getEndTime(getIntent(), TimeUnit.MILLISECONDS);
        Session session = Session.extract(getIntent());
    }
}