1

我正在使用 AsyncTask 使用最佳提供者标准获取用户位置。它适用于模拟器,但不适用于真实设备。

Criteria()用来选择最佳提供商并getLastKnownLocation获取位置。

这是我的代码:

class GetPositionTask extends AsyncTask<Void, Void, Location> 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 && 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 > 0) {
                boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                if (locationAccepted)
                    checkLocationStatus();
                else {
                    if (Build.VERSION.SDK_INT >= 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 >= 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();
    }
}

}

有什么错误吗?任何提示都会有所帮助。

有什么方法可以在不使用最后一个已知位置的情况下获得当前位置?

编辑:附注:在真实设备上,GPS 符号可见一秒钟,然后隐藏,然后出现错误。

4

0 回答 0