繁体   English   中英

Google Maps API V2如何获取位置?

[英]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提供程序将开始使用它。

这些是步骤。

  1. 创造
  2. 要求地点
  3. 等待开火

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
}

github MapMover这里的complete.java代码

我已经在我的应用程序中实现了同样的事情,我首先尝试通过以下方式使用Google Maps来实现:

  1. mGoogleMap.setMyLocationEnabled(真);

  2. mGoogleMap.getMyLocation();

但是问题在于它大部分返回零,因为我们不知道Google地图加载地图后多久才能获得位置信息。

然后,我使用Google Play服务,但有时也会返回零。 最后,我尝试使用Google Play服务和Location Poller Class,这对我来说更好,我不能说完美,但比仅使用Google Play服务更好,这里是希望它对您有帮助的链接

如果您正在寻找的话,这也是LocationManager类的一个非常简单的示例,这是链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM