Как я могу выполнять проверки местоположения Android через определенные промежутки времени? - PullRequest
3 голосов
/ 07 октября 2019

Мне нужно получить координаты устройства Android из приложения Android и отправить эти координаты на разрыв, даже когда приложение остановлено и / или устройство спит. Мне нужно делать это через фиксированные промежутки времени.

Я четко понимаю, что это сложное решение, но не могли бы вы упомянуть ключевые аспекты, которые необходимы для решения этой проблемы? Мне нужно выбрать направление в процессе разработки приложения.

Я провел обширные исследования в Интернете, есть много решений, но некоторым из них, кажется, уже несколько лет, а другим свойственно решать конкретные проблемы. по-разному. Невозможно попробовать их все, и из всей этой информации составить решение, которое будет отвечать моим потребностям и будет оптимальным и стабильным решением.

Спасибо

1 Ответ

2 голосов
/ 07 октября 2019

У меня была та же проблема, и это решение сработало для меня:

Определите работника, как показано ниже:

class SendLocationWorker(
  context: Context,
  workerParams: WorkerParameters
) : Worker(context, workerParams) {
  private var retrofit: Retrofit? = null
  private var locationApi: MyApi? = null
  private val userLocationDao = AppDatabase.getInstance(applicationContext)
      .userLocationDao()

  override fun doWork(): Result {
    return try {
      if (retrofit == null) {
        retrofit = MasterRetrofit().initRetrofit(Constants.MAIN_URL)
      }
      if (locationApi == null) {
        locationApi = retrofit!!.create(MyApi::class.java)
      }
      callApi()
      Result.success()
    } catch (ex: Exception) {
      Result.failure()
    }
  }

  @SuppressLint("CheckResult")
  private fun callApi() {
    val locations = getUserLocations()
    if (locations.isNotEmpty()) {
      val request = InsertLocationUserRequest()
      request.saveTrackings = locations

      locationApi!!.SaveTracking(request)
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .map(SuccessMapper<Response<InsertLocationUserResponse>>())
          .subscribe(
              { response ->
                if (response.body()!!.success) {
                  Observable.fromIterable(locations)
                      .forEach { location -> location.isSync = true }
                  userLocationDao.update(locations)
                }
              },
              { throwable ->

              },
              {
              }
          )
    }
  }

  private fun getUserLocations(): List<UserLocation> {
    return userLocationDao.findAll("isSync", "0")
  }
}

Кроме того, вам необходимо определить метод в MasterActivity или MasterPresenter, как этот:

  @Override public void sendStoredLocationToServer() {
    Constraints myConstraints = new Constraints.Builder()
        .setRequiresBatteryNotLow(true)
        .build();

    PeriodicWorkRequest sendLocationWorkerRequest =
        new PeriodicWorkRequest.Builder(SendLocationWorker.class, 10000, TimeUnit.MILLISECONDS)
            .setConstraints(myConstraints)
            .build();

    WorkManager.getInstance().enqueueUniquePeriodicWork("sendLocationWorker",
        ExistingPeriodicWorkPolicy.REPLACE,
        sendLocationWorkerRequest);
  }

Затем вы можете позвонить своему работнику в свой MasterActivity или MasterPresenter везде, где вы хотите, например:

sendStoredLocationToServer();

Этот работник сохранит ваши местоположения в базе данных и отправит их, если онвозможно и пометить все отправленные элементы как true (используя isSyns флаг).

Эта идея хорошо сработала для меня.

...