简体   繁体   中英

Continue tracking location in a service when user changes app or activity/fragment

I am making a fitness app and need to track location (using google play services) in the background - I run an unbound service. The service work fine when run from the fragment its started in, but when the user changes fragment or changes/minimizes app (say to start using the gmail app, etc...) the service stops. How do I keep tracking location so that when the app is minimized and then opened again, it will still be tracking (So that it can continuously write to the SQLite DB - Distance travelled, avg. speed, etc.)

segments of code from the fragment:

public void onResume(){
//setting up Broadcast Reciever
        if(broadcastReceiver == null){
            broadcastReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    Location currentLocation;
                    //retrieving extras with given tag from service
                    currentLocation = (Location) intent.getExtras().get("currentLocation");

                    //displaying speed and altitude if user has selected to view it from the spinner
                    if(appPreferences.getKeyStatsSpinner1().equalsIgnoreCase("CURRENT SPEED")){
                        spinner1TextView.setText(String.valueOf(currentLocation.getSpeed()));
                    }
                    if(appPreferences.getKeyStatsSpinner2().equalsIgnoreCase("CURRENT SPEED")){
                        spinner2TextView.setText(String.valueOf(currentLocation.getSpeed()));
                    }
                    if(appPreferences.getKeyStatsSpinner1().equalsIgnoreCase("CURRENT ALTITUDE")){
                        spinner1TextView.setText(String.valueOf(currentLocation.getAltitude()));
                    }
                    if(appPreferences.getKeyStatsSpinner2().equalsIgnoreCase("CURRENT ALTITUDE")){
                        spinner2TextView.setText(String.valueOf(currentLocation.getAltitude()));
                    }
                }
            };
        }

        //start recieving updates from service with tag given
        //getActivity().registerReceiver(broadcastReceiver, new IntentFilter("LocationTrackingService_update"));
        context.registerReceiver(broadcastReceiver, new IntentFilter("LocationTrackingService_update"));
}
 @Override
public void onPause() {
    super.onPause();

    Log.d(TAG, "onPause: service cancelled");

    //close connecting with broadcast receiver
    if(broadcastReceiver != null){
        //getActivity().unregisterReceiver(broadcastReceiver);
        context.unregisterReceiver(broadcastReceiver);
    }

    trackLocation(false);
}

private void trackLocation(Boolean trackLocation){
        if(trackLocation == true) {
            Intent locationTrackingService = new Intent(context, LocationTrackingService.class);
            //getActivity().startService(locationTrackingService);
            context.startService(locationTrackingService);
        }
        else{
            Intent locationTrackingService = new Intent(context, LocationTrackingService.class);
            //getActivity().stopService(locationTrackingService);
            context.stopService(locationTrackingService);
        }
    }

segments of code from the service:

//automatically called when we .connect() to googleApiClient
    @Override
    public void onConnected(@Nullable Bundle bundle) {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ............................
            return;
        }


        //sets location to last known location
        currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);

        //broadcasting intent with last known location
        Intent publishLocationUpdate = new Intent("LocationTrackingService_update");
        publishLocationUpdate.putExtra("currentLocation", currentLocation);
        sendBroadcast(publishLocationUpdate);

        //request updates
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
    }

I have read perhaps that I should use 'startForegroundService' instead. I was also thinking that if I removed the service destruction from onPause, the service would run indefinitely - but when I deleted the code from onPause, the service continued as normal..

You are right that you should use ForegroundService. The following example runs perfect. We are using this in our projects.

Android Play Location Foreground Service Example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM