当前位置失败 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() 失败?