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

تمثل الجلسات فاصلاً زمنيًا يمارس خلاله المستخدمون نشاطًا للياقة البدنية. تتيح واجهة برمجة تطبيقات الجلسات لتطبيقك إنشاء جلسات في متجر اللياقة البدنية.

بالنسبة إلى أنشطة اللياقة البدنية المستمرة التي يُبلغ فيها المستخدم تطبيقك عند بدء نشاط لياقة بدنية وانتهائه، يمكنك إنشاء جلسات في الوقت الفعلي.

يمكنك أيضًا إدراج جلسة في متجر اللياقة البدنية بعد انتهاء أحد أنشطة اللياقة البدنية أو عند استيراد البيانات والجلسات من خارج 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.

عرض الجلسات في التطبيقات الأخرى

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

لإنشاء غرض لعرض بيانات الجلسات على تطبيق مختلف، استخدِم الفئة 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());
    }
}