العمل باستخدام الجلسات

تمثّل الجلسات فاصلاً زمنيًا يتوقّف خلاله المستخدمون أداء نشاط اللياقة البدنية. تسمح واجهة برمجة التطبيقات 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 دقائق، واحدة للمشي خلال الدقائق العشر التالية، واحدة للجري خلال الدقائق العشر الأخيرة.

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();

قراءة بيانات اللياقة البدنية باستخدام الجلسات

تتيح لك واجهة برمجة تطبيقات الجلسات الحصول على قائمة بالجلسات من متجر اللياقة البدنية التي تطابق بعض المعايير. على سبيل المثال، يمكنك الحصول على جميع الجلسات المتضمنة في الفاصل الزمني أو الحصول على جلسة معينة حسب الاسم أو رقم التعريف. يمكنك أيضًا تحديد سواء كنت مهتمًا بالجلسات التي ينشئها تطبيقك أو أيّ تطبيق

للحصول على قائمة بالجلسات التي تتطابق مع بعض المعايير، يمكنك أولاً إنشاء مثال واحد (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 :

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 الفئة:

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

كل هدف يتلقّىه تطبيقك من Google Fit هو هدف واحد فقط. ولكن يمكنك الفلترة بحثًا عن أنواع MIME متعددة في فلتر أهداف واحد. يجب أن يتضمن فلتر الأهداف في تطبيقك جميع الأنشطة التي يستخدمها والدعم.

تتضمن أغراض اللياقة البدنية العناصر الإضافية التالية:

  • 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());
    }
}