Xử lý các phiên hoạt động

Phiên biểu thị khoảng thời gian mà người dùng thực hiện một hoạt động thể dục. API phiên cho phép ứng dụng của bạn tạo các phiên trong cửa hàng thể dục.

Đối với các hoạt động thể dục đang diễn ra mà người dùng thông báo cho ứng dụng của bạn khi họ bắt đầu và kết thúc một hoạt động thể dục, bạn có thể tạo các buổi tập theo thời gian thực.

Bạn cũng có thể chèn phiên tập thể dục vào cửa hàng thể dục sau một hoạt động thể dục kết thúc hoặc khi bạn nhập dữ liệu và phiên từ bên ngoài Google Fit.

Tạo phiên sự kiện theo thời gian thực

Để tạo phiên cho các hoạt động thể dục đang diễn ra, hãy hoàn tất các bước sau:

  1. Đăng ký dữ liệu hoạt động thể dục bằng RecordingClient.subscribe .

  2. Bắt đầu phiên bằng cách sử dụng SessionsClient.startSession khi người dùng bắt đầu hoạt động thể dục.

  3. Dừng phiên bằng cách sử dụng SessionsClient.stopSession khi người dùng kết thúc hoạt động thể dục.

  4. Huỷ đăng ký nhận dữ liệu về hoạt động thể dục bạn không còn muốn sử dụng RecordingClient.unsubscribe .

Bắt đầu một phiên

Để bắt đầu một phiên trong ứng dụng, hãy dùng phương thức 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));

Dừng một phiên

Để dừng một phiên trong ứng dụng, hãy dùng phương thức 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));

Phiên kết quả có các thông số sau:

  • Thời gian bắt đầu: Thời điểm ứng dụng của bạn gọi SessionsClient.startSession .

  • Thời gian kết thúc: Thời điểm ứng dụng của bạn gọi SessionsClient.stopSession .

  • Tên: Tên trong đối tượng Session mà bạn truyền đến SessionsClient.startSession

Chèn phiên hoạt động vào cửa hàng thể dục

Để chèn phiên hoạt động có dữ liệu mà bạn đã thu thập trước đây, hãy làm như sau:

  1. Tạo một đối tượng Session chỉ định khoảng thời gian và các yêu cầu khác của bạn.

  2. Tạo một SessionInsertRequest với phiên hoạt động đó.

  3. Thêm tập dữ liệu và điểm dữ liệu tổng hợp (không bắt buộc).

  4. Chèn phiên bằng cách sử dụng SessionsClient.insertSession .

Chèn phiên

Để chèn dữ liệu hoạt động thể dục có chứa siêu dữ liệu về phiên hoạt động thể dục vào dữ liệu về hoạt động thể dục của người dùng nhật ký của bạn, trước tiên hãy tạo một thực thể 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();

Lớp SessionInsertRequest cung cấp các phương thức thuận tiện để chèn dữ liệu vào lịch sử tập thể dục và tạo một phiên trong cùng một cuộc gọi đến SessionsClient.insertSession Các tập dữ liệu, nếu có, sẽ được chèn như thể bạn đã gọi HistoryClient.insertData và sau đó phiên sẽ được tạo.

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

Chèn phân đoạn hoạt động

Dữ liệu về phân đoạn hoạt động trong Google Fit cho biết hoạt động thể dục nào hiệu quả hoạt động của người dùng trong một khoảng thời gian nhất định. Dữ liệu phân đoạn hoạt động là thuộc loại com.google.activity.segment (TYPE_ACTIVITY_SEGMENT) và đặc biệt hữu ích khi hỗ trợ việc tạm dừng trong khi tập thể dục.

Ví dụ: nếu bạn tạo một phiên chạy bộ 30 phút với thuộc tính Session.Builder.setActivity() nhưng người dùng nghỉ 10 phút ở giữa, ứng dụng của bạn sẽ cho biết không chính xác rằng người dùng đã chạy trong 30 phút. Miễn là ứng dụng của bạn có thể phát hiện xem người dùng đang đi bộ hay chạy, dữ liệu phân đoạn hoạt động cho phép ứng dụng cho biết người dùng đã chạy 10 phút, đi bộ 10 phút, sau đó chạy thêm 10 phút. Các ứng dụng khác cũng có thể báo cáo hoạt động một cách chính xác bằng cách xem dữ liệu phân đoạn hoạt động mà bạn chèn.

Để thêm dữ liệu về phân đoạn hoạt động vào một phiên hoạt động, hãy tạo một tập dữ liệu chứa các điểm thuộc loại com.google.activity.segment. Mỗi điểm trong số này đại diện cho một khoảng thời gian liên tục mà người dùng đã thực hiện một loại hoạt động duy nhất.

Ví dụ trước đây về hoạt động chạy và đi bộ sẽ yêu cầu 3 phân đoạn hoạt động điểm: một để chạy trong 10 phút đầu tiên, một để đi bộ trong 10 phút tiếp theo và một quảng cáo để chạy trong 10 phút cuối cùng.

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

Đọc dữ liệu hoạt động thể dục bằng các phiên

API phiên cho phép bạn có được danh sách các phiên từ kho thể dục phù hợp với một số tiêu chí. Ví dụ: bạn có thể có được tất cả các phiên có trong một hoặc nhận một phiên cụ thể theo tên hay mã nhận dạng. Bạn cũng có thể chỉ định cho dù bạn quan tâm đến các phiên do ứng dụng của mình hay bất kỳ ứng dụng nào tạo ra.

Để có được danh sách các phiên phù hợp với một số tiêu chí, trước tiên hãy tạo một Thực thể 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();

Sau đó sử dụng SessionsClient.readSession phương thức:

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

Đọc dữ liệu giấc ngủ bằng phiên

Phiên giấc ngủ được coi là khác biệt với các phiên hoạt động khác. Theo mặc định, phản hồi đọc chỉ chứa phiên hoạt động chứ không chứa phiên giấc ngủ.

Để bao gồm phiên giấc ngủ, hãy sử dụng includeSleepSessions khi tạo SessionReadRequest. Để bao gồm cả hoạt động và hãy sử dụng cả includeSleepSessionsincludeActivitySessions.

Hiện các phiên hoạt động trong ứng dụng khác

Để hiển thị cho người dùng chế độ xem chi tiết hơn về một phiên cụ thể trong một ứng dụng khác, ứng dụng của bạn có thể gọi một ý định chứa thông tin phiên. Bạn có thể chỉ định một ứng dụng cụ thể, chẳng hạn như ứng dụng đã tạo phiên hoạt động đó. Hoặc, trong trường hợp ứng dụng đã tạo ra phiên hoạt động chưa được cài đặt trên thiết bị, bạn có thể cho phép bất kỳ ứng dụng có thể hiển thị hoạt động thể dục để phản hồi ý định.

Để tạo ý định hiển thị dữ liệu phiên trên một ứng dụng khác, hãy sử dụng phương thức SessionsApi.ViewIntentBuilder lớp:

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

Nhận ý định từ các ứng dụng khác

Cách đăng ký ứng dụng của bạn để nhận ý định từ các ứng dụng sức khoẻ thể chất và tinh thần khác: khai báo bộ lọc ý định trong tệp kê khai tương tự như sau:

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

Mỗi ý định mà ứng dụng của bạn nhận được từ Google Fit chỉ là một ý định nhưng bạn có thể lọc nhiều loại MIME trong một bộ lọc ý định duy nhất. Bộ lọc ý định của ứng dụng cần bao gồm tất cả hoạt động mà ứng dụng Google Cloud.

Ý định thể dục bao gồm những bổ sung sau:

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

Bạn có thể lấy dữ liệu từ các ứng dụng bổ sung này như sau:

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