Network provider and GPS provider working together, need to separate the both based on available providers

  • Replies:0
  • OpenNot stickiedUnanswered
  • Forum posts: 1

Jan 26, 2017 8:02:22 AM via Website

I am trying to develop an android application that gets the device latitude and longitude using GPS or Network providers, whichever is available for the process. The code works perfectly fine when the device's GPS is on but unfortunately it never works when the device's GPS is switched off.

I want to get the device's latitude and longitude based on the available providers, for example; if device's GPS is on it should get the device's latitude and longitude using GPS provider and if the GPS is switched off it should get the device's latitude and longitude using the network provider. In my case the network provider always returns false and only works when the device's GPS is switched on where as it should not bother about the device GPS to be on or off it should simply get the latitude and longitude based on network provider.

I have used the fused API from Google but even that has the same issue, I can only get the latitude and longitude using GPS provider and when I turn off the device's GPS it never returns the required latitude and longitude using network provider because network provider and GPS providers both returns false when device's GPS is switched off.

Both GPS and network provider is working on device's GPS, I want to separate their process respectively.

I am using following permissions and features

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.LOCATION_HARDWARE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-feature android:name="android.hardware.location" android:required="true"/>
<uses-feature android:name="android.hardware.location.network" android:required="true"/>
<uses-feature android:name="android.hardware.location.gps" android:required="true"/>

Following is my complete Java code that only works when device's GPS is on, in both GPS and network cases.

package com.example.administrator.locationgetter;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends Activity {
    public static final int MY_PERMISSIONS_REQUEST = 0;

    LocationManager locationManager;

    private LocationListener mLocationListener;


    private void showStatus(String st)
    {
        Toast.makeText(MainActivity.this,st,Toast.LENGTH_SHORT).show();
    }
    private LocationListener createLocationListener() {
        return new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                // Called when a new location is found by the network location provider.
                Toast.makeText(MainActivity.this,"accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude(),Toast.LENGTH_SHORT).show();
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
                showStatus(provider + " -- " + status);
            }

            public void onProviderEnabled(String provider) {
                showStatus(provider + " -- " + "ENABLED!");
            }

            public void onProviderDisabled(String provider) {
                showStatus(provider + " -- " + "DISABLED!");
            }


        };
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        //setSupportActionBar(toolbar);

        mLocationListener = createLocationListener();
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener);

                } else {
                    Toast.makeText(MainActivity.this, "So sad! Give me the damn permissions!", Toast.LENGTH_SHORT).show();

                }
                return;
            }
        }
    }

    public void btnLocation(View v) {

        if ((ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )){
            showStatus("Give me the permissions man!");
            ActivityCompat.requestPermissions(this,
                    new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST);
        }
        else
        {
            showStatus("Already have permission");
            locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
            String locationProvider = LocationManager.NETWORK_PROVIDER;
            Location location = locationManager.getLastKnownLocation(locationProvider);
            if(location != null)
            {
                Toast.makeText(MainActivity.this,"accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude(),Toast.LENGTH_SHORT).show();
            }
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener);

        }
    }
    public void btnLocation1(View v) {

        if ((ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )){
            showStatus("Give me the permissions man!");
            ActivityCompat.requestPermissions(this,
                    new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST);
        }
        else
        {
            showStatus("Already have permission");
            locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
            String locationProvider = LocationManager.GPS_PROVIDER;
            Location location = locationManager.getLastKnownLocation(locationProvider);
            if(location != null)
            {
                Toast.makeText(MainActivity.this,"accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude(),Toast.LENGTH_SHORT).show();
            }
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);

        }
    }
}

I have tested the application on KitKat, Lollipop and Marshmallow, all have the same results.

If you download the baidu maps and launch the app it will ask you the permission for location access just make sure that your location is off and simply grant the location permission to baidu map you will notice that it will point your location on baidu maps even if your gps or location service is off.