Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Location Services draining the Battery - Fused Location API

We have a location based application, where based on the users location we are trying to push some notifications of campaigns. But this seems to be draining the battery of the phone and at times consuming up to 30-35% of the charge.

Below is the implementation of Location in our app.

public class DashboardActivity extends BaseActivity implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks,
        LocationListener, ExitConfirmationDialog.OnExitResponseListner {


    private final int HAS_PERMISSION_COARSE_LOCATION = 1;
    private final int HAS_PERMISSION_FINE_LOCATION = 2;


    LocationManager locationManager;

    CustomTextViewDemi mNotificationCount;
    String count = "";
    Menu menu;
    List<CreateFragmentsPojo> fragments;

    boolean isSettingsScreenOpen = false;
    int backPresedCount = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dashboard);

        setTitle("Dashboard");

        setupNavigationView(0);

        fragments = new ArrayList<>();

        Utils.HandleViews(mLayout, false);

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        if (isGPSLocationEnabled(locationManager)) {
            buildGooleApiClient();
        } else if (isNetworkLocationEnabled(locationManager)) {
            buildGooleApiClient();
        } else {
            showAlert();
        }


    }


    private void buildGooleApiClient() {

        buildGoogleApiClient();

        if (Build.VERSION.SDK_INT >= 23) {
            requestPermission();
        } else {
            if (mGoogleApiClient != null) {
                if (mGoogleApiClient.isConnected()) {
                    getUserCurrentLocation();
                } else {
                    mGoogleApiClient.connect();
                }
            } else {
                getDashBoard("", "");
            }
        }
    }


    public void getData(String lat, String lng) {
        if (Utils.isInternetConnection(this)) {
            getCampaignDetails(lat, lng);
        } else {
            Utils.HandleViews(progressBar, false);
            Utils.showMessages(this, Params.CHECK_INTERNET_MESSAGE, true);
        }
    }


    private void getUserCurrentLocation() {

        try {
            Utils.HandleViews(progressBar, true);
            if (mGoogleApiClientAwareness == null) {
                buildGoogleApiAwarenessClient();
            }


            Awareness.SnapshotApi.getLocation(mGoogleApiClientAwareness)
                    .setResultCallback(new ResultCallback<LocationResult>() {
                        @Override
                        public void onResult(@NonNull LocationResult locationResult) {
                            if (!locationResult.getStatus().isSuccess()) {
                                Log.e("awareness demo api ", "Could not get location.");

                                if (mGoogleApiClient != null) {
                                    try {
                                        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                                        if (mLastLocation != null) {
                                            getDashBoard(mLastLocation.getLatitude() + "", mLastLocation.getLongitude() + "");
                                        } else {
                                            getDashBoard("", "");
                                        }
                                    } catch (SecurityException e) {
                                        e.printStackTrace();
                                    }
                                } else {

                                    if (locationManager != null) {
                                        String provider = Utils.getUserLastLocation(locationManager);
                                        if (provider != null) {
                                            try {
                                                Location location = locationManager.getLastKnownLocation(provider);
                                                if (location != null) {
                                                    getDashBoard(location.getLatitude() + "", location.getLongitude() + "");
                                                } else {
                                                    getDashBoard("", "");
                                                }
                                            } catch (SecurityException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                }
                            }
                            try {
                                Location location = locationResult.getLocation();

                                if (location != null) {
                                    getDashBoard(location.getLatitude() + "", location.getLongitude() + "");
                                } else {
                                    getDashBoard("", "");
                                }

                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });

        } catch (SecurityException se) {
            se.printStackTrace();
        }
    }



    private void showAlert() {
        final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setTitle("Enable Location")
                .setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
                        "get campaigns at your location.")
                .setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        isSettingsScreenOpen = true;
                        Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivityForResult(myIntent, 201);
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        getUserCurrentLocation();
                    }
                });

        dialog.show();
    }



    /**
     * Get user permissions for location based updates
     */
    @TargetApi(23)
    private void requestPermission() {
        int HAS_REQUEST_PERMISSION_COARSE_LOCATION = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);

        if (HAS_REQUEST_PERMISSION_COARSE_LOCATION
                != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

                new AlertDialog.Builder(this)
                        .setTitle("Request Permission")
                        .setMessage("Provide permission to access your location")
                        .setNegativeButton(android.R.string.cancel, null)
                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                                        HAS_PERMISSION_COARSE_LOCATION);
                            }
                        }).create().show();


            } else {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        HAS_PERMISSION_COARSE_LOCATION);

            }
        } else {
            requestFineLocationPermission();
        }

    }

    @TargetApi(23)
    private void requestFineLocationPermission() {

        int HAS_REQUEST_PERMISSION_FINE_LOCATION = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);

        if (HAS_REQUEST_PERMISSION_FINE_LOCATION
                != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

                new AlertDialog.Builder(this)
                        .setTitle("Request Permission")
                        .setMessage("Provide permission to access your location")
                        .setNegativeButton(android.R.string.cancel, null)
                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                        HAS_PERMISSION_FINE_LOCATION);
                            }
                        }).create().show();

            } else {
                requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        HAS_PERMISSION_FINE_LOCATION);


            }
        } else {
            getUserCurrentLocation();
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == HAS_PERMISSION_COARSE_LOCATION) {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                requestFineLocationPermission();
            }
        } else if (requestCode == HAS_PERMISSION_FINE_LOCATION) {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getUserCurrentLocation();
            }
        }
    }

    /**
     * Call to detect new campaigns near by
     */
    private void getUserLocationBackgroundProcess() {
        try {
            //Utils.getCurrentLocation(this);
            startLocationUpdates();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private boolean isGPSLocationEnabled(LocationManager locationManager) {
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

    }

    private boolean isNetworkLocationEnabled(LocationManager locationManager) {
        return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }


    protected synchronized void buildGoogleApiAwarenessClient() {
        try {
            Log.i(TAG, "activity Building GoogleApiClient===");
            mGoogleApiClientAwareness = new GoogleApiClient.Builder(this)
                    .addApi(Awareness.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();

            mGoogleApiClientAwareness.connect();
            //createLocationRequest();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    protected synchronized void buildGoogleApiClient() {
        try {
            Log.i(TAG, "activity Building GoogleApiClient===");

            buildGoogleApiAwarenessClient();

            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();

            createLocationRequest();
        } catch (Exception e) {
            e.printStackTrace();
            getUserCurrentLocation();
        }
    }


    protected void createLocationRequest() {
        mGoogleApiClient.connect();
        mLocationRequest = new LocationRequest();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setSmallestDisplacement(30);
    }


    @Override
    public void onLocationChanged(Location location) {
        mCurrentLocation = location;
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        getUserCurrentLocation();
       // startLocationUpdates();
    }

    protected void startLocationUpdates() {
        try {
            mRequestingLocationUpdates = true;

            Intent receiverIntentService = new Intent(this, LocationIntentService.class);
            PendingIntent pendingIntent = PendingIntent.getService(this, 1, receiverIntentService, 0);

            if (mGoogleApiClient != null) {
                if (mGoogleApiClient.isConnected()) {
                    LocationServices.FusedLocationApi.requestLocationUpdates(
                            mGoogleApiClient, mLocationRequest, pendingIntent);
                }
                /*else {
                    mGoogleApiClient.connect();
                    LocationServices.FusedLocationApi.requestLocationUpdates(
                            mGoogleApiClient, mLocationRequest, pendingIntent);

                }*/
            } else {
                buildGoogleApiClient();
            }
        } catch (SecurityException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onResume() {
        super.onResume();

        try {
            if (isSettingsScreenOpen) {
                isSettingsScreenOpen = false;
                getUserCurrentLocation();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }


    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }


    @Override
    protected void onStop() {
        super.onStop();

        if (mGoogleApiClient != null) {
            if (mGoogleApiClient.isConnected())
                mGoogleApiClient.disconnect();
        }
    }


}
like image 368
Harsha M V Avatar asked Dec 19 '16 06:12

Harsha M V


People also ask

What is fused location API?

The fused location provider is a location API in Google Play services that intelligently combines different signals to provide the location information that your app needs.

Does location services drain battery Android?

Adjust your location services settings​ But if these apps are running behind the scenes and you aren't traveling, location services can drain your battery. To adjust this: Go to Settings > Location. Disable location setting services by turning off the switch at the top of the screen.

Can I disable fused location?

In the app select the System tab search for the service named Fused Location and disable it. Also search for the service group Google Play Services. Inside it there will be another Fused Location service.

What is Android location API?

The Google Location Services API, part of Google Play services, is the preferred way to add location-awareness to your app. It offers a simpler API, higher accuracy, low-power geofencing, and more. If you are currently using the android.


1 Answers

Instead of

mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

try this

mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

mlocationrequest.setSmallestDisplacement(30); //higher priority

Displacement parameter is set to 30 meters //No location updates are received if the device does not move or cross that distance.

//setInterval as above 1 mins.
mlocationrequest.setInterval(60000); // Update location every 1 minute

mlocationrequest.setFastestInterval(10000);

LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY level accuracy is considered to be about 100 meter accuracy. Using a coarse accuracy such as this often consumes less power.

like image 88
Nas Avatar answered Sep 27 '22 17:09

Nas