【问题标题】:Current Location failed GoogleMap当前位置失败 GoogleMap
【发布时间】:2017-01-22 06:32:59
【问题描述】:

我想检查 GPS 是否打开,如果它应该显示当前位置。如果不是,它应该要求打开它。如果用户单击取消或不转动坐标将被设置为基本坐标。不幸的是,总是选择基本款。即使 GPS 是(我没有收到打开 GPS 的消息)

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;


    locationManagerr = (LocationManager) getSystemService(LOCATION_SERVICE);
    currentLocation=new Location("location");

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET}
                    , 10);
        }
    }else
        getLocation();
    log.i(TAG,"latitude  "+currentLocation.getLatitude());
    }

    private Location getLocation(){

                locationListener= new LocationListener() {
                    @Override
                    public void onLocationChanged(Location location) {
                        currentLocation=location;
                    }

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

                    @Override
                    public void onProviderDisabled(String provider) {
                        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(LocationFinder.this);
                        alertDialogBuilder.setMessage("GPS is off. Want to turn on GPS?")
                                .setCancelable(false)
                                .setPositiveButton("Turn On",
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(DialogInterface dialog, int id) {
                                                Intent callGPSSettingIntent = new Intent(
                                                        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                                startActivity(callGPSSettingIntent);
                                            }
                                        });
                        alertDialogBuilder.setNegativeButton("Cancel",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                       currentLocation=setStartCoordinate();
                                        dialog.cancel();
                                    }
                                });
                        AlertDialog alert = alertDialogBuilder.create();
                        alert.show();
                    }
                };
       return currentLocation;
        }
    private Location setStartCoordinate(){
        Location primaryLocalization= new Location("Basic");
        primaryLocalization.setLongitude(0);
        primaryLocalization.setLatitude(0);
        return primaryLocalization;
    }

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        case 10:
            try{
                getLocation();
                log.i(TAG,"latitude  "+currentLocation.getLatitude());
            }
            catch (SecurityException ex){log.i(TAG,"security error");}
            break;
        default:
            break;
    }
}

【问题讨论】:

  • 像这样试试.. if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){ //如果启用就做你需要的... }else{ //如果没有就做你需要的启用... } 并在此处引用stackoverflow.com/questions/843675/…

标签: android google-maps gps


【解决方案1】:

这需要大量的案例处理,我将提供您要求的所有功能的完整实现,并在下面进行简要说明。

1。在清单中提供位置权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

2。在应用的 build.gradle 中添加位置依赖

compile 'com.google.android.gms:play-services-location:9.2.1'

3。扩展 BroadcastReceiver 并创建 GPSStatusReceiver

public class GPSStatusReceiver extends BroadcastReceiver {

    private GpsStatusChangeListener mCallback;
    private Context mContext;

    public GPSStatusReceiver(Context context, GpsStatusChangeListener callback) {
        mCallback = callback;
        mContext = context;

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.location.PROVIDERS_CHANGED");
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
        context.registerReceiver(this, intentFilter);
    }

    public void unRegisterReceiver(){
        Log.d("ali", "unRegisterReceiver");
        mContext.unregisterReceiver(this);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            Log.d("ali", "in PROVIDERS_CHANGED");
            mCallback.onGpsStatusChange();
        }
    }

    public interface GpsStatusChangeListener{
        void onGpsStatusChange();
    }
}

4。创建一个 GPSLocation 类

public class GPSLocation implements
        ConnectionCallbacks,
        OnConnectionFailedListener,
        LocationListener,
        GPSStatusReceiver.GpsStatusChangeListener {

    public static final int REQUEST_CHECK_SETTINGS = 100;
    public static final int LOCATION_PERMISSION_REQUEST_CODE = 200;

    private static final int PERMISSION_GRANTED = 0;
    private static final int PERMISSION_DENIED = 1;
    private static final int PERMISSION_BLOCKED = 2;

    private GoogleApiClient mGoogleApiClient;
    private Location mCurrentLocation;
    private LocationCallback mCallback;
    private Activity mActivity;
    private Context mContext;
    private LocationRequest mLocationRequest;
    private GPSStatusReceiver mGPSStatusReceiver;

    private long intervalMillis = 10000;
    private long fastestIntervalMillis = 5000;
    private int accuracy = LocationRequest.PRIORITY_HIGH_ACCURACY;

    private boolean isInitialized = false;
    private boolean isLocationEnabled = false;
    private boolean isPermissionLocked = false;

    public GPSLocation(Activity activity, LocationCallback callback) {
        mActivity = activity;
        mContext = activity.getApplicationContext();
        mCallback = callback;
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(mContext)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
        createLocationRequest();
        mGPSStatusReceiver = new GPSStatusReceiver(mContext, this);
    }


    public void init(){
        isInitialized = true;
        if(mGoogleApiClient != null) {
            if (mGoogleApiClient.isConnected()) {
                requestPermission();
            } else {
                connect();
            }
        }
    }


    public void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(intervalMillis);
        mLocationRequest.setFastestInterval(fastestIntervalMillis);
        mLocationRequest.setPriority(accuracy);
    }


    public LocationRequest getLocationRequest() {
        return mLocationRequest;
    }


    public void connect(){
        if(mGoogleApiClient != null && isInitialized) {
            mGoogleApiClient.connect();
        }
    }


    public void disconnect(){
        if(mGoogleApiClient != null && isInitialized) {
            mGoogleApiClient.disconnect();
        }
    }


    private void getLastKnownLocation(){
        if(!mGoogleApiClient.isConnected()){
            Log.d("ali", "getLastKnownLocation restart ");
            mGoogleApiClient.connect();
        }
        else {
            if (checkLocationPermission(mContext) && isLocationEnabled) {
                Log.d("ali", "getLastKnownLocation read ");
                if(mCurrentLocation == null) {
                    mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                    mCallback.onLastKnowLocationFetch(mCurrentLocation);
                }
                startLocationUpdates();
            }else{
                Log.d("ali", "getLastKnownLocation get permission ");
                requestPermission();
            }
        }
        Log.d("ali", "mCurrentLocation " + mCurrentLocation);
    }


    public void startLocationUpdates() {
        if(checkLocationPermission(mContext)
                && mGoogleApiClient != null
                && mGoogleApiClient.isConnected()
                && isLocationEnabled) {
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }


    public void stopLocationUpdates() {
        if(mGoogleApiClient != null
                && mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(
                    mGoogleApiClient, this);
        }
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d("ali", "onConnected");
        requestPermission();
    }


    @Override
    public void onConnectionSuspended(int i) {
        Log.d("ali", "onConnectionSuspended");
    }


    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.d("ali", "onConnectionFailed");
    }


    @Override
    public void onLocationChanged(Location location) {
        Log.d("ali", "onLocationChanged : " + location);
        mCallback.onLocationUpdate(location);
    }


    @Override
    public void onGpsStatusChange() {
        Log.d("ali", "onGpsStatusChange");
        if(isInitialized && !isPermissionLocked) {
            if (!isLocationEnabled(mContext)) {
                isLocationEnabled = false;
                isPermissionLocked = true;
                stopLocationUpdates();
                requestPermission();
            }
        }
    }


    private void requestPermission(){
        if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED){
            String[] appPerm = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
            ActivityCompat.requestPermissions(mActivity, appPerm, LOCATION_PERMISSION_REQUEST_CODE);
        }else{
            getLocationSetting();
        }
    }


    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == GPSLocation.REQUEST_CHECK_SETTINGS) {
            if (resultCode == Activity.RESULT_OK) {
                getLastKnownLocation();
            }else{
                Toast.makeText(mContext, "Permission Denied", Toast.LENGTH_SHORT).show();
                mCallback.onLocationSettingsError();
            }
        }
    }


    private void getLocationSetting(){
        LocationSettingsRequest.Builder builder =
                new LocationSettingsRequest
                        .Builder()
                        .addLocationRequest(mLocationRequest);

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

        result.setResultCallback(new ResultCallback<LocationSettingsResult>(){
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        Log.d("ali", "SUCCESS");
                        isLocationEnabled = true;
                        isPermissionLocked = false;
                        getLastKnownLocation();
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        Log.d("ali", "RESOLUTION_REQUIRED");
                        try {
                            status.startResolutionForResult(
                                    mActivity,
                                    REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            e.printStackTrace();
                            mCallback.onLocationSettingsError();
                        }finally {
                            isPermissionLocked = false;
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        Log.d("ali", "SETTINGS_CHANGE_UNAVAILABLE");
                        Toast.makeText(mContext, "Location Unavailable", Toast.LENGTH_SHORT).show();
                        mCallback.onLocationSettingsError();
                        isPermissionLocked = false;
                        break;
                }
            }
        });

    }


    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        int permState;
        switch (requestCode) {
            case LOCATION_PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0) {
                    if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                        if(!ActivityCompat.shouldShowRequestPermissionRationale(
                                mActivity,
                                Manifest.permission.ACCESS_FINE_LOCATION)){
                            permState = PERMISSION_BLOCKED;
                        }else{permState = PERMISSION_DENIED;}
                    }else {permState = PERMISSION_GRANTED;}
                }
                else{permState = PERMISSION_DENIED;}

                switch (permState){
                    case PERMISSION_BLOCKED:
                        Toast.makeText(mContext,"Please give gps location permission to use the app.",Toast.LENGTH_LONG).show();
                        startInstalledAppDetailsActivity(mContext);
                        mCallback.onLocationPermissionDenied();
                        break;
                    case PERMISSION_DENIED:
                        Toast.makeText(mContext,"Permission Denied, app cannot access the gps location.", Toast.LENGTH_LONG).show();
                        break;
                    case PERMISSION_GRANTED:
                        getLocationSetting();
                        break;
                }
                break;
        }
    }

    public static boolean isLocationEnabled(Context context){
        LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        boolean gpsEnabled = false;
        boolean networkEnabled = false;

        try {
            gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch(Exception ex) {}

        try {
            networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch(Exception ex) {}

        return gpsEnabled && networkEnabled;
    }

    public static void startInstalledAppDetailsActivity(final Context context) {
        if (context == null) {
            return;
        }
        final Intent i = new Intent();
        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.setData(Uri.parse("package:" + context.getPackageName()));
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(i);
    }

    public static boolean checkLocationPermission(Context context) {
        String permission = "android.permission.ACCESS_FINE_LOCATION";
        int res = context.checkCallingOrSelfPermission(permission);
        return (res == PackageManager.PERMISSION_GRANTED);
    }

    public interface LocationCallback {
        void onLastKnowLocationFetch(Location location);
        void onLocationUpdate(Location location);
        void onLocationPermissionDenied();
        void onLocationSettingsError();
    }


    public void close() {
        mGPSStatusReceiver.unRegisterReceiver();
    }
}

5。在活动中使用以下代码

public class MainActivity extends AppCompatActivity implements GPSLocation.LocationCallback {

    private GPSLocation mGPSLocation;

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

        mGPSLocation = new GPSLocation(this, this);
        mGPSLocation.init();
    }

    @Override
    public void onLastKnowLocationFetch(Location location) {
        if(location != null) {
            Log.d("ali ", "onLastKnowLocationFetch " + location);
        }
    }

    @Override
    public void onLocationUpdate(Location location) {
        if(location != null) {
            Log.d("ali ", "onLocationUpdate " + location);
        }
    }

    @Override
    public void onLocationPermissionDenied() {

    }

    @Override
    public void onLocationSettingsError() {

    }

    @Override
    protected void onStart() {
        mGPSLocation.connect();
        super.onStart();
    }


    @Override
    public void onResume() {
        super.onResume();
        mGPSLocation.startLocationUpdates();
    }


    @Override
    protected void onPause() {
        super.onPause();
        mGPSLocation.stopLocationUpdates();
    }


    @Override
    protected void onStop() {
        mGPSLocation.disconnect();
        super.onStop();
    }


    @Override
    protected void onDestroy() {
        mGPSLocation.close();
        super.onDestroy();
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == GPSLocation.LOCATION_PERMISSION_REQUEST_CODE) {
            mGPSLocation.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == GPSLocation.REQUEST_CHECK_SETTINGS) {
            mGPSLocation.onActivityResult(requestCode, resultCode, data);
        }
    }
}

【讨论】:

  • 我尝试了您的解决方案,但结果很奇怪。很多时候,我得到了 currentLocation 等于 null 的日志。有时日志是正确的,你知道为什么吗?
  • 当前位置为空,因为当您开始阅读并尝试获取最后一个已知位置时,最后一个已知位置可能在第一次读取时不可用。这就是为什么在活动回调中有一个空检查。让系统读取 GPS 和最后一个已知位置,如果不为空,则在回调中处理结果。否则,根据可见的 GPS 卫星,位置读取是否正确。您必须实施过滤以选择下一个要选择的位置。这是系统提供的原始位置正在被读取。
  • 你能告诉我如何让系统读取gps最后一个已知位置吗?我以为 LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);行获取最后一个已知位置,但返回 null
  • 创建进度对话框并在 onLastKnowLocationFetch(Location location) if location !=null 或 onLocationUpdate(Location location) 当 location !=null 时调用其 show 方法,使用标志控制是否显示一次加载
  • 但是你仍然会得到正在渲染的谷歌地图。因此,当地图上的相机移动时调用对话框取消方法,然后设置 isShown = true,我建议您在启动地图活动时显示加载对话框,并在地图上的相机第一次与您的位置一起移动时取消
【解决方案2】:

以下代码检查是否启用了定位。如果没有,它会显示警报对话框以启用位置服务。

LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
try {
    gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}catch (Exception ex){}
try{
    network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}catch (Exception ex){}
if(!gps_enabled && !network_enabled){
    AlertDialog.Builder dialog = new AlertDialog.Builder(this);
    dialog.setMessage(getResources().getString(R.string.gps_network_not_enabled));
    dialog.setPositiveButton(getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface paramDialogInterface, int paramInt) {                 
            Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            Startup.this.startActivity(myIntent);                    
        }
    });
    dialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface paramDialogInterface, int paramInt) {
            // TODO Auto-generated method stub

        }
    });
    dialog.show();
}

在 AndroidManifest.xml 中添加以下代码

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

【讨论】:

    【解决方案3】:

    为我添加这个覆盖方法它工作正常--

     @Override
    public void onLocationChanged(Location location) {
        getLocation("onLocationChanged");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-13
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      相关资源
      最近更新 更多