我想揭露以下问题。
我有一个Android应用程序,它同时使用了UserLocation(我开发了自己的类,以便在应用程序显示时如下所述)和Google Maps Api v2。
假设该应用有两个按钮 按钮一 - >当用户点击应用程序显示带有大量标记的地图时,我使用google maps api V2片段。我可以使用以下行来显示用户位置。
mMap.setMyLocationEnabled(true);
按钮2 - >启动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类上使用的方法更有效。
非常感谢你阅读我的帖子
答案 0 :(得分:1)
Google正在使用googleplayservices中的位置提供商。它非常高效且易于编码。第一个位置(最后一个已知的位置)非常快。
没有一个复杂的检查提供商,它只适用于打开的东西。意思是如果用户以某种方式打开gps。 googleplayservices提供商将开始使用它。
这些是步骤。
github MapMover the complete.java code here
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
}
答案 1 :(得分:0)