Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
426 views
in Technique[技术] by (71.8m points)

android - In Oreo (8.0.0+) (API 26+), How to get a location services update when the app is in the background or kill

In Android O (8.0.0+) (API 26+), How to get a location services update when the app is in the background or kill. In "Strava" Android App (Available on Play Store), location services run properly when the app is in the background or kill. I need to build same functionality in my app. Whenever I start service using

startService(new Intent(this, GpsServices.class));

Then the onDestroy method is called after 10 sec when an app is an idle mode (the app is in the background or kill). Below is my code.

public class GpsServices extends Service implements LocationListener, Listener {

    @Override
    public void onCreate() {
        mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (mLocationManager != null) {
            mLocationManager.addGpsStatusListener(this);
        }
        if (mLocationManager != null) {
            mLocationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER,
                500,
                0,
                this);
        }    
    }

    public void onLocationChanged(Location location) {
        System.out.println("location = [" + location + "]");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // If we get killed, after returning from here, restart
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // We don't provide binding, so return null
        return null;
    }

    /* Remove the locationlistener updates when Services is stopped */
    @Override
    public void onDestroy() {
        try {
            mLocationManager.removeUpdates(this);
            mLocationManager.removeGpsStatusListener(this);
            stopForeground(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Any help would be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can try one of below two options or a combination of both, which have solved my problems when I have faced them.

Option 1

For location update to continue running in the background, you must use LocationServices API with FusedLocationProviderClient as described here and here in docs or here in CODEPATH.

Option 2

If you would have read the Android Oreo 8.0 Documentation properly somewhere in here, you would have landed on this solution.

Step 1: Make sure you start a service as a foreground service as given in below code

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {

            mainActivity.startService(new Intent(getContext(), GpsServices.class));
            mainActivity.startService(new Intent(getContext(), BluetoothService.class));
            mainActivity.startService(new Intent(getContext(), BackgroundApiService.class));
        }
        else {
            mainActivity.startForegroundService(new Intent(getContext(), GpsServices.class));
            mainActivity.startForegroundService(new Intent(getContext(), BluetoothService.class));
            mainActivity.startForegroundService(new Intent(getContext(), BackgroundApiService.class));
        }

Step 2: Use notification to show that your service is running. Add below line of code in onCreate method of service.

@Override
public void onCreate() {
    ...
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForeground(NOTIFICATION_ID, notification);
    }
    ...
}

Step 3: Remove the notification when the service is stopped or destroyed.

@Override
public void onDestroy() {
    ...
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
          stopForeground(true); //true will remove notification
    }
    ...
}

One problem with Option 2 is that it will keep showing the notification until your GpsService is running on all devices running on Android Oreo 8.0.

I'm sure that both these options will work even when the app is in the background or in kill state.

I hope this solution might solve your problem.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...