让GoogleApiClient与Activity Recognition配合使用

时间:2015-01-05 12:54:38

标签: java android eclipse google-api-client activity-recognition

我目前正在使用 ActivityRecognitionClient ,但不幸的是,谷歌宣布该课程已被弃用并使用 GoogleApiClient 而不是。

不确定我是否做错了,我对新的API文件感到困惑。我导入了Google Play库,设置了API v2密钥。我关注编码 ActivityRecognitionClient 版本的在线资源。

下面是不同文件的代码,每当我将tab切换到actRecog时,它就会崩溃并将错误指向此行,并带有空指针异常。

mActivityRecognitionPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 

以下完整源代码:(出于隐私目的,故意隐藏API v2密钥。)

MainActivity.java

package com.example.healthgps;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.app.Activity;
import android.app.TabActivity;
import android.content.Context;
import android.content.Intent;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;

public class MainActivity extends TabActivity  {

TabHost mTabHost;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);


    setContentView(R.layout.activity_main);
    mTabHost = getTabHost();

    TabSpec firstSpec = mTabHost.newTabSpec("Stats");
    firstSpec.setIndicator("Stats");
    Intent firstIntent = new Intent(this, FirstActivity.class);
    firstSpec.setContent(firstIntent);

    TabSpec thirdSpec = mTabHost.newTabSpec("ActRecog");
    thirdSpec.setIndicator("ActRecog");
    Intent thirdIntent = new Intent(this, activityrecignition.class);
    thirdSpec.setContent(thirdIntent);

    mTabHost.addTab(firstSpec);
    mTabHost.addTab(thirdSpec);

  }

}

清单XML文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.healthgps"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="17" />

    <permission 
        android:name="com.example.healthgps.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
    <uses-permission android:name="com.example.healthgps.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />



    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />


        <activity
            android:name="com.example.healthgps.MainActivity"
            android:label="Health Kit" 
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".FirstActivity"
            android:label="Health Kit" >
        </activity>
        <activity
            android:name=".activityrecignition"
            android:label="Health Kit" >
        </activity>

        <service
            android:name="com.example.healthgps.ActivityRecognitionIntentService"
            android:label="@string/app_name"
            android:exported="false">
        </service>


    <meta-data  
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    </application>
</manifest>

activityrecignition.java(故意输入名称)

package com.example.healthgps;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.ActivityRecognition;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;


public class activityrecignition extends FragmentActivity implements  ConnectionCallbacks,OnConnectionFailedListener {

 public static final int MILLISECONDS_PER_SECOND = 1000;
    public static final int DETECTION_INTERVAL_SECONDS = 20;
    public static final int DETECTION_INTERVAL_MILLISECONDS =
            MILLISECONDS_PER_SECOND * DETECTION_INTERVAL_SECONDS;
  private final static int
  CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

  private PendingIntent mActivityRecognitionPendingIntent;
    // Store the current activity recognition client

    private GoogleApiClient mGoogleApiClient;

    private Context mContext;
    private Intent intent;
    TextView tv;
     ActivityRecognitionIntentService ar;

    private boolean mInProgress;

    public enum REQUEST_TYPE {START, STOP}
    private REQUEST_TYPE mRequestType;
    Intent i;
    @Override
   protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.third);

    mActivityRecognitionPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    tv=(TextView) findViewById(R.id.activityname);
    mInProgress=false;
    ar.onHandleIntent(i);
}

@SuppressLint("NewApi") public static class ErrorDialogFragment extends DialogFragment {

 private Dialog mDialog;
 @SuppressLint("NewApi") public ErrorDialogFragment() {
  super();
  mDialog = null;
}

 public void setDialog(Dialog dialog) {
  mDialog = dialog;
}

  @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {
  return mDialog;
}
public void show(FragmentManager supportFragmentManager, String tag) {


}
 }
@Override
 protected void onActivityResult(
   int requestCode, int resultCode, Intent data) {
  switch (requestCode) {

  case CONNECTION_FAILURE_RESOLUTION_REQUEST :
      switch (resultCode) {
          case Activity.RESULT_OK :


          break;
      }

}

}

private boolean servicesConnected() {

 int resultCode =
      GooglePlayServicesUtil.
              isGooglePlayServicesAvailable(this);

 if (ConnectionResult.SUCCESS == resultCode) {
     Log.d("Activity Recognition", "Google Play services is available.");
  return true;
 } else {
    Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
          resultCode,
          this,
          CONNECTION_FAILURE_RESOLUTION_REQUEST);


  if (errorDialog != null) {
      // Create a new DialogFragment for the error dialog
      ErrorDialogFragment errorFragment = new ErrorDialogFragment();
      // Set the dialog in the DialogFragment
      errorFragment.setDialog(errorDialog);
      // Show the error dialog in the DialogFragment
      errorFragment.show(
              getSupportFragmentManager(),
              "Activity Recognition");
  }
  return false;
 }
}
public class ActivityRecognitionIntentService extends IntentService {

public ActivityRecognitionIntentService(String name) {
    super(name);
    // TODO Auto-generated constructor stub
}
private String getNameFromType(int activityType) {
    switch(activityType) {
        case DetectedActivity.IN_VEHICLE:
            return "in_vehicle";
        case DetectedActivity.ON_BICYCLE:
            return "on_bicycle";
        case DetectedActivity.ON_FOOT:
            return "on_foot";
        case DetectedActivity.STILL:
            return "still";
        case DetectedActivity.UNKNOWN:
            return "unknown";
        case DetectedActivity.TILTING:
            return "tilting";
    }
    return "unknown";
}
@Override
protected void onHandleIntent(Intent intent) {

    // If the incoming intent contains an update
    if (ActivityRecognitionResult.hasResult(intent)) {
        // Get the update
        ActivityRecognitionResult result =
                ActivityRecognitionResult.extractResult(intent);
        // Get the most probable activity
        DetectedActivity mostProbableActivity =
                result.getMostProbableActivity();
        /*
         * Get the probability that this activity is the
         * the user's actual activity
         */
        int confidence = mostProbableActivity.getConfidence();
        /*
         * Get an integer describing the type of activity
         */
        int activityType = mostProbableActivity.getType();
        String activityName = getNameFromType(activityType);
        tv.setText(activityName);
        /*
         * At this point, you have retrieved all the information
         * for the current update. You can display this
         * information to the user in a notification, or
         * send it to an Activity or Service in a broadcast
         * Intent.
         */

    } else {
        /*
         * This implementation ignores intents that don't contain
         * an activity update. If you wish, you can report them as
         * errors.
         */
        tv.setText("There are no updates!!!");
    }

}

}

public void onClick(View v){
    if(v.getId()==R.id.Start){
        startUpdates();
    }
    if(v.getId()==R.id.Stop){
        stopUpdates();
    }
}

public void startUpdates() {
    // Check for Google Play services
    mRequestType = REQUEST_TYPE.START;

    if (!servicesConnected()) {
        return;
    }
    // If a request is not already underway
    if (!mInProgress) {
        // Indicate that a request is in progress
        mInProgress = true;
        // Request a connection to Location Services
        mGoogleApiClient.connect();
    //
    } else {
        /*
         * A request is already underway. You can handle
         * this situation by disconnecting the client,
         * re-setting the flag, and then re-trying the
         * request.
         */

        mInProgress = true;
        mGoogleApiClient.disconnect();
        ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
    }
}



@Override
public void onConnected(Bundle dataBundle) {
    // TODO Auto-generated method stub

    ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
        /*
         * Since the preceding call is synchronous, turn off the
         * in progress flag and disconnect the client
         */
        mInProgress = false;
        mGoogleApiClient.disconnect();
        switch (mRequestType) {
        case START :
            /*
             * Request activity recognition updates using the
             * preset detection interval and PendingIntent.
             * This call is synchronous.
             */
            ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
            break;
        case STOP :
            ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(mGoogleApiClient, mActivityRecognitionPendingIntent);

            /*
             * An enum was added to the definition of REQUEST_TYPE,
             * but it doesn't match a known case. Throw an exception.
             */
            default :
            try {
                throw new Exception("Unknown request type in onConnected().");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
    }
}

@Override
public void onDisconnected() {
    // TODO Auto-generated method stub
    mInProgress = false;

}

 @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // Turn off the request flag
        mInProgress = false;
        /*
         * If the error has a resolution, start a Google Play services
         * activity to resolve it.
         */
        if (connectionResult.hasResolution()) {
            try {
                connectionResult.startResolutionForResult(
                        this,
                        CONNECTION_FAILURE_RESOLUTION_REQUEST);
            } catch (SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        // If no resolution is available, display an error dialog
        } else {
            // Get the error code
            int errorCode = connectionResult.getErrorCode();
            // Get the error dialog from Google Play services
            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                    errorCode,
                    this,
                    CONNECTION_FAILURE_RESOLUTION_REQUEST);
            // If Google Play services can provide an error dialog
            if (errorDialog != null) {
                // Create a new DialogFragment for the error dialog
                ErrorDialogFragment errorFragment =
                        new ErrorDialogFragment();
                // Set the dialog in the DialogFragment
                errorFragment.setDialog(errorDialog);
                // Show the error dialog in the DialogFragment
                errorFragment.show(
                        getSupportFragmentManager(),
                        "Activity Recognition");
            }
        }

    }



 public void stopUpdates() {
        // Set the request type to STOP
        mRequestType = REQUEST_TYPE.STOP;
        /*
         * Test for Google Play services after setting the request type.
         * If Google Play services isn't present, the request can be
         * restarted.
         */
        if (!servicesConnected()) {
            return;
        }
        // If a request is not already underway
        if (!mInProgress) {
            // Indicate that a request is in progress
            mInProgress = true;
            // Request a connection to Location Services
            mGoogleApiClient.connect();
        //
        } else {
            /*
             * A request is already underway. You can handle
             * this situation by disconnecting the client,
             * re-setting the flag, and then re-trying the
             * request.
             */
        }

    }
}

在旧代码中,它包含 ActivityRecognitionClient 需要实例化的部分,但 GoogleApiClient 不会没有。

是否有人设法切换到新的API?我需要一些指南来实现它。 感谢。

1 个答案:

答案 0 :(得分:4)

您必须按以下方式使用GoogleApiClient.Builder

GoogleApiClient.Builder builder = new GoogleApiClient.Builder(<context>)
            .addApi(<some api, i.e LocationServices.API>)
            .addConnectionCallbacks(new ConnectionCallbacks() {

                @Override
                public void onConnectionSuspended(int arg) {}

                @Override
                public void onConnected(Bundle arg0) {
                    Intent intent = new Intent(getApplicationContext(),      ActivityRecognitionService.class); // your custom ARS class
                    mPendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);

            ActivityRecognition.ActivityRecognitionApi
                    .requestActivityUpdates(mGoogleApiClient, ACTIVITY_RECOGNITION_INTERVAL, mPendingIntent);}

            }
            .addOnConnectionFailedListener(new OnConnectionFailedListener() {

                @Override
                public void onConnectionFailed(ConnectionResult arg0) {

                }
            });

mGoogleApiClient = builder.build();

mGoogleApiClient.connect();