我正在为我的应用程序使用Google API:ActivityRecognitionClient.requestActivityUpdates。该应用程序背后的逻辑是跟踪用户在短半径范围内的运动。例如,从一个房间到另一个房间。因此,我将使用倒数计时器继续轮询此API,并每30000毫秒检查一次特定设备的状态。如果用户有任何移动,我会将位置(WiFi)发送到服务器。
我正在使用相同的Google示例,但根据我的逻辑进行了更轻松的修改。但是我的问题是,待处理的Intent会随机发送先前的结果(3/10)。因此,大部分时间我都无法使用此API获得准确的结果。
根据我的分析,我发现,如果增加轮询间隔,结果的准确性也会提高。
我已经分析了堆栈溢出点[Activity Recognition PendingIntent stop been called in the middle of the night。但是我的问题不同。 如果有人有更好的解决方案/解决方法,请向我更新。我正在添加我的代码库供您参考。
经过测试的设备
Nexus 6P- OS- 8.1.0
代码库
/**
* Check the Device Moving Activity Status
* Integrated Google Activity Status API to get the Device is Idle or not
* If the device Idle status is 95% Accurate, then the App will send the user info to Server
*/
private fun checkActivityStatus() {
//Request the Activity status with the help of An Intent Service
val task = mActivityRecognitionClient.requestActivityUpdates(
Constants.DETECTION_INTERVAL_IN_MILLISECONDS,
getActivityDetectionPendingIntent())
task.addOnSuccessListener {
// Toast.makeText(this,
//getString(R.string.activity_updates_enabled),
// Toast.LENGTH_SHORT)
//.show()
setUpdatesRequestedState(true)
updateDetectedActivitiesList()
}
task.addOnFailureListener {
Log.w(TAG, getString(R.string.activity_updates_not_enabled))
/* Toast.makeText(this,
getString(R.string.activity_updates_not_enabled),
Toast.LENGTH_SHORT)
.show()*/
setUpdatesRequestedState(false)
}
}
/**
* Gets a PendingIntent to be sent for each activity detection.
*/
private fun getActivityDetectionPendingIntent(): PendingIntent {
val intent = Intent(this, DetectedActivitiesIntentService::class.java)
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling
// requestActivityUpdates() and removeActivityUpdates().
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
/**
* Processes the list of freshly detected activities. Asks the adapter to update its list of
* DetectedActivities with new `DetectedActivity` objects reflecting the latest detected
* activities.
*/
private fun updateDetectedActivitiesList() {
val detectedActivities: ArrayList<DetectedActivity> = Utils.detectedActivitiesFromJson(
PreferenceManager.getDefaultSharedPreferences(this)
.getString(Constants.KEY_DETECTED_ACTIVITIES, ""))
val detectedActivitiesMap = HashMap<Int, Int>()
for (activity in detectedActivities) {
detectedActivitiesMap[activity.type] = activity.confidence
}
val ideleConfidence = detectedActivitiesMap[Constants.MONITORED_ACTIVITIES[0]]
Log.i(TAG, "***IDLE Status = $ideleConfidence Present Location ${mSpDataSupplier.getSelectedLocation()}")
if (ideleConfidence != null && ideleConfidence!! > 95) {
// sendIdleStatusToServer(ideleConfidence)
if (!mLocationDataList.isEmpty()) {
sendLocationInfo(mLocationDataList.get(mLocationDataList.size - 1))
}
} else {
// The user is in Moving state- Need to clear the Data
synchronized(mLocationDataList) {
mLocationDataList.clear()
mDuration = 0
}
mSpDataSupplier.removeLocation()
sendBroadcastEndTraining()
sendToast("End Training...")
}
}
/**
* Sets the boolean in SharedPreferences that tracks whether we are requesting activity
* updates.
*/
private fun setUpdatesRequestedState(requesting: Boolean) {
PreferenceManager.getDefaultSharedPreferences(this)
.edit()
.putBoolean(Constants.KEY_ACTIVITY_UPDATES_REQUESTED, requesting)
.apply()
}