【问题标题】:How can I perform android location checks in intervals?如何定期执行 android 位置检查?
【发布时间】:2020-02-04 14:11:36
【问题描述】:

我需要从 android 应用程序中检索 android 设备坐标并将这些坐标发送到服务器,即使在应用程序停止和/或设备处于睡眠状态时也是如此。我需要在固定的时间间隔内执行此操作。

我清楚地知道这是一个复杂的解决方案,但您能否提及解决此问题所需的关键方面?我需要在开发应用程序的过程中选择一个方向。

我在网络上进行了广泛的研究,有很多解决方案,但其中一些似乎已经有几年历史了,而另一些则倾向于以不同的方式解决特定问题。不可能全部尝试,从所有这些信息中组成的解决方案将满足我的需求,并且将是最佳和稳定的解决方案。

谢谢

【问题讨论】:

    标签: android service location


    【解决方案1】:

    我遇到了同样的问题,这个解决方案对我有用:

    如下定义一个工人:

    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 标志)。

    这个想法对我很有效。

    【讨论】:

    • 感谢您的回答。我是古玩,据我了解,当应用程序停止或设备进入睡眠状态时,此代码将停止,对吗?
    • 当然是。用服务办理。请注意,在 android 8 或更高版本中,如果需要,您需要一个警报管理器来重新启动服务。 @TornikeShavishvili
    • 你同意我之前的评论吗?如果没问题,请检查我的回答是否属实。谢谢。 @TornikeShavishvili
    • 我一定会接受你的回答。但我想在我面前有全貌。即使应用程序关闭(未运行)或设备进入睡眠状态,Web 也让我对在 android 中运行服务感到困惑。也许您可以分享您在这个关键问题上的经验?谢谢
    • 所有经验分享有点困难,不过之前这篇文章对我有帮助,希望对你有所帮助:stackoverflow.com/questions/30525784/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2015-12-16
    • 1970-01-01
    相关资源
    最近更新 更多