活动识别在电话进入待机状态时停止接收更新(屏幕closures状态)

我在活动识别方面遇到了一些麻烦。 我已经在一个应用程序中实现它,并且在设备的屏幕打开时工作正常。 我有一个在我的活动识别意图服务类中的日志条目,我可以看到它什么时候得到一个更新。所以,我知道它是工作正常,当屏幕上。

但是,当手机进入待机状态(屏幕closures)后,它会停止检测使用活动。

DetectionRequester类中的onDisconnected()没有被调用,我使用日志文件进行检查。

我的问题:为什么我的应用程序在设备进入待机模式后,会停止跟踪使用情况? 我如何使它不停止检测用户活动?

让我知道,如果你需要看到任何代码,或者如果你需要我的应用程序的任何更多的细节。

来自我的MainActivity类的相关代码。 这是应用程序启动ActivityRecognition请求的地方。

public class MainActivity extends FragmentActivity { // The activity recognition update request object private DetectionRequester mDetectionRequester; // The activity recognition update removal object private DetectionRemover mDetectionRemover; // Store the current request type (ADD or REMOVE) private REQUEST_TYPE mRequestType; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Crashlytics.start(this); setContentView(R.layout.activity_main); mDetectionRequester = new DetectionRequester(this); mDetectionRemover = new DetectionRemover(this); // Check for Google Play services if (servicesConnected()) { /* *Set the request type. If a connection error occurs, and Google Play services can * handle it, then onActivityResult will use the request type to retry the request */ mRequestType = ActivityUtils.REQUEST_TYPE.ADD; // Pass the update request to the requester object mDetectionRequester.requestUpdates(); } } private boolean servicesConnected() { Log.wtf("Rakshak", "Service connected method"); // Check that Google Play services is available int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); // If Google Play services is available if (ConnectionResult.SUCCESS == resultCode) { Log.wtf("Rakshak", "Service connected method: connection result success"); // Continue return true; // Google Play services was not available for some reason } else { Log.wtf("Rakshak", "Service connected method: connection result failure"); // Display an error dialog GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0).show(); return false; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // Choose what to do based on the request code switch (requestCode) { // If the request code matches the code sent in onConnectionFailed case ActivityUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST : switch (resultCode) { // If Google Play services resolved the problem case Activity.RESULT_OK: // If the request was to start activity recognition updates if (ActivityUtils.REQUEST_TYPE.ADD == mRequestType) { // Restart the process of requesting activity recognition updates mDetectionRequester.requestUpdates(); // If the request was to remove activity recognition updates } else if (ActivityUtils.REQUEST_TYPE.REMOVE == mRequestType ){ /* * Restart the removal of all activity recognition updates for the * PendingIntent. */ // mDetectionRemover.removeUpdates( // mDetectionRequester.getRequestPendingIntent()); } break; // If any other result was returned by Google Play services default: // Report that Google Play services was unable to resolve the problem. Log.d(ActivityUtils.APPTAG, "unable to resolve Google play services problems"); } // If any other request code was received default: // Report that this Activity received an unknown requestCode Log.d(ActivityUtils.APPTAG, "received an unknown request code"); break; } } 

我的DetectionRequester类:

 public class DetectionRequester implements ConnectionCallbacks, OnConnectionFailedListener { // Storage for a context from the calling client private Context mContext; // Stores the PendingIntent used to send activity recognition events back to the app private PendingIntent mActivityRecognitionPendingIntent; // Stores the current instantiation of the activity recognition client private ActivityRecognitionClient mActivityRecognitionClient; public DetectionRequester(Context context) { // Save the context mContext = context; // Initialize the globals to null mActivityRecognitionPendingIntent = null; mActivityRecognitionClient = null; } /** * Returns the current PendingIntent to the caller. * * @return The PendingIntent used to request activity recognition updates */ public PendingIntent getRequestPendingIntent() { return mActivityRecognitionPendingIntent; } /** * Sets the PendingIntent used to make activity recognition update requests * @param intent The PendingIntent */ public void setRequestPendingIntent(PendingIntent intent) { mActivityRecognitionPendingIntent = intent; } /** * Start the activity recognition update request process by * getting a connection. */ public void requestUpdates() { requestConnection(); } /** * Make the actual update request. This is called from onConnected(). */ private void continueRequestActivityUpdates() { /* * Request updates, using the default detection interval. * The PendingIntent sends updates to ActivityRecognitionIntentService */ getActivityRecognitionClient().requestActivityUpdates( ActivityUtils.DETECTION_INTERVAL_MILLISECONDS, createRequestPendingIntent()); // Disconnect the client requestDisconnection(); } /** * Request a connection to Location Services. This call returns immediately, * but the request is not complete until onConnected() or onConnectionFailure() is called. */ private void requestConnection() { getActivityRecognitionClient().connect(); } /** * Get the current activity recognition client, or create a new one if necessary. * This method facilitates multiple requests for a client, even if a previous * request wasn't finished. Since only one client object exists while a connection * is underway, no memory leaks occur. * * @return An ActivityRecognitionClient object */ private ActivityRecognitionClient getActivityRecognitionClient() { if (mActivityRecognitionClient == null) { mActivityRecognitionClient = new ActivityRecognitionClient(mContext, this, this); } return mActivityRecognitionClient; } /** * Get the current activity recognition client and disconnect from Location Services */ private void requestDisconnection() { getActivityRecognitionClient().disconnect(); } /* * Called by Location Services once the activity recognition client is connected. * * Continue by requesting activity updates. */ @Override public void onConnected(Bundle arg0) { // If debugging, log the connection Log.w("Rakshak", "Locatin client connected"); // Continue the process of requesting activity recognition updates continueRequestActivityUpdates(); } /* * Called by Location Services once the activity recognition client is disconnected. */ @Override public void onDisconnected() { // In debug mode, log the disconnection Log.w("Rakshak", "Locatin client dis-connected"); // Destroy the current activity recognition client mActivityRecognitionClient = null; } /** * Get a PendingIntent to send with the request to get activity recognition updates. Location * Services issues the Intent inside this PendingIntent whenever a activity recognition update * occurs. * * @return A PendingIntent for the IntentService that handles activity recognition updates. */ private PendingIntent createRequestPendingIntent() { // If the PendingIntent already exists if (null != getRequestPendingIntent()) { // Return the existing intent return mActivityRecognitionPendingIntent; // If no PendingIntent exists } else { // Create an Intent pointing to the IntentService Intent intent = new Intent(mContext, ActivityRecognitionIntentService.class); /* * Return a PendingIntent to start the IntentService. * Always create a PendingIntent sent to Location Services * with FLAG_UPDATE_CURRENT, so that sending the PendingIntent * again updates the original. Otherwise, Location Services * can't match the PendingIntent to requests made with it. */ PendingIntent pendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); setRequestPendingIntent(pendingIntent); return pendingIntent; } } /* * Implementation of OnConnectionFailedListener.onConnectionFailed * If a connection or disconnection request fails, report the error * connectionResult is passed in from Location Services */ @Override public void onConnectionFailed(ConnectionResult connectionResult) { /* * Google Play services can resolve some errors it detects. * If the error has a resolution, try sending an Intent to * start a Google Play services activity that can resolve * error. */ if (connectionResult.hasResolution()) { try { connectionResult.startResolutionForResult((Activity) mContext, ActivityUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST); /* * Thrown if Google Play services canceled the original * PendingIntent */ } catch (SendIntentException e) { // display an error or log it here. } /* * If no resolution is available, display Google * Play service error dialog. This may direct the * user to Google Play Store if Google Play services * is out of date. */ } else { Dialog dialog = GooglePlayServicesUtil.getErrorDialog( connectionResult.getErrorCode(), (Activity) mContext, ActivityUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST); if (dialog != null) { dialog.show(); } } } 

}

意向服务:

 public class ActivityRecognitionIntentService extends IntentService { public ActivityRecognitionIntentService() { // Set the label for the service's background thread super("ActivityRecognitionIntentService"); } @Override protected void onHandleIntent(Intent intent) { Log.w("Rakshak", "the on handel intent called"); // I see this only when the devices screen is on // do some fun stuff } 

Solutions Collecting From Web of "活动识别在电话进入待机状态时停止接收更新(屏幕closures状态)"

为了避免耗尽电量,闲置的Android设备很快就会入睡。 这是你停止服务的原因。 您可以阅读更多关于如何在这里处理: 保持设备醒来 。 也可以从cwac-wakeful库中查看WakefulIntentService 。 看起来像是你在找什么。

看看“重复报警”:

它们在应用程序之外运行,所以即使应用程序没有运行, 即使设备本身已经睡着 ,也可以使用它们触发事件或操作。

https://developer.android.com/training/scheduling/alarms.html

或在“WakeLock”:

使用唤醒锁的一个合理的情况可能是一个后台服务 ,需要抢到一个唤醒锁,以保持CPU运行在屏幕closures的情况下工作 。 再一次,这种做法应该尽量减less,因为它对电池寿命的影响。

特别是 “WakefulBroadcastReceiver”:

将广播接收机与服务结合使用,可以pipe理后台任务的生命周期。

WakefulBroadcastReceiver是一种特殊types的广播接收器,负责为您的应用程序创build和pipe理PARTIAL_WAKE_LOCK。 WakefulBroadcastReceiver将工作传递给一个服务(通常是一个IntentService),同时确保设备在转换中不会回到hibernate状态。 如果在将工作转换为服务时不保持唤醒locking,则可以在工作完成之前有效地让设备重新进入hibernate状态。 最终的结果是,应用程序可能不会完成工作,直到将来的任意点,这是不是你想要的。

https://developer.android.com/training/scheduling/wakelock.html#cpu

如果考虑使用第二种方法,请小心消耗电池电量。