Android Workmanager: дождитесь BroadcastReceiver, прежде чем вернуть результат - PullRequest
0 голосов
/ 19 июня 2019

Я отправляю SMS, используя SmsManager, и я использовал WorkManager, чтобы иметь возможность делать это в фоновом режиме. Поскольку количество сообщений является динамическим, я приковал WorkerRequest к этому. Это фрагмент:

private fun startSmsWork(sms: Array<SmsEntity>) {
    val gson = Gson()

    val smsWorkerRequestBuilder = OneTimeWorkRequestBuilder<SmsWorker>()
      smsWorkerRequestBuilder.setInputData(workDataOf(SMS_WORKER_INPUT_KEY to gson.toJson(sms[0])))

    var continuation = WorkManager.getInstance()
      .beginWith(smsWorkerRequestBuilder.build())

    for (i in 1 until sms.size) {
      smsWorkerRequestBuilder.setInputData(workDataOf(SMS_WORKER_INPUT_KEY to gson.toJson(sms[i])))
      continuation = continuation.then(smsWorkerRequestBuilder.build())
    }

    continuation.enqueue()
}

А это мой рабочий класс:

class SmsWorker(ctx: Context, workerParams: WorkerParameters) : Worker(ctx, workerParams) {

  override fun doWork(): Result {
    return try {
      val data = inputData.getString(SMS_WORKER_INPUT_KEY)
      val messages = Gson().fromJson(data, SmsEntity::class.java)
      sendSms(messages)
      Result.success()
    } catch (e: Exception) {
      Log.e("Sms", e.localizedMessage)
      Result.failure()
    }
  }

  private fun sendSms(msg: SmsEntity) {
    try {
      Log.d("SmsWorker", "Sending message ${msg.id}....")
      val sentIntent = Intent(SENT_INTENT_ACTION)
      sentIntent.putExtra(SENT_INTENT_EXTRA, msg.id)
      val sentPI = PendingIntent.getBroadcast(applicationContext, 0, sentIntent, 0)

      val deliveredIntent = Intent(DELIVERED_INTENT_ACTION)
      deliveredIntent.putExtra(DELIVERED_INTENT_EXTRA, msg.id)
      val deliveredPI = PendingIntent.getBroadcast(applicationContext, 0, sentIntent, 0)

      val smsManager = SmsManager.getDefault()
      smsManager.sendTextMessage(msg.num, null, msg.message, sentPI, deliveredPI)
    } catch (e: Exception) {
      Log.e("Sms", e.localizedMessage)
    }
  }
}

Все работает хорошо, НО я хочу иметь возможность отслеживать каждое отправленное сообщение. Поэтому я добавил BroadcastReceiver для этого, но намерение, которое получает BroadcastReceiver, будет только самым последним (в случае нескольких сообщений). Я узнал, что мне нужно дождаться отправки сообщения, прежде чем отправить его.

У меня вопрос, как я смогу реализовать это в своем рабочем классе, чтобы он ожидал результата в BroadcastReceiver, прежде чем вернуть объект Result.

Любой вклад очень ценится

1 Ответ

0 голосов
/ 20 июня 2019

Если вы хотите асинхронно ожидать результата операции во время рабочего, используйте ListenableWorker.

Кроме того, несколько общих советов: поскольку вы имеете дело с SMS, я почти уверен, что для вашей работы вам понадобится сетевое ограничение. И вы также можете посмотреть на уникальную работу и добавление, если это имеет смысл для вашего варианта использования.

...