java - Google Maps API V2 如何获取位置?

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

我想提出以下问题。

我有一个 Android 应用程序,它同时使用了 UserLocation(我开发了自己的类,以便获取应用程序启动的时间,正如我在下面解释的那样)和 Google Maps Api v2。

假设应用程序有两个按钮 按钮一--> 当用户单击应用程序时会显示带有很多标记的 map ,我使用的是 google maps api V2 fragment 。我可能会使用以下行来显示用户位置。

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 Maps Api V2 如何在当前未启用提供程序的情况下获取设备位置?有什么方法可以使用与我在 MyLocationManager 类上使用的方法相比似乎更有效的方法。

非常感谢你阅读我的帖子

最佳答案

Google 正在使用来自 googleplayservices 的位置提供程序。它 super 高效且 super 容易编码。第一个位置(最后一个已知位置)非常快。

没有任何复杂的供应商检查,它只适用于打开的内容。意思是如果用户以某种方式打开 gps。 googleplayservices 提供商将开始使用它。

这些是步骤。

  1. 创建
  2. 连接
  3. 请求位置
  4. 等待onlocation触发

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

关于java - Google Maps API V2 如何获取位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22934689/

相关文章:

java - 将 Excel 单元格内容读取为 Java InputStream

android - 如何在 Android Studio 中使用 onMarkerClick 打开一个新 Activity

android - 如何将经纬度转换为位置变量?

android - 谷歌地图多个标记不显示,一个显示另一个隐藏反之亦然

java - Java 中的线程安全或多线程 CRF 支持连续变量?

Java 并发数 : synchronized statements/methods causing StackOverflowError exception

java - sleep 时线程中断

Android:谷歌加按钮加载永不停止

android - 从Flutter项目构建APK时出错

java - 获取二维数组android之一