[英]How Google Maps API V2 Gets Location?
我想提出以下问题。
我有一个Android应用程序,它同时使用了UserLocation(我开发了自己的类,以获取应用程序的时间,如下所述)和Google Maps Api v2。
假设该应用程序有两个按钮按钮一个->当用户单击该应用程序时,会显示带有很多标记的地图,我使用了Google Maps api V2片段。 我可以使用以下行显示用户位置。
mMap.setMyLocationEnabled(true);
按钮两个->启动AsyncTask以获取用户位置并计算壁橱位置,然后在Map和ListView上显示。 下面,我提供我所有的代码来做到这一点:
private class findPosicionTask extends AsyncTask<Void,Integer,Location>
{
private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
private int error = 0;
private Activity actividad;
private int procesoTerminado=0;
public findPosicionTask(Activity actividad)
{
this.actividad = actividad;
}
@Override
protected void onPreExecute()
{
if (!LocationSettingsManager.isLocationServiceAvaliable(getApplicationContext()))
{
cancel(true);
}
else
{
this.dialog.setMessage(getString(R.string.obteniendoPoisicion));
this.dialog.show();
}
}
@Override
protected Location doInBackground(Void... params)
{
if (this.error==0)
{
try
{
Looper.prepare();
MyLocationManager.LocationResult locationResult = new MyLocationManager.LocationResult(){
@Override
public void gotLocation(Location location) {
if (location!=null)
{
LocationSingleton posicionSingleton = (LocationSingleton)getApplication();
posicionSingleton.setMiPoscion(location);
posicionSingleton.setFecha(new Date());
procesoTerminado=1;
onPostExecute(location);
}
else
{
procesoTerminado=1;
onPostExecute(location);
}
}
};
MyLocationManager myLocation = new MyLocationManager();
if (!myLocation.getLocation(getApplicationContext(), locationResult))
{
}
}
catch (Exception e)
{
error=2;
cancel(true);
return null;
}
}
return null;
}
@Override
protected void onPostExecute(Location posicion)
{
if (procesoTerminado==1)
{
if (this.dialog.isShowing())
{
this.dialog.dismiss();
}
if (error==0)
{
if (posicion==null)
{
MessageManager.muestraMensaje(this.actividad, R.string.noSeObtuvoLocalizacion);
}
else
{
ArrayList centros = DBFacade.findCentros(getBaseContext());
ArrayList<Centro> centrosMasCercanos = DistanciasManager.getCentrosMasCercanos(posicion, centros);
Intent i = new Intent(getBaseContext(), CentrosCercanosActivity.class);
i.putExtra("centrosMasCercanos", centrosMasCercanos);
i.putExtra("posicion", posicion);
startActivity(i);
}
}
else
{
if (error==2)
{
MessageManager.muestraMensaje(this.actividad, R.string.noSeObtuvoLocalizacion);
}
}
}
}
@Override
protected void onCancelled() {
super.onCancelled();
if (this.dialog.isShowing())
{
this.dialog.dismiss();
}
MessageManager.muestraMensaje(this.actividad, R.string.servicioLocalizacionDesactivado);
}
}
这是我自己的MyLocationManager类
public class MyLocationManager {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try
{
gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
catch(Exception ex)
{
}
try
{
network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
catch(Exception ex)
{
}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if (gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if (network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 5000);
return true;
}
LocationListener locationListenerGps = new LocationListener()
{
@Override
public void onLocationChanged(Location location) {
Location gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
long diffInMs = (new Date().getTime()/60000) - (gps_loc.getTime()/60000);
if (diffInMs<1)
{
if (((int)gps_loc.getAccuracy())<=3000)
{
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
timer1.cancel();
locationResult.gotLocation(gps_loc);
Looper.loop();
return;
}
}
}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener()
{
@Override
public void onLocationChanged(Location location) {
Location net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
long diffInMs = (new Date().getTime()/60000) - (net_loc.getTime()/60000);
if (diffInMs<1)
{
if (((int)net_loc.getAccuracy())<=3000)
{
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
timer1.cancel();
locationResult.gotLocation(net_loc);
Looper.loop();
return;
}
}
}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask
{
@Override
public void run()
{
Looper.prepare();
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null;
Location gps_loc=null;
Location finalLocation=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
long diffInMs;
if (gps_loc!=null)
{
diffInMs = (new Date().getTime()/60000) - (gps_loc.getTime()/60000);
if (diffInMs>1)
gps_loc=null;
}
if (net_loc!=null)
{
diffInMs = (new Date().getTime()/60000) - (net_loc.getTime()/60000);
if (diffInMs>1)
net_loc=null;
}
if (gps_loc!=null || net_loc!=null)
{
int gpsAccuracy = 1000000;
int netAccuracy = 1000000;
if (gps_loc!=null)
gpsAccuracy = (int)gps_loc.getAccuracy();
if (net_loc!=null)
netAccuracy = (int)net_loc.getAccuracy();
if (netAccuracy<gpsAccuracy)
finalLocation=net_loc;
else
finalLocation=gps_loc;
if (((int)finalLocation.getAccuracy())<=3000)
{
locationResult.gotLocation(finalLocation);
Looper.loop();
return;
}
else
{
locationResult.gotLocation(null);
Looper.loop();
return;
}
}
else
{
locationResult.gotLocation(null);
Looper.loop();
return;
}
}//fin del run
}//fin de la clase GetLastLocation
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
如您在AsyncTask的OnPreExecute方法上所看到的,请检查是否启用了位置提供程序:
public static boolean isLocationServiceAvaliable(Context mContext)
{
String locationProviders = Settings.Secure.getString(mContext.getContentResolver(),Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (locationProviders.trim().equals(""))
return false;
else
return true;
}
好吧,在大多数情况下,应用程序都能正常运行,但是在某些情况下(这让我发疯了),方法“ isLocationServiceAvaliable”返回false,因此该应用程序表示未启用位置提供程序。
即使在设备设置上启用了位置提供程序,也会发生这种情况,更极端的是,如果用户单击“按钮一”,则该应用会正确显示用户位置的google地图。
那么,即使当前未启用提供商,Google Maps Api V2如何获取设备位置呢? 有什么方法可以使用与我在MyLocationManager类上使用的方法似乎更有效的方法相同的方法。
非常感谢您阅读我的帖子
Google正在使用googleplayservices的位置提供程序。 它超级高效且超级容易编码。 第一个位置(最后知道的位置)来的很快。
对于提供者,没有复杂的检查,它只能与打开的东西一起使用。 意味着用户是否以某种方式打开了gps。 googleplayservices提供程序将开始使用它。
这些是步骤。
github MapMover这里的complete.java代码
locationClient = new LocationClient(activity, this, this);
locationClient.connect();
public void onConnected(Bundle dataBundle) {
// Create a new global location parameters object
locationRequest = LocationRequest.create();
// Set the update interval 70% of the interval
// this is to make sure we have an updated location
// when the animation completes
locationInterval = (long) (interval * .70);
locationRequest.setInterval(locationInterval);
locationRequest.setFastestInterval(locationInterval);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationClient.requestLocationUpdates(locationRequest, this);
}
@Override
public void onLocationChanged(Location location) {
// here you have a location to do with what you will
}
我已经在我的应用程序中实现了同样的事情,我首先尝试通过以下方式使用Google Maps来实现:
mGoogleMap.setMyLocationEnabled(真);
mGoogleMap.getMyLocation();
但是问题在于它大部分返回零,因为我们不知道Google地图加载地图后多久才能获得位置信息。
然后,我使用Google Play服务,但有时也会返回零。 最后,我尝试使用Google Play服务和Location Poller Class,这对我来说更好,我不能说完美,但比仅使用Google Play服务更好,这里是希望它对您有帮助的链接 。
如果您正在寻找的话,这也是LocationManager类的一个非常简单的示例,这是链接
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.