2013-07-18 3 views
1

Я пытаюсь понять, что в Android-локации найдено много кода в Интернете, все они выглядят по-разному, и они жонглируют библиотеками по-разному, что меня смущает. Я не смог найти широко используемый подход.Проблемы с местоположением Android

В принципе, мне нужно получить местоположение с помощью GPS, если местоположение не удалось получить в течение 90 секунд с помощью GPS, затем получите местоположение, предоставленное сетью. Каков самый простой способ сделать это?

Я тестировал следующий фрагмент, но результаты на устройстве не являются надежными, иногда неясно, как убедиться, что getLastKnownLocation() не получает старое сохраненное местоположение, которое не является текущим. Благодаря!

location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
    if (location != null) { 
    gps_latitude = location.getLatitude(); 
    gps_longitude = location.getLongitude(); 
    gps_timestamp = location.getTime(); 
    gps_accuracy = location.getAccuracy(); 
    gps_provider = location.getProvider(); 
    gps_speed = location.getSpeed(); 
} 
+0

См. Мой отредактированный ответ –

ответ

3

Попробуйте LocationCLient, чтобы получить лучшее последнее известное местоположение. Этот класс использует сочетание GPS, WiFi и датчиков для автоматического определения текущего местоположения. Таким образом, нет необходимости выбирать между GPS или сетью.

Это guide как его использовать.

EDIT: Вы должны использовать Google Play Services библиотеку, которая совместима с API 8.

+0

Я использую API 8 – user2566468

0

Вы уверены, что вам нужно расставить приоритеты местоположение GPS так трудно? Есть несколько недостатков, чтобы трудное требование о поставщике GPS:

  1. Вы должны использовать самый старый API, так как это единственный, где вы можете явно заставить какой «тип» затруднительные вы получите. (The «LocationManager»)

  2. Это, как правило, значительно хуже из пользовательского опыта точки зрения, так как она занимает больше времени, чтобы получить GPS фикс, он не будет работать в помещении и т.д.

  3. Поздние API, есть много отличной логики, в которой можно взвешивать такие вещи, как время автономной работы, быстрота, точность и т. д.

Я ничего не знаю о вашем применении, конечно, просто опрокидывая вас, чтобы подумать о том, каковы ваши настоящие требования.

Есть и другие преимущества для «нового» API-интерфейсов, которые я обнаружил, из первых рук при переключении в нашем приложении около 18 месяцев назад:

Это быстрее и надежнее. он менее багги. Например, в старом API иногда можно получить «старое» исправление с новой меткой времени. Это никогда не бывает. Там больше, но это будет еще более длинный пост. Это определенно истощает меньше батареи. Например, когда вы открывали карту, GPS постоянно работал, и значок GPS был виден. Это не относится к новой. Это заставило пользователей задаться вопросом, что происходит. Это еще одна проблема. Итак, когда дело доходит до выхода и работы, все лучше. Но есть и некоторые минусы:

У вас должно быть установлено приложение Google Play Services, что означает, что он не будет работать на каких-либо моделях телефонов, не одобренных Google, и в некоторых случаях вам нужно будет сообщить пользователям, которых они должны установить Это.

API сам по себе более сложный IMO, частично из-за пункта 1. В дополнение к «обычным» обратным вызовам, то есть ожиданию исправлений местоположения и т. Д.Теперь у вас есть процесс, который принимает участие, прежде чем вы сможете начать, где вам нужно проверить, что доступны сервисы, и «подключить» локатор. Это дополнительный код и немного сложнее понять. Более ошибочные условия, которые необходимо учитывать и в коде (если вас это беспокоит ...)

Служба Google Play сама по себе требует не менее 2,2, чтобы она не работала для более старых устройств, чем это. Мы должны были рассказать некоторым клиентам, которых они должны были обновить ...

Надеюсь, это поможет!

0

Используйте код ниже. Он отлично работает для меня. Его дает мне место на обоих GPS и сети

package com.fudiyo.LocationTracker; 

import android.app.Dialog; 
import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.provider.Settings; 
import android.util.Log; 
import android.view.View; 
import android.view.Window; 
import android.widget.Button; 

import com.fudiyo.R; 

public class GPSLocationNetwork extends Service implements LocationListener { 

    private final Context mContext; 

    // flag for GPS status 
    boolean isGPSEnabled = false; 

    // flag for network status 
    boolean isNetworkEnabled = false; 

    // flag for GPS status 
    boolean canGetLocation = false; 

    Location location; // location 
    double latitude; // latitude 
    double longitude; // longitude 

    // The minimum distance to change Updates in meters 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters 

    // The minimum time between updates in milliseconds 
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute 

    // Declaring a Location Manager 
    public LocationManager locationManager; 

    public GPSLocationNetwork(Context context) { 
     this.mContext = context; 
     getLocation(); 
    } 

    @SuppressWarnings("static-access") 
    public Location getLocation() { 
     try { 
      locationManager = (LocationManager) mContext 
        .getSystemService(mContext.LOCATION_SERVICE); 

      // getting GPS status 
      isGPSEnabled = locationManager 
        .isProviderEnabled(LocationManager.GPS_PROVIDER); 

      // getting network status 
      isNetworkEnabled = locationManager 
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
      // 
      if (!isNetworkEnabled) { 
       // no network provider is enabled 
      } else { 
       this.canGetLocation = true; 
       // First get location from Network Provider 
       if (isNetworkEnabled) { 
        locationManager.requestLocationUpdates(
          LocationManager.NETWORK_PROVIDER, 
          MIN_TIME_BW_UPDATES, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 

        Log.d("Network", "Network"); 
        if (locationManager != null) { 
         location = locationManager 
           .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (location != null) { 
          latitude = location.getLatitude(); 
          longitude = location.getLongitude(); 
         } 
        } 
       } 
      } 
       // if GPS Enabled get lat/long using GPS Services 
       if (isGPSEnabled) { 
        this.canGetLocation = true; 
        if (location == null) { 
         locationManager.requestLocationUpdates(
           LocationManager.GPS_PROVIDER, 
           MIN_TIME_BW_UPDATES, 
           MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
         Log.d("GPS Enabled", "GPS Enabled"); 
         if (locationManager != null) { 
          location = locationManager 
            .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
          if (location != null) { 
           latitude = location.getLatitude(); 
           longitude = location.getLongitude(); 
          } 
         } 
        } 
       } 


     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return location; 
    } 

    /** 
    * Stop using GPS listener Calling this function will stop using GPS in your 
    * app 
    * */ 
    public void stopUsingGPS() { 
     if (locationManager != null) { 
      locationManager.removeUpdates(GPSLocationNetwork.this); 
     } 
    } 

    /** 
    * Function to get latitude 
    * */ 
    public double getLatitude() { 
     if (location != null) { 
      latitude = location.getLatitude(); 
     } 

     // return latitude 
     return latitude; 
    } 

    /** 
    * Function to get longitude 
    * */ 
    public double getLongitude() { 
     if (location != null) { 
      longitude = location.getLongitude(); 
     } 

     // return longitude 
     return longitude; 
    } 

    /** 
    * Function to check GPS/wifi enabled 
    * 
    * @return boolean 
    * */ 
    public boolean canGetLocation() { 
     return this.canGetLocation; 
    } 

    /** 
    * Function to show settings alert dialog On pressing Settings button will 
    * lauch Settings Options 
    * */ 
    public void showSettingsAlert() { 



     final Dialog gpsDialog = new Dialog(mContext); 
     gpsDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 

     gpsDialog.setContentView(R.layout.gps_enable_dialog); 
     gpsDialog.setCancelable(true); 

     Button gpsSettingBtn = (Button) gpsDialog 
       .findViewById(R.id.btn_setting_gps_dialog); 
     Button gpsCancelBtn = (Button) gpsDialog 
       .findViewById(R.id.btn_cancel_gps_dialog); 

     gpsSettingBtn.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 


       gpsDialog.dismiss(); 
       Intent intent = new Intent(
         Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
       mContext.startActivity(intent); 
      } 
     }); 

     gpsCancelBtn.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 

       gpsDialog.dismiss(); 
      } 
     }); 

     gpsDialog.show(); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     this.location = location; 
     getLatitude(); 
     getLongitude(); 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
    } 

    @Override 
    public IBinder onBind(Intent arg0) { 
     return null; 
    } 

} 
+1

Хотя этот код может ответить на вопрос, было бы лучше объяснить, как он решает проблему, не вводя других и почему ее использовать. Ответы только на код не полезны в долгосрочной перспективе. – JAL

1

Немного запоздалые для партии, но полагал, что это было бы целесообразно, чтобы получить возможность отправлять обновления для людей, читающих это в 2016 году (или позже).

Как было предложено другими ответами, лучшим способом в настоящее время является использование API-интерфейса Google Apps для сервисов. Если вам действительно не нужен мелкомасштабный контроль поставщиков местоположения, Google API обязуется дать вам более точную оценку местоположения за более короткое время, используя только ресурсы (GPS, WiFi, Cell Tower, Bluetooth), которые действительно необходимы для устройства каждого пользователя.

К сожалению, подписка на обновления местоположения по-прежнему может быть затруднительной (как указывал Matthias, API немного сложнее). Вы должны сделать некоторые или все из следующих действий:

  • После: Запрашивать разрешение местоположения (Зефир и выше)
  • Подключение к API, обрабатывать различные ошибки и угловые случаи
  • Проверить и, возможно, включить необходимые провайдеры местонахождения
  • обновления Запрос местоположения

Я боролся с установкой обновлений местоположения в нескольких различных проектах и ​​решить, d, чтобы написать класс, который делает большую часть работы для вас:

LocationAssistant - Hassle-free location updates on Android

Я также написал подробное сообщение в блоге о настройке Android расположение на широком диапазоне Android версий, которые вы можете read here.


Таким образом, чтобы решить исходную задачу (получить последнюю актуальную местоположение с точностью GPS как можно быстрее):

public class MyActivity extends Activity implements LocationAssistant.Listener { 

    private LocationAssistant assistant; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     ... 
     // You can specify a different accuracy and interval here, depending on the needs of your app 
     assistant = new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, true); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     assistant.start(); 
    } 

    @Override 
    protected void onPause() { 
     assistant.stop(); 
     super.onPause(); 
    } 

    @Override 
    public void onNewLocationAvailable(Location location) { 
     // Do something with the location 
    } 

    ... 
} 

onNewLocationAvailable() вызывается как только первое правильное местоположение является доступный. Существует несколько методов прослушивателя, которые необходимо реализовать для решения ситуаций, когда разрешение не предоставляется или поставщики местоположения отключены. Но в сущности это он.

LocationAssistant также позволяет надежно отбрасывать ложные местоположения (в случае, если это требуется для вашего приложения).

Смежные вопросы