gpt4 book ai didi

android - 使用 IntentService 和 ActivityRecognition 更新 UI

转载 作者:行者123 更新时间:2023-11-30 03:24:22 26 4
gpt4 key购买 nike

我正在为位置使用新的 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com