The Recording API allows your app to request automated storage of sensor data in a battery-efficient manner by creating subscriptions. Once you add a subscription for a data type, then it's Google Play services' responsibility to start recording the data for the requested data type in the background. This recorded data is stored in the Google fitness store and can be queried by History API. The Recording API only decides which data type to record; everything else is managed by the Google fitness platform. The Recording API is part of Google play services. The steps for connecting to Google play services via the GoogleApiClient
class are exactly the same as for the Sensors API, discussed in the previous section. In our example, inside SubscriptionActivity
we will perform four important tasks with subscriptions. First, we will get authorization to read history data from the fitness store using the History API. Second, we will list all the existing subscriptions. Third, we will add subscriptions from the spinner drop-down. Finally, we will delete an already added subscription. Now let's look at the individual tasks performed by SubscriptionActivity
.
SubscriptionActivity
is to get authorization from the user to read history fitness data using the History API. This authorization has to be requested for the first time only. The code and process for getting authorization is exactly the same as for Sensors API, which we discussed in the previous section. The only difference is that we have to add RECORDING_API
in place of SENSORS_API
in the addApi()
method of the GoogleApiClient
class.Even though authorization has already been given in the SensorActivity
class, we still have to get authorization for two reasons: we are using a different API (History API) and the user might go directly to SubscriptionActivity
instead of going to SensorActivity
first. The code used inSubscriptionActivity
can be downloaded from the code bundle for this chapter:public class SubscriptionActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, OnItemSelectedListener, OnItemClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.subscriptiondata_layout); mClient = new GoogleApiClient.Builder(this) .addApi(Fitness.RECORDING_API) .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ)) .addScope(new Scope(Scopes.FITNESS_BODY_READ)) .addScope(new Scope(Scopes.FITNESS_LOCATION_READ)) .addScope(new Scope(Scopes.FITNESS_NUTRITION_READ)) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this).build(); setUpSpinnerDropDown(); setUpListView(); }
SubscriptionActivity
is to list all the existing active subscriptions. We show the entire active subscriptions list of the data type in the ListView
, which is set up inside the setUpListView()
method (this method is the same as in the previous SensorActivity
class) and is called from the onCreate()
method of the activity. As soon as we get connected to the Google play services through the GoogleApiClient
object, we call the listExistingSubscription()
method to get the list of active subscriptions. Inside the listExistingSubscription()
method, we use the listSubscriptions()
method of Recording API to get the list of all active subscriptions asynchronously inside the object of ResultCallback<ListSubscriptionsResult>
, which is set using the setResultCallback()
method of the API. We receive a list of Subscription objects, which contains all the details of the active subscription. To display the results in the ListView
, we only take the data type of the subscription and add it to the mDataTypeList
, which acts a source for the ListView
. We set the item click listener on the ListView
to receive the clicked subscription item index. The implementation details of ListAdapter
can be found in the code that comes with this chapter:
@Override public void onConnected(Bundle bundle) { listExistingSubscription(); } public void listExistingSubscription() { Fitness.RecordingApi.listSubscriptions(mClient) setResultCallback(new ResultCallback<ListSubscriptionsResult>() { @Override public void onResult(ListSubscriptionsResult listSubscriptionsResult) { mDataTypeList.clear(); for (Subscription sc : listSubscriptionsResult.getSubscriptions()) { mDataTypeList.add(sc.getDataType()); } runOnUiThread(new Runnable() { @Override public void run() { mListAdapter.notifyDataSetChanged(); } }); } }); }
SubscriptionActivity
is to add subscriptions. We can add subscriptions based either on a data source or a data type. For our example, we add it using a data type. We use the spinner drop-down to let the user select a particular data type. In the setUpSpinnerDropDown()
method (this method is the same as in the previous SensorActivity
class) we set up the spinner and set its selected listener. We get all the human readable strings values for all the available data types from the getDataTypeReadableValues()
method of the DataHelper
utility singleton class. After the user has selected a data type from the spinner drop-down value, we add the subscription for that particular data type. In the onItemSelected()
spinner callback, we get the selected item position and by using the getDataTypeRawValues()
method of the DataHelper
utility class, we get its corresponding DataType
object value, which is then passed to the addSubscription()
method for adding a subscription. Inside the addSubscription()
method, we use the subscribe()
method of Recording API to add the subscription. Once the subscription is successfully added, then we refresh the active subscription list by calling the listExistingSubscription()
method:
@Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if(position!=0 && mClient.isConnected()) { addSubscription(DataHelper.getInstance() .getDataTypeRawValues().get(position)); } } public void addSubscription(DataType mDataType) { Fitness.RecordingApi.subscribe(mClient, mDataType) .setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { if (status.isSuccess()) { listExistingSubscription(); } else { Log.i(TAG, "There was a problem subscribing."); } } }); }
SubscriptionActivity
is to remove any active subscriptions. This is done by taking the clicked index of displayed active subscription data types on ListView
inside onItemClick()
and sending the corresponding data type to the removeSubscription()
method. Inside the removeSubscription()
method, we use the unsubscribe()
method of Recording API to remove the active subscription. The unsubscribe()
API accepts the object of the GoogleApiClient
class and the data type to be removed. Once the subscription has been removed successfully, we remove the subscribed data type from mDataTypeList
and refresh the ListView
:@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { removeSubscription(mDataTypeList.get(position)); } public void removeSubscription(DataType mDataType) { Fitness.RecordingApi.unsubscribe(mClient, mDataType) .setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { if (status.isSuccess()) { runOnUiThread(new Runnable() { @Override public void run() { mDataTypeList.remove (lastRemovedPosition); mListAdapter.notifyDataSetChanged(); } }); } else { Log.i(TAG, "Failed to unsubscribe "); } } }); }
In the SubscriptionActivity
, we developed a utility that deals with all the operations (adding, removing, listing) for subscriptions. Subscriptions are really helpful when you don't want your application to manage the collection and storage of fitness data by staying in the background forever. All subscribed data is collected and stored in the Google Fitness Store and can be retrieved using History API, which we will discuss in the next section. The following is a screenshot from a Nexus 5X device showing the list of active subscriptions: