当前位置失败 GoogleMap

Posted

技术标签:

【中文标题】当前位置失败 GoogleMap【英文标题】:Current Location failed 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 //如果没有就做你需要的启用... 并在此处引用***.com/questions/843675/… 【参考方案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;
                        elsepermState = PERMISSION_DENIED;
                    else permState = PERMISSION_GRANTED;
                
                elsepermState = 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");

【讨论】:

以上是关于当前位置失败 GoogleMap的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Google Maps v2 上将标记添加到当前位置?

Google Maps Android API v2,错误的标记位置

在“不允许”位置获取后,sendSynchronousRequest 在 3.1.2 下失败

为啥在我的代码中获取状态位置的 mciSendString() 失败?

Fused Location Provider:有没有办法检查位置更新是不是失败?

无法在位置更改时获取当前位置 android