android - 如何将工作管理器与 GoogleApiClient 一起使用并进行改造?
问题描述
所以我使用 Worker Manger 在后台打开我的应用程序,从 google fit 收集数据并将其发送到服务器。
- 我尝试在我的工作人员内部调用 api 并且效果很好。
- 然后我尝试连接到 google fit 并收集数据,它运行良好。
但是当我尝试将 2 点结合在一起时,它不起作用。它总是抛出android.os.NetworkOnMainThreadException
空消息
谁能给我一个为什么会发生这种情况的原因?
这是我的代码
class TrackWorker(context: Context, params: WorkerParameters) : Worker(context, params), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
@Inject
lateinit var useCase: TrackUseCase
val TAG: String = TrackWorker::class.java.simpleName
private var client: GoogleApiClient? = null
private var totalSteps: Int = 0
private var totalDistance: Float = 0f
override fun onConnectionFailed(p0: ConnectionResult) {
Log.d(TAG, "Failed")
}
override fun onConnected(p0: Bundle?) {
val ESTIMATED_STEP_DELTAS = DataSource.Builder()
.setAppPackageName("com.google.android.gms")
.setDataType(DataType.TYPE_STEP_COUNT_DELTA)
.setType(DataSource.TYPE_DERIVED)
.setStreamName("estimated_steps")
.build()
val readRequest = DataReadRequest.Builder()
.aggregate(ESTIMATED_STEP_DELTAS, DataType.AGGREGATE_STEP_COUNT_DELTA)
.aggregate(DataType.TYPE_DISTANCE_DELTA, DataType.AGGREGATE_DISTANCE_DELTA)
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.aggregate(DataType.TYPE_ACTIVITY_SEGMENT, DataType.AGGREGATE_ACTIVITY_SUMMARY)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(CalendarUtil.getFirstDayOfWeek(), CalendarUtil.getNow(), TimeUnit.MILLISECONDS)
.build()
val result = Fitness.HistoryApi.readData(client, readRequest)
val totalResult = result.setResultCallback { it ->
if (it.status.isSuccess) {
val buckets = it.buckets
for (bucket in buckets) {
val dataSets = bucket.dataSets
for (dataSet in dataSets) {
if (dataSet.dataType.name == "com.google.step_count.delta") {
for (dp in dataSet.dataPoints) {
for (field in dp.dataType.fields) {
val steps = dp.getValue(field).asInt()
totalSteps += steps
}
}
}
}
for (dataSet in dataSets) {
if (dataSet.dataType.name == "com.google.distance.delta") {
for (dp in dataSet.dataPoints) {
for (field in dp.dataType.fields) {
val distance = dp.getValue(field).asFloat()
totalDistance += distance
}
}
}
}
}
} else {
Log.e(TAG, "There was a problem getting the step count")
}
if (totalSteps != 0 && totalDistance != 0f) {
val jsonArray = JsonArray()
val trackBodyJSON = JsonObject()
trackBodyJSON.addProperty("trackDate", CalendarUtil.getCurrentDate())
trackBodyJSON.addProperty("walksteps", totalSteps)
trackBodyJSON.addProperty("walkkm", totalDistance)
jsonArray.add(trackBodyJSON)
useCase.execute(TrackUseCase.Request(jsonArray))
.subscribe({
Log.d(TAG, "it's here $it")
}, {
Log.d(TAG, "errorrrr ${it}")
when (it) {
is ApiException ->
Log.d(TAG, "API ERROR ? ${it.apiErrorResponse.message}")
is TimeoutConnectionException -> {
Log.d(TAG, "API ERROR ? Timeout")
}
else -> {
Log.d(TAG, "error ${it.localizedMessage}")
}
}
})
}
}
}
override fun onConnectionSuspended(p0: Int) {
Log.d(TAG, "SUSSPENDED")
}
override fun doWork(): Result {
(applicationContext as WalkAndTalkApp).component().inject(this)
if (client == null) {
client = GoogleApiClient.Builder(applicationContext)
.addApi(Fitness.RECORDING_API)
.addApi(Fitness.HISTORY_API)
.addScope(Scope(Scopes.FITNESS_LOCATION_READ))
.addScope(Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build()
if (!client!!.isConnected)
client!!.connect()
}
return Result.SUCCESS
}
}
我尝试使用链接工作者管理器,但第二个工作者在第一个连接到 google fit sdk 并获取数据之前被执行
下面是代码
private var totalSteps: Int = 0
private var totalDistance: Float = 0f
val TAG: String = "DAILYTRAKWORKER"
class ConnectWorker(context: Context, params: WorkerParameters) : Worker(context, params), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private var client: GoogleApiClient? = null
override fun onConnectionFailed(p0: ConnectionResult) {
Log.d(TAG, "Failed")
}
override fun onConnected(p0: Bundle?) {
Log.d(TAG, "CONNNNECTED")
val ESTIMATED_STEP_DELTAS = DataSource.Builder()
.setAppPackageName("com.google.android.gms")
.setDataType(DataType.TYPE_STEP_COUNT_DELTA)
.setType(DataSource.TYPE_DERIVED)
.setStreamName("estimated_steps")
.build()
val readRequest = DataReadRequest.Builder()
.aggregate(ESTIMATED_STEP_DELTAS, DataType.AGGREGATE_STEP_COUNT_DELTA)
.aggregate(DataType.TYPE_DISTANCE_DELTA, DataType.AGGREGATE_DISTANCE_DELTA)
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.aggregate(DataType.TYPE_ACTIVITY_SEGMENT, DataType.AGGREGATE_ACTIVITY_SUMMARY)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(CalendarUtil.getFirstDayOfWeek(), CalendarUtil.getNow(), TimeUnit.MILLISECONDS)
.build()
val result = Fitness.HistoryApi.readData(client, readRequest)
result.setResultCallback { it ->
if (it.status.isSuccess) {
val buckets = it.buckets
for (bucket in buckets) {
val dataSets = bucket.dataSets
for (dataSet in dataSets) {
if (dataSet.dataType.name == "com.google.step_count.delta") {
for (dp in dataSet.dataPoints) {
for (field in dp.dataType.fields) {
val steps = dp.getValue(field).asInt()
totalSteps += steps
Log.d(TAG, "steps: $steps")
}
}
}
}
for (dataSet in dataSets) {
if (dataSet.dataType.name == "com.google.distance.delta") {
for (dp in dataSet.dataPoints) {
for (field in dp.dataType.fields) {
val distance = dp.getValue(field).asFloat()
Log.d(TAG, "distance: " + distance / 1000)
totalDistance += distance
}
}
}
}
}
} else {
Log.e(TAG, "There was a problem getting the step count")
}
}
}
override fun onConnectionSuspended(p0: Int) {
Log.d(TAG, "SUSSPENDED")
}
override fun doWork(): Result {
if (client == null) {
client = GoogleApiClient.Builder(applicationContext)
.addApi(Fitness.RECORDING_API)
.addApi(Fitness.HISTORY_API)
.addScope(Scope(Scopes.FITNESS_LOCATION_READ))
.addScope(Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build()
if (!client!!.isConnected)
client!!.connect()
}
return Result.SUCCESS
}
}
class TrackWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
@Inject
lateinit var useCase: TrackUseCase
override fun doWork(): Result {
(applicationContext as WalkAndTalkApp).component().inject(this)
Log.i(TAG, "trackworker:$totalSteps ")
if (totalSteps != 0 && totalDistance != 0f) {
val jsonArray = JsonArray()
val trackBodyJSON = JsonObject()
Log.i(TAG, "Total steps:$totalSteps ")
Log.i(TAG, "Total Distance:$totalDistance ")
Log.d(TAG, "CURRENT DATE ${CalendarUtil.getCurrentDate()}")
trackBodyJSON.addProperty("trackDate", CalendarUtil.getCurrentDate())
trackBodyJSON.addProperty("walksteps", totalSteps)
trackBodyJSON.addProperty("walkkm", totalDistance)
jsonArray.add(trackBodyJSON)
Log.d(TAG, "LIST ---> $jsonArray")
useCase.execute(TrackUseCase.Request(jsonArray))
.subscribe({
Log.d(TAG, "it's here $it")
}, {
Log.d(TAG, "errorrrr ${it}")
when (it) {
is ApiException ->
Log.d(TAG, "API ERROR ? ${it.apiErrorResponse.message}")
is TimeoutConnectionException -> {
Log.d(TAG, "API ERROR ? Timeout")
}
else -> {
Log.d(TAG, "error ${it.localizedMessage}")
}
}
})
}
return Result.SUCCESS
}
}
解决方案
推荐阅读
- asp.net - CSS 在 MVC 5.2 中无法正确呈现
- python - pytest:使用“会话”范围夹具以及默认范围夹具
- css - 如何解决我的引导表布局问题?
- sql - 如何在条件结果集中获得行号?
- python - Treeview如何使用光标上下键选择多行
- javascript - 有没有办法用 Python 解密 AES?
- javascript - 一种在单个语句中附加具有多个属性的 img 的方法?
- javascript - 卡在 Leetcode 19 问题“从列表末尾删除第 N 个节点”
- c++ - Qcombobox如何改变一行编辑的文本
- angular - 角度 7 填充子对象