Google Fit cho Android: Recording API
Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)
Google Fit là một nền tảng cho phép các nhà phát triển xây dựng các ứng dụng tập trung vào dữ liệu sức khoẻ của người dùng. Một trong những công cụ mà Google đã cung cấp là Google Fit cho Android, nó tồn tại như là một gói trong Google Play Services.
Mặc dù có rất nhiều các API khác nhau có sẵn cho Google Fit, như đã thảo luận trong bài viết tổng quan này trên Envato Tuts+, nhưng hướng dẫn này tập trung vào việc thiết lập và sử dụng Google Fit để tạo ra các truy cập dữ liệu cảm biến chạy nền sử dụng ít năng lượng. Chúng ta sẽ khám phá cách làm thế nào để tận dụng Google Play Services để lưu trữ dữ liệu sức khoẻ để nó có thể được truy cập tại một thời điểm sau đó.
Recording API khác so với Sensors API trong đó dữ liệu cảm biến trực tiếp không được gởi tới Recording API, mà thay vào đó dữ liệu được lưu trực tuyến để lưu một bản ghi của hoạt động của người dùng. Hướng dẫn này bao gồm một dự án mẫu, bạn có thể tải về từ GitHub.
1. Thiết lập dự án
Bước 1: Thiết lập Developer Console
Để sử dụng Google Fit, bạn cần phải tạo ra một client ID OAuth 2.0 và đăng ký ứng dụng của bạn thông qua Google Developer Console. Bạn có thể tìm thấy một diễn giải chi tiết về cách để thiết lập Google Developer Console trong hướng dẫn của tôi về Sensors API của Google Fit.
Bước 2: Tạo dự án Android
Một khi bạn đã cấu hình ứng dụng của bạn để xác thực trong Google Developer Console, hãy sử dụng tên gói mà bạn đăng ký để tạo một ứng dụng Android mới với một SDK level tối thiểu là 14 và một Activity
rỗng.
Với ứng dụng Android cơ bản đã được tạo ra, hãy mở tập tin build.gradle và bao gồm Google Play Services dưới phần dependencies và đồng bộ ứng dụng của bạn.
1 |
compile 'com.google.android.gms:play-services-fitness:8.4.0' |
Bây giờ bạn có thể bao gồm các lớp cần thiết của Google Play Services vào ứng dụng của bạn. Trước khi chúng ta đi sâu vào code Java cho hướng dẫn, hãy mở activity_main.xml và sửa đổi nó để nó bao gồm hai phần tử Button
mà sẽ được sử dụng để minh hoạ một số chức năng của Recording API.
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" |
3 |
android:layout_width="match_parent" |
4 |
android:layout_height="match_parent" |
5 |
android:orientation="vertical"> |
6 |
|
7 |
<Button
|
8 |
android:id="@+id/btn_show_subscriptions" |
9 |
android:layout_width="match_parent" |
10 |
android:layout_height="wrap_content" |
11 |
android:text="Show Subscriptions"/> |
12 |
<Button
|
13 |
android:id="@+id/btn_cancel_subscriptions" |
14 |
android:layout_width="match_parent" |
15 |
android:layout_height="wrap_content" |
16 |
android:text="Cancel Subscriptions"/> |
17 |
</LinearLayout>
|
Khi ứng dụng của bạn chạy, giao diện người dùng sẽ trông giống như hình dưới đây.



Để hoàn tất việc thiết lập dự án, mở MainActivity.java của bạn và cài đặt các hàm callback và các phương thức cần thiết của chúng sau đây:
GoogleApiClient.ConnectionCallbacks
GoogleAPiClient.OnConnectionFailedListener
View.OnClickListener
Bạn cũng cần phải thêm các biến thành viên cho lớp của bạn, như hình dưới đây.
1 |
public class MainActivity extends AppCompatActivity implements |
2 |
GoogleApiClient.ConnectionCallbacks, |
3 |
GoogleApiClient.OnConnectionFailedListener, |
4 |
View.OnClickListener { |
5 |
|
6 |
private Button mCancelSubscriptionsBtn; |
7 |
private Button mShowSubscriptionsBtn; |
8 |
|
9 |
private ResultCallback<Status> mSubscribeResultCallback; |
10 |
private ResultCallback<Status> mCancelSubscriptionResultCallback; |
11 |
private ResultCallback<ListSubscriptionsResult> mListSubscriptionsResultCallback; |
12 |
|
13 |
private GoogleApiClient mGoogleApiClient; |
14 |
|
15 |
@Override
|
16 |
protected void onCreate(Bundle savedInstanceState) { |
17 |
super.onCreate(savedInstanceState); |
18 |
setContentView(R.layout.activity_main); |
19 |
}
|
20 |
|
21 |
@Override
|
22 |
public void onConnected(@Nullable Bundle bundle) { |
23 |
Log.e("RecordingAPI", "onConnected"); |
24 |
}
|
25 |
|
26 |
@Override
|
27 |
public void onConnectionSuspended(int i) { |
28 |
Log.e("RecordingAPI", "onConnectionSuspended"); |
29 |
}
|
30 |
|
31 |
@Override
|
32 |
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { |
33 |
Log.e("RecordingAPI", "onConnectionFailed"); |
34 |
}
|
35 |
|
36 |
@Override
|
37 |
public void onClick(View v) { |
38 |
}
|
39 |
}
|
2. Khởi tạo
Trước khi bạn có thể bắt đầu sử dụng các hàm callback và các View mà bạn đã định nghĩa ở trên, bạn cần phải khởi tạo chúng. Chúng ta làm điều này bằng cách tạo ra hai phương thức trợ giúp, một cho khởi tạo các View và một cho khởi tạo các hàm callback được gọi bên trong onCreate()
.
Phương thức initViews()
tham chiếu đến các đối tượng Button
được định nghĩa trong activity_main.xml và thiết lập một OnClickListener
cho mỗi Button.
1 |
@Override
|
2 |
protected void onCreate(Bundle savedInstanceState) { |
3 |
super.onCreate(savedInstanceState); |
4 |
setContentView(R.layout.activity_main); |
5 |
|
6 |
initViews(); |
7 |
initCallbacks(); |
8 |
}
|
9 |
|
10 |
private void initViews() { |
11 |
mCancelSubscriptionsBtn = (Button) findViewById(R.id.btn_cancel_subscriptions); |
12 |
mShowSubscriptionsBtn = (Button) findViewById(R.id.btn_show_subscriptions); |
13 |
|
14 |
mCancelSubscriptionsBtn.setOnClickListener(this); |
15 |
mShowSubscriptionsBtn.setOnClickListener(this); |
16 |
}
|
Trong initCallbacks()
, mọi thứ hơi thú vị hơn một chút. Mỗi hàm callback được sử dụng cho một hoạt động không đồng bộ cụ thể của Recording API. Như tên gợi ý, mSubscribeResultCallback
được gọi khi bạn lần đầu tiên thêm một subscription cho một cảm biến, mCancelSubscriptionResultCallback
được gọi khi bạn hủy subscription đó, và mListSubscriptionResultCallback
được sử dụng khi bạn yêu cầu một danh sách của tất cả các subscription.
Trong đoạn code sau, hai hàm callback liên quan đến bắt đầu và dừng lại một subscription chỉ ghi lại thành công hay thất bại. mListSubscriptionResultCallback
nhận một danh sách subscription và lưu thông tin về mỗi subscription bằng cách lấy DataType
và sau đó mỗi Field
liên kết với subscription.
1 |
private void initCallbacks() { |
2 |
mSubscribeResultCallback = new ResultCallback<Status>() { |
3 |
@Override
|
4 |
public void onResult(@NonNull Status status) { |
5 |
if (status.isSuccess()) { |
6 |
if (status.getStatusCode() == FitnessStatusCodes.SUCCESS_ALREADY_SUBSCRIBED) { |
7 |
Log.e( "RecordingAPI", "Already subscribed to the Recording API"); |
8 |
} else { |
9 |
Log.e("RecordingAPI", "Subscribed to the Recording API"); |
10 |
}
|
11 |
}
|
12 |
}
|
13 |
};
|
14 |
|
15 |
mCancelSubscriptionResultCallback = new ResultCallback<Status>() { |
16 |
@Override
|
17 |
public void onResult(@NonNull Status status) { |
18 |
if (status.isSuccess()) { |
19 |
Log.e( "RecordingAPI", "Canceled subscriptions!"); |
20 |
} else { |
21 |
// Subscription not removed
|
22 |
Log.e("RecordingAPI", "Failed to cancel subscriptions"); |
23 |
}
|
24 |
}
|
25 |
};
|
26 |
|
27 |
mListSubscriptionsResultCallback = new ResultCallback<ListSubscriptionsResult>() { |
28 |
@Override
|
29 |
public void onResult(@NonNull ListSubscriptionsResult listSubscriptionsResult) { |
30 |
for (Subscription subscription : listSubscriptionsResult.getSubscriptions()) { |
31 |
DataType dataType = subscription.getDataType(); |
32 |
Log.e( "RecordingAPI", dataType.getName() ); |
33 |
for (Field field : dataType.getFields() ) { |
34 |
Log.e( "RecordingAPI", field.toString() ); |
35 |
}
|
36 |
}
|
37 |
}
|
38 |
};
|
39 |
}
|
3. Kết nối và kiểm soát các Subscription
Bây giờ thì bạn đã có một cái sườn chung cho ứng dụng mẫu của bạn, đã đến lúc để tổng hợp tất cả mọi thứ bằng cách kết nối đến Google Play Services và yêu cầu các subscription.
Trong onCreate()
, bạn có thể khởi tạo và kết nối đến Google Play Services bằng cách khai báo rằng bạn sử dụng Fitness.RECORDING_API
, thêm một phạm vi cho việc đọc dữ liệu sức khoẻ, và thiết lập nó tự động kết nối/ngắt kết nối trong suốt vòng đời của ứng dụng.
1 |
mGoogleApiClient = new GoogleApiClient.Builder(this) |
2 |
.addApi(Fitness.RECORDING_API) |
3 |
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ)) |
4 |
.addConnectionCallbacks(this) |
5 |
.enableAutoManage(this, 0, this) |
6 |
.build(); |
Bất cứ lúc nào sau khi GoogleApiClient
đã kết nối, bạn có thể yêu cầu một subscription. Đối với hướng dẫn này, chúng ta đăng ký trong onConnected()
. Đoạn code sau đây cho thấy cách để bắt đầu một subscription cho những thay đổi ở trong số bước chân của người dùng, tuy vậy bạn có thể truy cập bất kỳ cảm biến nào mà Google Fit hỗ trợ.
Nếu một subscription đang chạy vì một hành động trước đó, thì hàm callback nhận được một mã trạng thái của FitnessStatusCodes.SUCCESS_ALREADY_SUBSCRIBED
.
1 |
@Override
|
2 |
public void onConnected(@Nullable Bundle bundle) { |
3 |
Fitness.RecordingApi.subscribe(mGoogleApiClient, DataType.TYPE_STEP_COUNT_DELTA) |
4 |
.setResultCallback(mSubscribeResultCallback); |
5 |
}
|
Đôi khi có thể hữu ích khi yêu cầu một danh sách các subscription. Trước đó, bạn đã tạo ra hai Button cho các hoạt động này. Trong phương thức onClick()
, bạn kiểm tra xem Button nào đã được chạm vào và thực hiện hành động tương ứng.
1 |
@Override
|
2 |
public void onClick(View v) { |
3 |
switch(v.getId()) { |
4 |
case R.id.btn_cancel_subscriptions: { |
5 |
cancelSubscriptions(); |
6 |
break; |
7 |
}
|
8 |
case R.id.btn_show_subscriptions: { |
9 |
showSubscriptions(); |
10 |
break; |
11 |
}
|
12 |
}
|
13 |
}
|
Nếu showSubscriptions()
được gọi, thì ứng dụng yêu cầu một danh sách các subscription kết hợp với Recording API.
1 |
private void showSubscriptions() { |
2 |
Fitness.RecordingApi.listSubscriptions(mGoogleApiClient) |
3 |
.setResultCallback(mListSubscriptionsResultCallback); |
4 |
}
|
Điều này làm cho mListSubscriptionsResultCallback
đăng xuất tất cả các subscription đã kết nối. Kết quả sẽ như thế này:
1 |
.../com.tutsplus.googlefitrecordingapi E/RecordingAPI: com.google.step_count.delta |
2 |
.../com.tutsplus.googlefitrecordingapi E/RecordingAPI: steps(i) |
Hủy bỏ một subscription thì đơn giản như bạn có thể thấy dưới đây.
1 |
private void cancelSubscriptions() { |
2 |
Fitness.RecordingApi.unsubscribe(mGoogleApiClient, DataType.TYPE_STEP_COUNT_DELTA) |
3 |
.setResultCallback(mCancelSubscriptionResultCallback); |
4 |
}
|
Tổng kết
Bây giờ bạn đã có kiến thức cơ bản về cách kết nối với Google Fit từ một ứng dụng Android và làm việc với Recording API. Mặc dù bây giờ có vẻ như không nhiều lắm, nhưng nó giúp mở ra cách để bạn lưu trữ thông tin về các hoạt động thể chất của người dùng để chúng có thể được truy cập bởi các API khác của Google Fit trong ứng dụng của bạn.