Тайм-аут Android GPS - PullRequest
       13

Тайм-аут Android GPS

12 голосов
/ 07 июня 2010

Редактировать: Я переписываю этот вопрос, потому что я, видимо, не ясно.

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

У меня есть приложение, которое делает много вещей. Одна из вещей, которую он должен сделать, - позволить пользователю нажать кнопку, чтобы отправить свои текущие координаты на сервер. Мне нужны координаты телефона , когда пользователь нажимает кнопку или в течение достаточно короткого времени после этого.

Поскольку я знаю, что получение исправления GPS не является мгновенным, и я знаю, что это может занять минуты или часы (в течение которых пользователь продвинулся на большое расстояние), мне нужно кодировать время ожидания для этой функции. Для этой функции просто недопустимо загружать местоположение GPS пользователя через три минуты (например) после того, как он нажал кнопку. Это нормально, если это займет 45 секунд, не хорошо, если это займет 75 секунд. Если пользователь не смог быстро найти местоположение, можно уведомить пользователя об ошибке.

Мне нужна функция для получения местоположения GPS и отправки его на сервер, , если это не займет более одной минуты '.

Мой оригинальный код ниже. Я изменил некоторые вещи с момента публикации. Я добавил таймер в методе onStartCommand (). Я запускаю TimerTask, который через 60 секунд вызовет мой метод stop (). В начале метода onLocationChanged () я отменяю TimerTask.

Мой вопрос: является ли схема Таймера хорошим способом реализации этого тайм-аута? Есть ли лучший способ?

Оригинальный вопрос:

Я пишу приложение для Android, которое, помимо прочего, должно отправлять текущие координаты GPS на сервер, когда пользователь сообщает об этом. Из контекстного меню я запускаю сервис ниже. Служба является LocationListener и запрашивает обновления из LocationManager. Когда он получает местоположение (onLocationChanged ()), он удаляет себя в качестве прослушивателя и отправляет координаты на сервер. Все это работает.

Однако, если GPS-координаты не доступны быстро, моя служба просто продолжает работать, пока не получит некоторые. Он поддерживает интерфейс с диалоговым окном, что раздражает. Хуже того, если пользователь перешел с момента запуска службы, первые координаты GPS могут быть неправильными, и приложение отправит неверные данные на сервер.

Мне нужен тайм-аут на службе. Есть ли хороший способ сделать это? Я не очень опытен с потоками. Я думаю, что я могу запустить Runnable в методе onStartCommand (), который каким-то образом будет отсчитывать 30 секунд, а затем, если еще нет результата GPS, вызвать метод stop () моей службы. Это звучит как лучший способ сделать это?

В качестве альтернативы, можно ли сказать, что GPS не может получить исправление? Как мне это сделать?

Редактировать: Чтобы уточнить, я ищу лучший способ "сдаться" при получении Места через некоторое время.

public class AddCurrentLocation extends Service implements LocationListener {

    Application app;
    LocationManager mLocManager;
    ProgressDialog mDialog;

    @Override
    public int onStartCommand(Intent intent, int arg0, int arg1) {
        app = getApplication();

        // show progress dialog
        if (app.getScreen() != null) {
            mDialog = ProgressDialog.show(app.getScreen(), "", "Adding Location. Please wait...", true);
        }

        // find GPS service and start listening
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        String bestProvider = mLocManager.getBestProvider(criteria, true);
        mLocManager.requestLocationUpdates(bestProvider, 2000, 0, this);

        return START_NOT_STICKY;
    }

    private void stop() {
        mLocManager.removeUpdates(this);
        if (mDialog != null) {
            mDialog.dismiss();
        }
        stopSelf();
    }

    @Override
    public void onLocationChanged(Location location) {
        // done with GPS stop listening
        mLocManager.removeUpdates(this);

        sendLocation(location); // method to send info to server
        stop();
    }

    // other required methods and sendLocation() ...

}

Ответы [ 5 ]

6 голосов
/ 08 июня 2010

Это не совсем так, как это работает.В большинстве ситуаций это займет много времени, чтобы починить GPS.Но с этого момента каждое обновление (каждые 2 секунды в вашем коде) будет текущей позицией человека.И первым исправлением, которое вы получите, будет текущая позиция человека, поэтому данные не будут «устаревшими».

Другое дело.Если вы запускаете этот код в сервисе, вы не должны блокировать пользовательский интерфейс с помощью диалогового окна прогресса и определенно не из Сервиса.Это утечка памяти, ожидающая своего появления.Вы должны показывать прогресс, только если это что-то, что может занять максимум 5 секунд и работает в потоке в Activity.Другой вариант - показать диалоговое окно прогресса в строке заголовка и по-прежнему разрешать пользователю взаимодействовать с приложением (поэтому вы все равно используете службу).Отображение прогресса в течение длительного периода времени действительно не является дружественным к пользователю.Особенно, если они каким-то образом меняют ориентацию (может быть, случайно), а затем происходит сбой вашего приложения из-за дескриптора сервиса для диалога, и им приходится начинать сначала.приложение , чтобы увидеть отличный пример того, как действие должно работать со службой.Он использует сервис для извлечения данных и показывает прогресс в заголовке, когда сервис выполняет некоторую работу.И все же позволяет вам делать другие вещи в приложении.

4 голосов
/ 09 июня 2010

Скотт, есть много факторов, которые влияют на то, сколько времени может занять первое исправление - или даже на то, может ли оно быть достигнуто, наиболее распространенными из которых являются физические препятствия между устройством и спутниками (например, здания, стены каньона и т. Д.).

Вы не можете контролировать, сколько времени понадобится движку GPS для доставки исправления, но вы можете сказать, как оно работает, включая время первого исправления:

locationManager.addGpsStatusListener(gpsListener);

    // this reports on the status of the GPS engine, but does not enable additional controls 
    private static final GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
        public void onGpsStatusChanged(int event) {
            GpsStatus gpsStatus = locationManager.getGpsStatus(null);
            switch (event) {
                case GpsStatus.GPS_EVENT_STARTED: 
                    Log.i(TAG, "onGpsStatusChanged(): GPS started");
                    break;
                case GpsStatus.GPS_EVENT_FIRST_FIX: 
                    Log.i(TAG, "onGpsStatusChanged(): time to first fix in ms = " + gpsStatus.getTimeToFirstFix());
                    break;
                case GpsStatus.GPS_EVENT_SATELLITE_STATUS: 
                    // int maxSatellites = gpsStatus.getMaxSatellites();    // appears fixed at 255
                    // if (H.DEBUG) Log.d(TAG, "onGpsStatusChanged(): max sats = " + maxSatellites);
                    if (H.VERBOSE) Log.d(TAG, "onGpsStatusChanged(): ##,used,s/n,az,el");
                    Iterable<GpsSatellite>satellites = gpsStatus.getSatellites();
                    Iterator<GpsSatellite>satI = satellites.iterator();
                    while (satI.hasNext()) {
                        GpsSatellite satellite = satI.next();
                        if (H.VERBOSE) Log.d(TAG, "onGpsStatusChanged(): " + satellite.getPrn() + "," + satellite.usedInFix() + "," + satellite.getSnr() + "," + satellite.getAzimuth() + "," + satellite.getElevation()); 
                        // http://en.wikipedia.org/wiki/Global_Positioning_System: the almanac consists of coarse orbit and status information for each satellite
                        // http://en.wikipedia.org/wiki/Ephemeris: the positions of astronomical objects in the sky at a given time
                        // + "," + satellite.hasAlmanac() + "," + satellite.hasEphemeris());
                    }
                    break;
                case GpsStatus.GPS_EVENT_STOPPED: 
                    Log.i(TAG, "onGpsStatusChanged(): GPS stopped");
                    break;
            }       
        }
    };

События будут генерироваться при попытке двигателя прослушивать доступные спутники. В недавнем тесте этого с легкими препятствиями я обнаружил, что для первоначального исправления потребовалось 22,4 секунды, в течение которых 24 события SATELLITE_STATUS сообщали о постепенном доступе 8 спутников, прежде чем были получены достаточно чистые сигналы для достижения исправления. Вот последнее событие:

06-08 23: 23: 25.147, D, GPS, 22427, «onGpsStatusChanged (): ##, используется, з / п, аз, эл» 06-08 23: 23: 25.147, D, GPS, 22427, "onGpsStatusChanged (): 2, true, 26.0,57.0,73.0" 06-08 23: 23: 25.147, D, GPS, 22427, "onGpsStatusChanged (): 4, правда, 30.0,46.0,27.0" 06-08 23: 23: 25.147, D, GPS, 22427, "onGpsStatusChanged (): 5, true, 19.0,144.0,25.0" 06-08 23: 23: 25.155, D, GPS, 22427, "onGpsStatusChanged (): 9, правда, 22.0,202.0,22.0" 06-08 23: 23: 25.155, D, GPS, 22427, "onGpsStatusChanged (): 10, true, 17.0,109.0,32.0" 06-08 23: 23: 25.155, D, GPS, 22427, "onGpsStatusChanged (): 12, правда, 32.0 320.0,80.0" 06-08 23: 23: 25.155, D, GPS, 22427, "onGpsStatusChanged (): 29, истина, 21.0,278.0,21.0" 06-08 23: 23: 25.155, D, GPS, 22427, "onGpsStatusChanged (): 30, true, 31.0,312.0,43.0" 06-08 23: 23: 25.163, D, GpsLocationProvider, 1039, TTFF: 22457 06-08 23: 23: 25.194, I, GPS, 22427, onGpsStatusChanged (): время первого исправления в мс = 22457

Обратите внимание, что в назначенное время вы получите текущее местоположение, а не то, где вы когда-то могли быть. Я думаю, что вместе с тем, что у вас уже есть, вы можете добраться туда сейчас. Или посмотрите, как это делают профессионалы здесь .

3 голосов
/ 17 сентября 2010

Существует пример получения местоположения GPS с тайм-аутом.

http://sikazi.blogspot.com/2010/09/android-gps-timeout.html#more

1 голос
/ 04 февраля 2013

Я боролся с подобной проблемой и недавно переключился с таймера на AlarmManager, который кажется намного более устойчивым. Это может быть излишним для вашей ситуации (я использую это для повторной выборки местоположения), но вы можете по крайней мере использовать Handler вместо таймера. (Используйте Handler.postDelayed.)

0 голосов
/ 26 июля 2012

Исходя из ответа Шона, упакуйте параметры в JSON и отправьте объекты JSON на сервер

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...