Поэтому я использую 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
}
}