Какой самый простой и надежный способ узнать текущее местоположение пользователя на Android?

Чтобы подтвердить загрузку cdn-скрипта, вы можете проверить наличие какой-либо переменной / функции, которую этот скрипт определяет, если он не определен - тогда cdn не удалось, и вам нужно загрузить копию локального скрипта.

В этом принципе такие как:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.5.1.min.js">\x3C/script>')</script>

(если нет свойства window.jQuery, указанный скрипт cdn не загружен).

Вы можете создавать свои собственные решения с помощью этого метода. Например, плагин jQuery tooltip создает функцию $.tooltip(), поэтому мы можем проверить ее с помощью кода следующим образом:

<script>
    if (typeof $.tooltip === 'undefined') {
        document.write('<script src="js/libs/jquery.tooltip.min.js">\x3C/script>');
    }
</script>
773
задан Vivek Barai 12 January 2018 в 05:35
поделиться

4 ответа

Вот что я делаю:

  1. Прежде всего, я проверяю, какие провайдеры включены. Некоторые могут быть отключены на устройстве, некоторые могут быть отключены в манифесте приложения.
  2. Если какой-либо провайдер доступен, я запускаю слушателей местоположения и таймер таймаута. В моем примере он составляет 20 секунд, для GPS этого может быть недостаточно, поэтому вы можете увеличить его.
  3. Если я получаю обновление от прослушивателя местоположения, я использую предоставленное значение. Я останавливаю слушателей и таймер.
  4. Если я не получаю никаких обновлений и таймер истек, я должен использовать последние известные значения.
  5. Я беру последние известные значения от доступных провайдеров и выбираю самое последнее из них.

Вот как я использую свой класс:

LocationResult locationResult = new LocationResult(){
    @Override
    public void gotLocation(Location location){
        //Got the location!
    }
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);

А вот класс MyLocation:

import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class MyLocation {
    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(), 20000);
        return true;
    }

    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerNetwork);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerGps);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    class GetLastLocation extends TimerTask {
        @Override
        public void run() {
             lm.removeUpdates(locationListenerGps);
             lm.removeUpdates(locationListenerNetwork);

             Location net_loc=null, gps_loc=null;
             if(gps_enabled)
                 gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
             if(network_enabled)
                 net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

             //if there are both values use the latest one
             if(gps_loc!=null && net_loc!=null){
                 if(gps_loc.getTime()>net_loc.getTime())
                     locationResult.gotLocation(gps_loc);
                 else
                     locationResult.gotLocation(net_loc);
                 return;
             }

             if(gps_loc!=null){
                 locationResult.gotLocation(gps_loc);
                 return;
             }
             if(net_loc!=null){
                 locationResult.gotLocation(net_loc);
                 return;
             }
             locationResult.gotLocation(null);
        }
    }

    public static abstract class LocationResult{
        public abstract void gotLocation(Location location);
    }
}

Возможно, кто-то захочет изменить мою логику. Например, если вы получаете обновление от провайдера сети, не останавливайте слушателей, а продолжайте ждать. GPS дает более точные данные, поэтому стоит подождать. Если таймер истек, а вы получили обновление от сети, но не от GPS, то вы можете использовать значение, предоставленное сетью.

Еще один подход - использовать LocationClient http://developer.android.com/training/location/retrieve-current.html. Но он требует установки Google Play Services apk на устройство пользователя.

928
ответ дан 22 November 2019 в 21:21
поделиться

В Действии Класс делает специализированный метод:

private void getTheUserPermission() {
        ActivityCompat.requestPermissions(this, new String[]
                {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        LocationGetter locationGetter = new LocationGetter(FreshMenuSearchActivity.this, REQUEST_LOCATION, locationManager);


        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {

            locationGetter.OnGPS();
        } else {

            locationGetter.getLocation();
        }
    }

Делают имя класса locationgetter:-

public class LocationGetter {

        private int REQUEST_LOCATION;
        private FreshMenuSearchActivity mContext;
        private LocationManager locationManager;
        private Geocoder geocoder;

        public LocationGetter(FreshMenuSearchActivity mContext, int requestLocation, LocationManager locationManager) {
            this.mContext = mContext;
            this.locationManager = locationManager;
            this.REQUEST_LOCATION = requestLocation;
        }


        public void getLocation() {

            if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,

                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(mContext, new String[]
                        {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
            } else {
                Location LocationGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                Location LocationNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                Location LocationPassive = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);

                if (LocationGps != null) {
                    double lat = LocationGps.getLatitude();
                    double longi = LocationGps.getLongitude();
                    getTheAddress(lat, longi);
                } else if (LocationNetwork != null) {
                    double lat = LocationNetwork.getLatitude();
                    double longi = LocationNetwork.getLongitude();
                    getTheAddress(lat, longi);
                } else if (LocationPassive != null) {
                    double lat = LocationPassive.getLatitude();
                    double longi = LocationPassive.getLongitude();
                    getTheAddress(lat, longi);
                } else {
                    Toast.makeText(mContext, "Can't Get Your Location", Toast.LENGTH_SHORT).show();
                }

            }

        }

        private void getTheAddress(double latitude, double longitude) {
            List<Address> addresses;
            geocoder = new Geocoder(mContext, Locale.getDefault());

            try {
                addresses = geocoder.getFromLocation(latitude, longitude, 1);
                String address = addresses.get(0).getAddressLine(0);
                String city = addresses.get(0).getLocality();
                String state = addresses.get(0).getAdminArea();
                String country = addresses.get(0).getCountryName();
                String postalCode = addresses.get(0).getPostalCode();
                String knownName = addresses.get(0).getFeatureName();
                Log.d("neel", address);
            } catch (IOException e) {
                e.printStackTrace();
            }


        }

        public void OnGPS() {

            final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);

            builder.setMessage("Enable GPS").setCancelable(false).setPositiveButton("YES", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mContext.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
            }).setNegativeButton("NO", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    dialog.cancel();
                }
            });
            final AlertDialog alertDialog = builder.create();
            alertDialog.show();
        }

    }
UserDefined
0
ответ дан 22 November 2019 в 21:21
поделиться

Я не уверен, могут ли службы определения местоположения получать информацию о местоположении из других инфраструктур, кроме GPS, но, согласно этой статье, это кажется возможным:

Приложения могут звонить на любой из несколько видов методов позиционирования.

Использование сети мобильной связи: текущий идентификатор ячейки может быть использован для определить базовую приемопередающую станцию (BTS), что устройство обменивается данными с и местонахождением этой BTS.Ясно, что точность этого метода зависит от размера ячейки, а может быть довольно неточным. Сотовая связь GSM может быть от 2 до 20 километров в диаметре. Другой методы, используемые вместе с идентификатором соты, могут достичь точности в пределах 150 метров.

Использование спутников: The Global Система позиционирования (GPS), управляемая Министерством обороны США, использует созвездие из 24 спутников на орбите Земли. GPS определяет положение устройства путем расчета различия во временном сигнале от разные спутники нужны, чтобы достичь получатель. Сигналы GPS кодируются, поэтому мобильное устройство должно быть оборудовано с GPS-приемником. GPS есть потенциально самый точный метод (от 4 до 40 метров, если GPS приёмник имеет хороший обзор неба), но у него есть недостатки: лишний оборудование может быть дорогостоящим, потребляет аккумулятор во время использования и требует немного разминки после холодного старта, чтобы получить начальное исправление видимых спутников. Он также страдает от "эффектов каньона". в городах, где видимость со спутника прерывистый.

Использование ближнего боя позиционирование маяков: относительно небольшие участки, такие как одиночный здание, локальная сеть может предоставить места вместе с другими Сервисы. Например, уместно оборудованные устройства могут использовать Bluetooth для ближнее позиционирование.

5
ответ дан 22 November 2019 в 21:21
поделиться

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

И простой способ получить общее местоположение - это зарегистрироваться в сети (обычно довольно быстро).

LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
     LocationManager.NETWORK_PROVIDER, 1000, 1000, this);

, а затем выполнение

locationManager.removeUpdates(this);

в методе onLocationChanged () слушателя.

14
ответ дан 22 November 2019 в 21:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: