我一直在研究这款应用。 它只是不会执行。 每次都崩溃。请帮忙。
的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidrecipes.usermotionactivity"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.androidrecipes.usermotionactivity.UserMotionService" />
</application>
</manifest>
UserMotionService.java
package com.androidrecipes.usermotionactivity;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
import android.app.IntentService;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
public class UserMotionService extends IntentService {
private static final String TAG = "UserMotionService";
/*
* Callback interface for detected activity type changes
*/
public interface OnActivityChangedListener{
public void onUserActivityChanged(int bestChoice, int bestConfidence,
ActivityRecognitionResult newActivity);
}
/* Last detected activity type */
private DetectedActivity mLastKnownActivity;
/*
* Marshals requests from the background thread so the callbacks
* can be made on the main (UI) thread.
*/
private CallbackHandler mHandler;
private static class CallbackHandler extends Handler {
/* Callback for activity changes */
private OnActivityChangedListener mCallback;
public void setCallback(OnActivityChangedListener callback) {
mCallback = callback;
}
@Override
public void handleMessage(Message msg) {
if (mCallback != null) {
//Read payload data out of the message and fire callback
ActivityRecognitionResult newActivity = (ActivityRecognitionResult) msg.obj;
mCallback.onUserActivityChanged(msg.arg1, msg.arg2, newActivity);
}
}
}
public UserMotionService() {
//String is used to name the background thread created
super("UserMotionService");
mHandler = new CallbackHandler();
}
public void setOnActivityChangedListener(OnActivityChangedListener listener) {
mHandler.setCallback(listener);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.w(TAG, "Service is stopping...");
}
/*
* Incoming action events from the framework will come
* in here. This is called on a background thread, so
* we can do long processing here if we wish.
*/
@Override
protected void onHandleIntent(Intent intent) {
if (ActivityRecognitionResult.hasResult(intent)) {
//Extract the result from the Intent
ActivityRecognitionResult result =
ActivityRecognitionResult.extractResult(intent);
DetectedActivity activity = result.getMostProbableActivity();
Log.v(TAG, "New User Activity Event");
//If the highest probability is UNKNOWN, but the confidence is low,
// check if another exists and select it instead
if (activity.getType() == DetectedActivity.UNKNOWN
&& activity.getConfidence() < 60
&& result.getProbableActivities().size() > 1) {
//Select the next probable element
activity = result.getProbableActivities().get(1);
}
//On a change in activity, alert the callback
if (mLastKnownActivity == null
|| mLastKnownActivity.getType() != activity.getType()
|| mLastKnownActivity.getConfidence() != activity.getConfidence()) {
//Pass the results to the main thread inside a Message
Message msg = Message.obtain(null,
0, //what
activity.getType(), //arg1
activity.getConfidence(), //arg2
result);
mHandler.sendMessage(msg);
}
mLastKnownActivity = activity;
}
}
/*
* This is called when the Activity wants to bind to the
* service. We have to provide a wrapper around this instance
* to pass it back.
*/
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/*
* This is a simple wrapper that we can pass to the Activity
* to allow it direct access to this service.
*/
private LocalBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public UserMotionService getService() {
return UserMotionService.this;
}
}
/*
* Utility to get a good display name for each state
*/
public static String getActivityName(DetectedActivity activity) {
switch(activity.getType()) {
case DetectedActivity.IN_VEHICLE:
return "Driving";
case DetectedActivity.ON_BICYCLE:
return "Biking";
case DetectedActivity.ON_FOOT:
return "Walking";
case DetectedActivity.STILL:
return "Not Moving";
case DetectedActivity.TILTING:
return "Tilting";
case DetectedActivity.UNKNOWN:
default:
return "No Clue";
}
}
}
MainActivity.java
package com.androidrecipes.usermotionactivity;
import com.androidrecipes.usermotionactivity.UserMotionService.LocalBinder;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.ActivityRecognitionClient;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements
ServiceConnection,
UserMotionService.OnActivityChangedListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private static final String TAG = "UserActivity";
private Intent mServiceIntent;
private PendingIntent mCallbackIntent;
private UserMotionService mService;
private ActivityRecognitionClient mRecognitionClient;
//Custom list adapter to display our results
private ActivityAdapter mListAdapter;
private View mBlockingView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBlockingView = findViewById(R.id.blocker);
//Construct a simple list adapter that will display all the
// incoming activity change events from the service.
ListView list = (ListView) findViewById(R.id.list);
mListAdapter = new ActivityAdapter(this);
list.setAdapter(mListAdapter);
//When the list is clicked, display all the probable activities
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
showDetails(mListAdapter.getItem(position));
}
});
//Check if Google Play Services is up to date.
switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this)) {
case ConnectionResult.SUCCESS:
//Do nothing, move on
break;
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
Toast.makeText(this,
"Activity service requires an update, please open Google Play.",
Toast.LENGTH_SHORT).show();
finish();
return;
default:
Toast.makeText(this,
"Activity service is not available on this device.",
Toast.LENGTH_SHORT).show();
finish();
return;
}
//Create a client instance for talking to Google Services
mRecognitionClient = new ActivityRecognitionClient(this, this, this);
//Create an Intent to bind to the service
mServiceIntent = new Intent(this, UserMotionService.class);
//Create a PendingIntent that Google Services will use for callbacks
mCallbackIntent = PendingIntent.getService(this, 0,
mServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
protected void onResume() {
super.onResume();
//Connect to Google Services and our Service
mRecognitionClient.connect();
bindService(mServiceIntent, this, BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
//Disconnect from all services
mRecognitionClient.removeActivityUpdates(mCallbackIntent);
mRecognitionClient.disconnect();
disconnectService();
unbindService(this);
}
/** ServiceConnection Methods */
public void onServiceConnected(ComponentName name, IBinder service) {
//Attach ourselves to our Service as a callback for events
mService = ((LocalBinder) service).getService();
mService.setOnActivityChangedListener(this);
}
@Override
public void onServiceDisconnected(ComponentName name) {
disconnectService();
}
private void disconnectService() {
if (mService != null) {
mService.setOnActivityChangedListener(null);
}
mService = null;
}
/** Google Services Connection Callbacks */
@Override
public void onConnected(Bundle connectionHint) {
//We must wait until the services are connected
// to request any updates.
mRecognitionClient.requestActivityUpdates(5000, mCallbackIntent);
}
@Override
public void onDisconnected() {
Log.w(TAG, "Google Services Disconnected");
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.w(TAG, "Google Services Connection Failure");
}
/** OnActivityChangedListener Methods */
@Override
public void onUserActivityChanged(int bestChoice, int bestConfidence,
ActivityRecognitionResult newActivity) {
//Add latest event to the list
mListAdapter.add(newActivity);
mListAdapter.notifyDataSetChanged();
//Determine user action based on our custom algorithm
switch (bestChoice) {
case DetectedActivity.IN_VEHICLE:
case DetectedActivity.ON_BICYCLE:
mBlockingView.setVisibility(View.VISIBLE);
break;
case DetectedActivity.ON_FOOT:
case DetectedActivity.STILL:
mBlockingView.setVisibility(View.GONE);
break;
default:
//Ignore other states
break;
}
}
/*
* Utility that builds a simple Toast with all the probable
* activity choices with their confidence values
*/
private void showDetails(ActivityRecognitionResult activity) {
StringBuilder sb = new StringBuilder();
sb.append("Details:");
for(DetectedActivity element : activity.getProbableActivities()) {
sb.append("\n"+UserMotionService.getActivityName(element)
+ ", " + element.getConfidence() + "% sure");
}
Toast.makeText(this, sb.toString(), Toast.LENGTH_SHORT).show();
}
/*
* ListAdapter to display each activity result we receive from the service
*/
private static class ActivityAdapter extends ArrayAdapter<ActivityRecognitionResult> {
public ActivityAdapter(Context context) {
super(context, android.R.layout.simple_list_item_1);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
}
//Display the most probable activity with its confidence in the list
TextView tv = (TextView) convertView;
ActivityRecognitionResult result = getItem(position);
DetectedActivity newActivity = result.getMostProbableActivity();
String entry = DateFormat.format("hh:mm:ss", result.getTime())
+ ": " + UserMotionService.getActivityName(newActivity) + ", "
+ newActivity.getConfidence() + "% confidence";
tv.setText(entry);
return convertView;
}
}
}
logcat的:
09-02 10:29:16.635: D/dalvikvm(1867): GC_FOR_ALLOC freed 42K, 4% free 2901K/3008K, paused 151ms, total 152ms
09-02 10:29:16.635: I/dalvikvm-heap(1867): Grow heap (frag case) to 3.500MB for 635808-byte allocation
09-02 10:29:16.755: D/dalvikvm(1867): GC_FOR_ALLOC freed 2K, 4% free 3520K/3632K, paused 117ms, total 117ms
09-02 10:29:17.495: D/AndroidRuntime(1867): Shutting down VM
09-02 10:29:17.535: W/dalvikvm(1867): threadid=1: thread exiting with uncaught exception (group=0xb2d74b20)
09-02 10:29:17.675: E/AndroidRuntime(1867): FATAL EXCEPTION: main
09-02 10:29:17.675: E/AndroidRuntime(1867): Process: com.androidrecipes.usermotionactivity, PID: 1867
09-02 10:29:17.675: E/AndroidRuntime(1867): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androidrecipes.usermotionactivity/com.androidrecipes.usermotionactivity.MainActivity}: java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist. You must have the following declaration within the <application> element: <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.ActivityThread.access$800(ActivityThread.java:135)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.os.Handler.dispatchMessage(Handler.java:102)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.os.Looper.loop(Looper.java:136)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.ActivityThread.main(ActivityThread.java:5017)
09-02 10:29:17.675: E/AndroidRuntime(1867): at java.lang.reflect.Method.invokeNative(Native Method)
09-02 10:29:17.675: E/AndroidRuntime(1867): at java.lang.reflect.Method.invoke(Method.java:515)
09-02 10:29:17.675: E/AndroidRuntime(1867): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
09-02 10:29:17.675: E/AndroidRuntime(1867): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
09-02 10:29:17.675: E/AndroidRuntime(1867): at dalvik.system.NativeStart.main(Native Method)
09-02 10:29:17.675: E/AndroidRuntime(1867): Caused by: java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist. You must have the following declaration within the <application> element: <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
09-02 10:29:17.675: E/AndroidRuntime(1867): at com.google.android.gms.common.GooglePlayServicesUtil.A(Unknown Source)
09-02 10:29:17.675: E/AndroidRuntime(1867): at com.google.android.gms.common.GooglePlayServicesUtil.isGooglePlayServicesAvailable(Unknown Source)
09-02 10:29:17.675: E/AndroidRuntime(1867): at com.androidrecipes.usermotionactivity.MainActivity.onCreate(MainActivity.java:69)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.Activity.performCreate(Activity.java:5231)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-02 10:29:17.675: E/AndroidRuntime(1867): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
09-02 10:29:17.675: E/AndroidRuntime(1867): ... 11 more
我已经包含了必要的权限,代码中没有错误。 然而它说&#34;不幸的是,UserMotion已经停止&#34;。 请帮忙。
答案 0 :(得分:0)
此错误是由于清单
中标记内的此标记丢失所致<application>
....
....
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</appliacation