如何获取设备的最后位置?

时间:2017-11-20 12:52:16

标签: android location

我正在尝试获取用户的最后一个已知位置,但是当我打开应用程序时,它只是在textViews中显示一个空白屏幕,它应该显示纬度的经度和时间。我找不到任何瑕疵或错误。所以,我需要一些帮助。这个代码在我昨天运行时有效,但现在不能正常工作。以下是我的

MainActivity.java:

public class MainActivity extends AppCompatActivity implements LocationListener {
final String TAG = "GPS";
private final static int ALL_PERMISSIONS_RESULT = 101;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final long MIN_TIME_BW_UPDATES = 1000 ;

TextView tvLatitude, tvLongitude, tvTime;
LocationManager locationManager;
Location loc;
ArrayList<String> permissions = new ArrayList<>();
ArrayList<String> permissionsToRequest;
ArrayList<String> permissionsRejected = new ArrayList<>();
boolean isGPS = false;
boolean isNetwork = false;
boolean canGetLocation = true;

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

    tvLatitude = (TextView) findViewById(R.id.tvLatitude);
    tvLongitude = (TextView) findViewById(R.id.tvLongitude);
    tvTime = (TextView) findViewById(R.id.tvTime);

    locationManager = (LocationManager) getSystemService(Service.LOCATION_SERVICE);
    isGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    isNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
    permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
    permissionsToRequest = findUnAskedPermissions(permissions);

    if (!isGPS && !isNetwork) {
        Log.d(TAG, "Connection off");
        showSettingsAlert();
        getLastLocation();
    } else {
        Log.d(TAG, "Connection on");
        // check permissions
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (permissionsToRequest.size() > 0) {
                requestPermissions(permissionsToRequest.toArray(new String[permissionsToRequest.size()]),
                        ALL_PERMISSIONS_RESULT);
                Log.d(TAG, "Permission requests");
                canGetLocation = false;
            }
        }

        // get location
        getLocation();
    }
}

@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "onLocationChanged");
    updateUI(location);
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {}

@Override
public void onProviderEnabled(String s) {
    getLocation();
}

@Override
public void onProviderDisabled(String s) {
    if (locationManager != null) {
        locationManager.removeUpdates(this);
    }
}

private void getLocation() {
    try {
        if (canGetLocation) {
            Log.d(TAG, "Can get location");
            if (isGPS) {
                // from GPS
                Log.d(TAG, "GPS on");
                locationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                if (locationManager != null) {
                    loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    if (loc != null)
                        updateUI(loc);
                }
            } else if (isNetwork) {
                // from Network Provider
                Log.d(TAG, "NETWORK_PROVIDER on");
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                if (locationManager != null) {
                    loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (loc != null)
                        updateUI(loc);
                }
            } else {
                loc.setLatitude(0);
                loc.setLongitude(0);
                updateUI(loc);
            }
        } else {
            Log.d(TAG, "Can't get location");
        }
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

private void getLastLocation() {
    try {
        Criteria criteria = new Criteria();
        String provider = locationManager.getBestProvider(criteria, false);
        Location location = locationManager.getLastKnownLocation(provider);
        Log.d(TAG, provider);
        Log.d(TAG, location == null ? "NO LastLocation" : location.toString());
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

private ArrayList findUnAskedPermissions(ArrayList<String> wanted) {
    ArrayList result = new ArrayList();

    for (String perm : wanted) {
        if (!hasPermission(perm)) {
            result.add(perm);
        }
    }

    return result;
}

private boolean hasPermission(String permission) {
    if (canAskPermission()) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
        }
    }
    return true;
}

private boolean canAskPermission() {
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}

@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case ALL_PERMISSIONS_RESULT:
            Log.d(TAG, "onRequestPermissionsResult");
            for (String perms : permissionsToRequest) {
                if (!hasPermission(perms)) {
                    permissionsRejected.add(perms);
                }
            }

            if (permissionsRejected.size() > 0) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (shouldShowRequestPermissionRationale(permissionsRejected.get(0))) {
                        showMessageOKCancel("These permissions are mandatory for the application. Please allow access.",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                            requestPermissions(permissionsRejected.toArray(
                                                    new String[permissionsRejected.size()]), ALL_PERMISSIONS_RESULT);
                                        }
                                    }
                                });
                        return;
                    }
                }
            } else {
                Log.d(TAG, "No rejected permissions.");
                canGetLocation = true;
                getLocation();
            }
            break;
    }
}

public void showSettingsAlert() {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
    alertDialog.setTitle("GPS is not Enabled!");
    alertDialog.setMessage("Do you want to turn on GPS?");
    alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    });

    alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
        }
    });

    alertDialog.show();
}

private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(MainActivity.this)
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", null)
            .create()
            .show();
}

private void updateUI(Location loc) {
    Log.d(TAG, "updateUI");
    tvLatitude.setText(Double.toString(loc.getLatitude()));
    tvLongitude.setText(Double.toString(loc.getLongitude()));
    tvTime.setText(DateFormat.getTimeInstance().format(loc.getTime()));
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (locationManager != null) {
        locationManager.removeUpdates(this);
    }
}
}

}

2 个答案:

答案 0 :(得分:1)

融合位置提供商客户端是最好的方法。 尝试使用此代码获取getLastLocation()方法:

FusedLocationProviderClient mLocationProvider = LocationServices.getFusedLocationProviderClient(activity);
        mLocationProvider.getLastLocation().addOnSuccessListener(activity, location -> {
            if (location != null) {
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();    
            }
        }).addOnFailureListener(e -> {
                //some log here
        });

答案 1 :(得分:0)

你可以尝试下面的解决方案并让我知道,因为它对我来说很好。

将您的提供商更改为

String provider = LocationManager.NETWORK_PROVIDER;

您已在getLastLocation()方法中提及此提供商。

还在清单文件中添加以下权限

<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.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>