- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为位置使用新的 API 并尝试 ActivityRecognition。我使用了 Google Developers Training 上的代码库在我想更新 UI 之前,一切都很顺利。 (我知道您不能直接在服务上更新 UI,这就是我使用处理程序/接口(interface)/其他东西的原因。)我尝试了什么:
使用接口(interface),但这没有用,因为我没有找到从 IntentService 获取 Activity 上下文的方法。
还尝试将处理程序传递给 IntentService,以便它发送带有操作的消息,但出于某种原因,每当它到达对此的调用时:
// If the intent contains an update
if (ActivityRecognitionResult.hasResult(intent)) {
这只会返回 false,因为我将信使与处理程序一起传递。如果我删除添加包含消息的额外内容的行,它就可以正常工作,但我无法更新我的 UI。
我尝试在启动服务之前删除多余的内容,但没有成功。任何想法我应该如何解决这个问题?
这些是我的代码:
Activity :
public class MainActivity 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 ActivityRecognitionClient mActivityRecognitionClient;
private Context mContext;
// Flag that indicates if a request is underway.
private boolean mInProgress;
private static final String TAG = "MainActivity";
public static final String KEY_ACTION = "user_action";
public enum REQUEST_TYPE {START, STOP}
private REQUEST_TYPE mRequestType;
private TextView tvAction;
//FIXME I'm aware of this potential leak
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Bundle reply = msg.getData();
final String userAction = reply.getString(KEY_ACTION);
tvAction.setText("You are now: "+userAction);
// do whatever with the bundle here
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
tvAction = (TextView)findViewById(R.id.tv_action);
// Start with the request flag set to false
mInProgress = false;
mActivityRecognitionClient =
new ActivityRecognitionClient(mContext, this, this);
Intent intent = new Intent(
mContext, ActivityRecognitionIntentService.class);
//putting this will make return false.
intent.putExtra("messenger", new Messenger(handler));
mActivityRecognitionPendingIntent =
PendingIntent.getService(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
private void startUpdates() {
mRequestType = REQUEST_TYPE.START;
// Check for Google Play services
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
mActivityRecognitionClient.connect();
//
}
}
private 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
mActivityRecognitionClient.connect();
//
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST:
/*
* If the result code is Activity.RESULT_OK, try to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK:
/*
* Try the request again
*/
break;
}
}
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Activity Recognition", "Google Play services is available.");
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(resultCode, 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");
}
return false;
}
}
// Define a DialogFragment that displays the error dialog
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
// Default constructor. Sets the dialog field to null
public ErrorDialogFragment() {
super();
mDialog = null;
}
// Set the dialog to display
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
// Return a Dialog to the DialogFragment.
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
@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");
}
}
}
@Override
public void onConnected(Bundle arg0) {
switch (mRequestType) {
case START:
/*
* Request activity recognition updates using the preset
* detection interval and PendingIntent. This call is
* synchronous.
*/
mActivityRecognitionClient.requestActivityUpdates(
DETECTION_INTERVAL_MILLISECONDS,
mActivityRecognitionPendingIntent);
break;
case STOP :
mActivityRecognitionClient.removeActivityUpdates(
mActivityRecognitionPendingIntent);
break;
default :
Log.e(TAG, "Unknown request type in onConnected().");
break;
}
/*
* Since the preceding call is synchronous, turn off the
* in progress flag and disconnect the client
*/
mInProgress = false;
mActivityRecognitionClient.disconnect();
}
@Override
public void onDisconnected() {
// Turn off the request flag
mInProgress = false;
// Delete the client
mActivityRecognitionClient = null;
}
@Override
protected void onPause() {
super.onPause();
stopUpdates();
}
@Override
protected void onResume() {
super.onResume();
startUpdates();
}
@Override
protected void onStop() {
super.onStop();
stopUpdates();
}
}
Intent 服务
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
public class ActivityRecognitionIntentService extends IntentService {
// Formats the timestamp in the log
private static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss.SSSZ";
private static final String TAG = "ActivityRecognitionIntentService";
private static final String SHARED_PREFERENCES = "ActivityRecognition";
private static final String KEY_PREVIOUS_ACTIVITY_TYPE = "KEY_PREVIOUS_ACTIVITY_TYPE";
// A date formatter
private SimpleDateFormat mDateFormat;
// Store the app's shared preferences repository
private SharedPreferences mPrefs;
protected Messenger messenger;
public ActivityRecognitionIntentService() {
// Set the label for the service's background thread
super("ActivityRecognitionIntentService");
}
public ActivityRecognitionIntentService(String name) {
super(name);
}
@Override
public void onStart(Intent intent, int startId) {
Bundle extras = intent.getExtras();
messenger = (Messenger) extras.get("messenger");
intent.removeExtra("messenger");
super.onStart(intent, startId);
}
/**
* Called when a new activity detection update is available.
*/
@Override
protected void onHandleIntent(Intent intent) {
// Get a handle to the repository
Context mContext = getApplicationContext();
mPrefs = mContext.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
// Get a date formatter, and catch errors in the returned timestamp
try {
mDateFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance();
} catch (Exception e) {
Log.e(TAG, getString(R.string.date_format_error));
}
// Format the timestamp according to the pattern, then localize the
// pattern
mDateFormat.applyPattern(DATE_FORMAT_PATTERN);
mDateFormat.applyLocalizedPattern(mDateFormat.toLocalizedPattern());
// If the intent contains an update
if (ActivityRecognitionResult.hasResult(intent)) {
// Get the update
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
// Get the most probable activity from the list of activities in the
// update
DetectedActivity mostProbableActivity = result.getMostProbableActivity();
// Get the confidence percentage for the most probable activity
int confidence = mostProbableActivity.getConfidence();
// Get the type of activity
int activityType = mostProbableActivity.getType();
// Check to see if the repository contains a previous activity
if (!mPrefs.contains(KEY_PREVIOUS_ACTIVITY_TYPE)) {
// This is the first type an activity has been detected. Store
// the type
Editor editor = mPrefs.edit();
editor.putInt(KEY_PREVIOUS_ACTIVITY_TYPE, activityType);
editor.commit();
// If the repository contains a type
} else if (
// The confidence level for the current activity is > 50%
(confidence >= 50)) {
// Notify the user
final String userAction = getNameFromType(activityType);
sendNotification(userAction);
if (messenger != null) {
Message msg = Message.obtain();
Bundle data = new Bundle();
data.putString(MainActivity.KEY_ACTION, userAction);
msg.setData(data); //put the data here
try {
messenger.send(msg);
} catch (RemoteException e) {
Log.i("error", "error");
}
}
}
}
}
/**
* Post a notification to the user. The notification prompts the user to
* click it to open the device's GPS settings
*/
private void sendNotification(String type) {
// Create a notification builder that's compatible with platforms >=
// version 4
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
// Set the title, text, and icon
builder.setContentTitle(getString(R.string.app_name)).setContentText(type)// getString(R.string.turn_on_GPS))
.setSmallIcon(R.drawable.ic_launcher)
// Get the Intent that starts the Location settings panel
.setContentIntent(getContentIntent());
// Get an instance of the Notification Manager
NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Build the notification and post it
notifyManager.notify(0, builder.build());
}
/**
* Get a content Intent for the notification
*
* @return A PendingIntent that starts the device's Location Settings panel.
*/
private PendingIntent getContentIntent() {
// Set the Intent action to open Location Settings
Intent gpsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
// Create a PendingIntent to start an Activity
return PendingIntent.getActivity(getApplicationContext(), 0, gpsIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/**
* Map detected activity types to strings
*
* @param activityType
* The detected activity type
* @return A user-readable name for the type
*/
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";
}
}
最佳答案
IntentService 不允许更新 UI,因为它们旨在运行后台任务。
您应该改为基于通知设计您的服务界面,当点击通知时可以打开应用 Activity 以显示有关服务状态的详细信息。
关于android - 使用 IntentService 和 ActivityRecognition 更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18523336/
我很想知道 GooglePlay 服务中的 ActivityRecognition 是如何工作的? 我认为加速度计数据可以识别 Activity 。对吗?请告诉我详细情况如何? 最佳答案 我也在寻找这
我已经将这段代码放在一起来获取用户 Activity ,看看他是走路还是开车还是静止不动,但它不起作用,onHandleIntent 从未调用过。它正在连接到 GoogleApiClient。 这是我
我希望使用 Google Play 服务 ActivityRecognition API作为 Android 应用程序的一部分,该应用程序的大部分使用都将处于离线状态;用户通常会出门在外,并且无法保证
根据我的研究,我意识到 Google 的 Activity Recognition API 允许您检测手机用户正在进行的 Activity (步行、驾驶等),但我想检测过渡中的变化。我想知道这种转
我有一个使用 ActivityRecognition 的 DetectedActivities 的广播接收器。我注意到它确实连接了,但我没有收到任何数据。这是在三星 Note 2 上。在我试过的其他手
我正在使用 ActivityRecognitionClient 类来获取用户 Activity 的数据,无论他是走路、运行还是骑自行车等...... 问题在于使用 PendingIntent,所以我可
有没有什么好的方法可以模拟DetectedActivity.IN_VEHICLE在 Android 模拟器中。目前,我正在尝试获取 ActivityRecognitionApi通过 telnet 发送
我正在为位置使用新的 API 并尝试 ActivityRecognition。我使用了 Google Developers Training 上的代码库在我想更新 UI 之前,一切都很顺利。 (我知道
我正在寻找实现这个的通用设计: 我想注册到 ActivityRecognition API 以接收此 API 不时调用的 IntentService 中的定期更新,而我的应用程序中的其他所有内容都完全
我是一名优秀的程序员,十分优秀!