Google Maps API V2如何获取位置?

时间:2014-04-08 10:47:15

标签: java android google-maps-android-api-2

我想揭露以下问题。

我有一个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类上使用的方法更有效。

非常感谢你阅读我的帖子

2 个答案:

答案 0 :(得分:1)

Google正在使用googleplayservices中的位置提供商。它非常高效且易于编码。第一个位置(最后一个已知的位置)非常快。

没有一个复杂的检查提供商,它只适用于打开的东西。意思是如果用户以某种方式打开gps。 googleplayservices提供商将开始使用它。

这些是步骤。

  1. 创建
  2. 连接
  3. 地点要求
  4. 等待onlocation开火
  5. 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
    }
    

    github MapMover the complete.java code here

答案 1 :(得分:0)

我在我的应用程序中实现了同样的功能,我首先尝试使用谷歌地图:

  1. mGoogleMap.setMyLocationEnabled(真);

  2. mGoogleMap.getMyLocation();

  3. 但问题是它大部分都归零,因为我们不知道Google地图在加载地图后获取位置的时间有多长。

    然后我使用谷歌播放服务,但它有时也返回零。 最后,我尝试使用Google Play服务和位置轮询类,这对我来说更好,我不能说完美,但比仅使用Google Play服务更好link希望它有所帮助。

    如果您正在寻找的是link

    ,这里还有一个非常简单的LocationManager类示例