【问题标题】:Android background location service stops at some timeAndroid后台定位服务有时会停止
【发布时间】:2020-08-09 02:17:21
【问题描述】:

我想每 15 分钟在后台获取当前位置。我用Timer 创建了一个后台服务。但它会在某个时间点停止。

请纠正我,如何在后台不停地运行它?

public class BackgroundService extends Service implements LocationListener {

    public static String str_receiver = "app.BackgroundService.Locationreceiver";
    boolean isGPSEnable = false;
    boolean isNetworkEnable = false;
    double latitude, longitude;
    LocationManager locationManager;
    Location location;
    long notify_interval = 600000;
    Intent intent;
    private Handler mHandler = new Handler();
    private Timer mTimer = null;

    public BackgroundService() {

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        Toast.makeText(BackgroundService.this, "Getting Location", Toast.LENGTH_SHORT).show();

        mTimer = new Timer();
        mTimer.schedule(new TimerTaskToGetLocation(), 60000, notify_interval);
        intent = new Intent(str_receiver);
    }

    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    private void fn_getlocation() {
        locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
        isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnable && !isNetworkEnable) {
            Toast.makeText(BackgroundService.this, "GPS disabled", Toast.LENGTH_LONG).show();
        } else {

            if (isNetworkEnable) {
                location = null;
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    return;
                }
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000000, 20, this);
                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {

                        Log.e("latitude", location.getLatitude() + "");
                        Log.e("longitude >>", location.getLongitude() + "");

                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                        fn_update(location);
                    }
                }

            }

            if (isGPSEnable) {
                location = null;
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    return;
                }
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000000, 20, this);
                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    if (location != null) {
                        Log.e("latitude>>", location.getLatitude() + "");
                        Log.e("longitude", location.getLongitude() + "");
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                        fn_update(location);
                    }
                }
            }

        }
    }

    private void fn_update(Location location) {
        intent.putExtra("latutide", location.getLatitude() + "");
        intent.putExtra("longitude", location.getLongitude() + "");
        sendBroadcast(intent);
    }

    private class TimerTaskToGetLocation extends TimerTask {
        @Override
        public void run() {

            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    fn_getlocation();
                }
            });

        }
    }

在清单中

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

【问题讨论】:

标签: android geolocation background-service


【解决方案1】:

问题是位置服务对于 android 来说昂贵。因此,当应用程序进入后台时,android os 会停止繁重的后台服务。这就是为什么您无法获得位置,或者在某些情况下,您可能会获得旧位置本身。

请看一下这个,android 中的后台执行限制,以了解该问题。

https://medium.com/exploring-android/exploring-background-execution-limits-on-android-oreo-ab384762a66c

因此,您应该使用 ForegroundService,它会在服务运行时生成 Notification

它的onCreate()有点像

 override fun onCreate() {
    super.onCreate()
    log("The service has been created".toUpperCase())
    var notification = createNotification()
    startForeground(1, notification)
}

它应该被启动为

context.startForegroundService(it)

这里有一篇关于其详细实现的文章。 我希望这应该对你有所帮助。

【讨论】:

  • 不管怎样,服务停止了...我一直在跟踪它...?...在实际旅程中。
猜你喜欢
  • 2019-03-03
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2012-06-25
  • 2015-12-17
  • 2013-09-25
相关资源
最近更新 更多