Flutter:如何在 Android 和 iPhone 上关闭应用程序时以约 15 秒的频率获取位置

问题描述 投票:0回答:1

我正在创建一个 Flutter 应用程序,需要在应用程序关闭时以大约 15-30 秒的频率获取用户的位置。目前,我使用“位置”flutter 包,它允许我在应用程序打开但不在屏幕上时获取位置。但是,我希望在关闭应用程序并打开手机时跟踪位置。

我尝试过使用地理定位器和工作管理器来检索位置,但它们的最小频率为 15 分钟,这太罕见了。我目前使用“位置”包,但是当应用程序关闭时它会停止运行并且不会在启动时运行。我找到了 flutter_background_geolocation,但它不是开源的。

这是我的实现:

myapp/android/app/main/java/com/flutter/myapp/LocationService.kt

package com.flutter.myapp

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.FusedLocationProviderClient
class LocationService : Service() {
    private val CHANNEL_ID = "ForegroundServiceChannel"
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var locationCallback: LocationCallback

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                super.onLocationResult(locationResult)
                locationResult?.let {
                    // Handle location update here
                    val location = it.lastLocation
            }
        }
        startLocationUpdates()
    }
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val serviceChannel = NotificationChannel(
                CHANNEL_ID,
                "Foreground Service Channel",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(serviceChannel)
        }
    }

    private fun startLocationUpdates() {
        val locationRequest = LocationRequest.create().apply {
            interval = 15000 
            fastestInterval = 5000
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        }

        fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
    }
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Location Service")
            .setContentText("Tracking your location...")
            .setContentIntent(getPendingIntent())
            .build()

        startForeground(1, notification)
        return START_STICKY
    }
    private fun getPendingIntent(): PendingIntent {
        val notificationIntent = Intent(this, MainActivity::class.java)
        return PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
    }
    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
    override fun onDestroy() {
        super.onDestroy()
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }
}

添加到 myapp/android/app/main/kotlin/com/flutter/myapp/MainActivity.kt:

<service
        android:name=".LocationService"
        android:enabled="true"
        android:exported="false"/>

服务的使用:

class ForegroundService {
  static const platform =
      MethodChannel('com.flutter.myapp/locationService');

  Future<void> startService() async {
    try {
      final intent = AndroidIntent(
        action: 'com.flutter.myapp.START_LOCATION_SERVICE',
        package: 'com.flutter.myapp',
        componentName: 'com.flutter.myapp/.LocationService',
        flags: <int>[Flag.FLAG_ACTIVITY_NEW_TASK],
      ); 
      intent.sendBroadcast();
      await platform.invokeMethod('startService');
    } on PlatformException catch (e) {
      print("Failed to start service: '${e.message}'.");
    }
  }

  Future<void> stopService() async {
    try {
      await platform.invokeMethod('stopService');
    } on PlatformException catch (e) {
      print("Failed to stop service: '${e.message}'.");
    }
  }

当我关闭应用程序(即在应用程序列表中向上滑动)时,这会打印在日志中:

D/FlutterGeolocator(27222): Detaching Geolocator from activity
D/FlutterGeolocator(27222): Flutter engine disconnected. Connected engine count 0
D/FlutterGeolocator(27222): Disposing Geolocator services
E/FlutterGeolocator(27222): Geolocator position updates stopped
D/FlutterGeolocator(27222): Stopping location service.
D/FlutterLocationService(27222): Unbinding from location service.
D/FlutterLocationService(27222): Destroying service.
D/FlutterGeolocator(27222): Unbinding from location service.
D/FlutterGeolocator(27222): Destroying location service.
D/FlutterGeolocator(27222): Stopping location service.
D/FlutterGeolocator(27222): Destroyed location service.
android flutter geolocation
1个回答
0
投票

有一个包 background locator 可以解决这个问题。 请检查这个问题,希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.