2 つの主な処理を行う次のコードがあります。
- Google Play サービスに接続します。
- onConnected() メソッド内で startService(...) メソッドを呼び出すことにより、サービスが開始されます。
プログラムを実行すると、次のログ メッセージが表示されます。
Connected!!!
Fit wasn't able to connect, so the request failed.
GoogleFitService destroyed.
これが私のコードです:
public class MainActivity extends ActionBarActivity {
public final static String TAG = "GoogleFitService";
private static final int REQUEST_OAUTH = 1;
private static final String AUTH_PENDING = "auth_state_pending";
private boolean authInProgress = false;
private GoogleApiClient mClient = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buildFitnessClient();
}
private void buildFitnessClient() {
// Create the Google API Client
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.API)
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected!!!");
// Now you can make calls to the Fitness APIs.
// Put application specific code here.
Intent service = new Intent(MainActivity.this,
GoogleFitService.class);
service.putExtra(GoogleFitService.SERVICE_REQUEST_TYPE,
GoogleFitService.TYPE_REQUEST_CONNECTION);
startService(service);
}
@Override
public void onConnectionSuspended(int i) {
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG, "Connection lost. Reason: Service Disconnected");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed. Cause: " + result.toString());
if (!result.hasResolution()) {
// Show the localized error dialog
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), MainActivity.this, 0).show();
return;
}
if (!authInProgress) {
try {
Log.i(TAG, "Attempting to resolve failed connection");
authInProgress = true;
result.startResolutionForResult(MainActivity.this, REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
}
}
)
.build();
}
@Override
protected void onStart() {
super.onStart();
// Connect to the Fitness API
Log.i(TAG, "Connecting...");
mClient.connect();
Intent service = new Intent(this, GoogleFitService.class);
service.putExtra(GoogleFitService.SERVICE_REQUEST_TYPE, GoogleFitService.TYPE_REQUEST_CONNECTION);
startService(service);
}
@Override
protected void onStop() {
super.onStop();
if (mClient.isConnected()) {
mClient.disconnect();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_OAUTH) {
authInProgress = false;
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to connect
if (!mClient.isConnecting() && !mClient.isConnected()) {
mClient.connect();
}
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(AUTH_PENDING, authInProgress);
}
}
2 番目のクラスは基本的に Intent サービスです。間違いはここにあるのかもしれません。
public class GoogleFitService extends IntentService {
public static final String TAG = "GoogleFitService";
private GoogleApiClient mGoogleApiFitnessClient;
private boolean mTryingToConnect = false;
public static final String SERVICE_REQUEST_TYPE = "requestType";
public static final int TYPE_GET_STEP_TODAY_DATA = 1;
public static final int TYPE_REQUEST_CONNECTION = 2;
public static final String HISTORY_INTENT = "fitHistory";
public static final String HISTORY_EXTRA_STEPS_TODAY = "stepsToday";
public static final String FIT_NOTIFY_INTENT = "fitStatusUpdateIntent";
public static final String FIT_EXTRA_CONNECTION_MESSAGE =
"fitFirstConnection";
public static final String FIT_EXTRA_NOTIFY_FAILED_STATUS_CODE =
"fitExtraFailedStatusCode";
public static final String FIT_EXTRA_NOTIFY_FAILED_INTENT =
"fitExtraFailedIntent";
@Override
public void onDestroy() {
Log.d(TAG, "GoogleFitService destroyed");
if (mGoogleApiFitnessClient.isConnected()) {
Log.d(TAG, "Disconecting Google Fit.");
mGoogleApiFitnessClient.disconnect();
}
super.onDestroy();
}
@Override
public void onCreate() {
super.onCreate();
buildFitnessClient();
Log.d(TAG, "GoogleFitService created");
}
public GoogleFitService() {
super("GoogleFitService");
}
@Override
protected void onHandleIntent(Intent intent) {
//Get the request type
int type = intent.getIntExtra(SERVICE_REQUEST_TYPE, 1);
//block until google fit connects. Give up after 10 seconds.
if (!mGoogleApiFitnessClient.isConnected()) {
mTryingToConnect = true;
mGoogleApiFitnessClient.connect();
//Wait until the service either connects or fails to connect
while (mTryingToConnect) {
try {
Thread.sleep(100, 0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (mGoogleApiFitnessClient.isConnected()) {
if (type == TYPE_GET_STEP_TODAY_DATA) {
Log.d(TAG, "Requesting steps from Google Fit");
getStepsToday();
Log.d(TAG, "Fit update complete. Allowing Android to destroy
the service.");
} else if (type == TYPE_REQUEST_CONNECTION) {
}
} else {
//Not connected
Log.w(TAG, "Fit wasn't able to connect, so the request failed.");
}
}
private void getStepsToday() {
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
long startTime = cal.getTimeInMillis();
final DataReadRequest readRequest = new DataReadRequest.Builder()
.read(DataType.TYPE_STEP_COUNT_DELTA)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();
DataReadResult dataReadResult =
Fitness.HistoryApi.readData(mGoogleApiFitnessClient,
readRequest).await(1, TimeUnit.MINUTES);
DataSet stepData =
dataReadResult.getDataSet(DataType.TYPE_STEP_COUNT_DELTA);
int totalSteps = 0;
for (DataPoint dp : stepData.getDataPoints()) {
for (Field field : dp.getDataType().getFields()) {
int steps = dp.getValue(field).asInt();
totalSteps += steps;
}
}
publishTodaysStepData(totalSteps);
}
private void publishTodaysStepData(int totalSteps) {
Intent intent = new Intent(HISTORY_INTENT);
// You can also include some extra data.
intent.putExtra(HISTORY_EXTRA_STEPS_TODAY, totalSteps);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void buildFitnessClient() {
// Create the Google API Client
mGoogleApiFitnessClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.API)
.addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Google Fit connected.");
mTryingToConnect = false;
Log.d(TAG, "Notifying the UI that we're
connected.");
notifyUiFitConnected();
}
@Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at
some point,
mTryingToConnect = false;
if (i ==
GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Google Fit Connection lost.
Cause:Network Lost.");
} else if (i ==
GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG, "Google Fit Connection lost.
Reason:Service Disconnected ");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
@Override
public void onConnectionFailed(ConnectionResult
result) {
mTryingToConnect = false;
notifyUiFailedConnection(result);
}
}
)
.build();
}
private void notifyUiFitConnected() {
Intent intent = new Intent(FIT_NOTIFY_INTENT);
intent.putExtra(FIT_EXTRA_CONNECTION_MESSAGE,
FIT_EXTRA_CONNECTION_MESSAGE);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void notifyUiFailedConnection(ConnectionResult result) {
Intent intent = new Intent(FIT_NOTIFY_INTENT);
intent.putExtra(FIT_EXTRA_NOTIFY_FAILED_STATUS_CODE,
result.getErrorCode());
intent.putExtra(FIT_EXTRA_NOTIFY_FAILED_INTENT, result.getResolution());
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
何がうまくいかなかったのでしょうか?ありがとう、テオ。