Android location service working in emulator, not on real device using AsyncTask?
<p>I am using AsyncTask for getting the user location using best provider criteria. It works on the emulator, but not on the real device. </p>

<p>I am using <code>Criteria()</code> to select the best provider and <code>getLastKnownLocation</code> to get the location.</p>

<p>Here is my code:</p>

<pre><code>class GetPositionTask extends AsyncTask&lt;Void, Void, Location&gt; implements LocationListener
{
    ProgressDialog progressDialog;
    private Location location;
    private LocationManager lm;
    private String mProviderName;

    protected void onPreExecute()
    {
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (checkPermission()) {
            Criteria criteria = new Criteria(); //Using criteria to get the best provider.
            mProviderName = lm.getBestProvider(criteria, true);
            lm.requestLocationUpdates(mProviderName, 1000, 0, this);
        }
        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setTitle("Please Wait..");
        progressDialog.setMessage("Processing...!!");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    protected Location doInBackground(Void... params)
    {
        // Try to use the last known position
        if (checkPermission()) {
            Location location = lm.getLastKnownLocation(mProviderName);
            return location;
        }
        return null;
    }

    protected void onPostExecute(Location location)
    {
        if (progressDialog != null &amp;&amp; progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
        if (location != null) {
            Toast.makeText(getApplicationContext(), "GPS locked! Processing your address!", Toast.LENGTH_SHORT).show();
        } else {
            new AlertDialog.Builder(MainActivity.this)
                    .setTitle("Error")
                    .setMessage("Server Error! Please Try again!!") //This error message is thrown in the real device, not on emulator.
                    .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    })
                    .setCancelable(false)
                    .show();
        }
        if (checkPermission()) {
            lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            lm.removeUpdates(this);
            if (location != null) {
                new GeocodeAsyncTask().execute(location.getLatitude(), location.getLongitude()); //This is another AsyncTask to get the address from the location.
            }
        }
    }

    @Override
    public void onLocationChanged(Location location) {}
    public void onProviderDisabled(String provider) {}
    public void onProviderEnabled(String provider) {}
    public void onStatusChanged(String provider, int status, Bundle extras) {}
}

private boolean checkPermission() {
    int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
    return result == PackageManager.PERMISSION_GRANTED;
}

private void requestPermission() {
    ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (grantResults.length &gt; 0) {
                boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                if (locationAccepted)
                    checkLocationStatus();
                else {
                    if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M) {
                        if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
                            showMessageOKCancel("You need to allow access to the Locations!",
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M) {
                                                requestPermissions(new String[]{ACCESS_FINE_LOCATION},
                                                        PERMISSION_REQUEST_CODE);
                                            }
                                        }
                                    });
                            return;
                        }
                    }

                }
            }
            break;
    }
}

private void checkLocationStatus() {
    if (checkPermission()) {
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            new GetPositionTask().execute();
        }
        else{
            startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
        }
    } else {
        Toast.makeText(this, "Needs to access GPS. Please give access to it!", Toast.LENGTH_SHORT).show();
        requestPermission();
    }
}
</code></pre>

<p>}</p>

<p>Is there any mistake in it? Any hint would help.</p>

<p>Is there any way that i could get current location without using the last known location?</p>

<p>Edit: 
Just a side note: On real device, the GPS symbol is visible for a second and then it goes hidden, then came the error.</p>