Android: таймер в фоновом режиме - PullRequest
2 голосов
/ 28 декабря 2010

Привет,

Я пытаюсь реализовать таймер, который отправляет GPS-координаты на мой сервер каждые 10 секунд.

Вот фрагмент кода службы, которую я внедряю:

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Timer timer=new Timer();
        TimerTask tt=new TimerTask(){
            @Override
            public void run() {
                Location loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                sendCoords(String.valueOf(loc.getLatitude()), String.valueOf(loc.getLongitude()));
                Toast.LENGTH_SHORT).show();
                Log.i("EOH",String.valueOf(loc.getLatitude()));
            }
        };
        timer.schedule(tt,0,10000);

        return START_STICKY;
    }

Теперь проблема в том, что что-то внутри run () заставляет мое приложение закрываться принудительно.

Вот дамп LogCat:

12-28 18: 44: 18.284: ОШИБКА / AndroidRuntime (6537): ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: Таймер-0 12-28 18:44:18.284: ОШИБКА / AndroidRuntime (6537): java.lang.RuntimeException: Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare () 12-28 18: 44: 18.284: ОШИБКА / AndroidRuntime (6537): на андроиде.os.Handler. (Handler.java:121) 12-28 18: 44: 18.284: ОШИБКА / AndroidRuntime (6537): на prestocab.driver.Background $ 2. (Background.java:83) 12-28 18: 44: 18.284: ОШИБКА / AndroidRuntime (6537): в prestocab.driver.Background.sendCoords (Background.java:83) 12-28 18: 44: 18.284: ОШИБКА / AndroidRuntime (6537): в prestocab.driver.Background $ 3.run (фон).java: 114) 12-28 18: 44: 18.284: ОШИБКА / AndroidRuntime (6537): at java.util.Timer $ TimerImpl.run (Timer.java:289) 12-28 18: 44: 18.554: ОШИБКА / WindowManager(1310): вернуть в removeWindowLocked

Может кто-нибудь предложить исправление для этого?

Я пробовал использовать функцию locationManager onLocationChanged (), но я могуне устанавливайте интервал в 10 секунд.Видимо, указанное время является лишь руководством, а ОС определяет, что лучше.Даже когда я устанавливаю интервал в 100 секунд, он дает мне местоположение каждую секунду или около того.Отсюда и причина использования таймера.

Надеюсь, кто-нибудь что-нибудь подскажет.

Заранее спасибо,

Ответы [ 3 ]

7 голосов
/ 28 декабря 2010

Я пытаюсь реализовать таймер, который отправляет GPS-координаты на мой сервер каждые 10 секунд.

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

Вот фрагмент кода службы, которую я внедряю:

Это ошибочно. getLastKnownLocation() обычно возвращает null, для начала, за пределами вашей Timer / TimerTask проблемы.

Я надеюсь, что кто-то может что-то предложить.

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

Затем используйте requestLocationUpdates(). Если вы получаете слишком много показаний, игнорируйте те, которые вам не нужны, и не отправляйте их на сервер. И, конечно, пожалуйста, запускайте это только в течение короткого периода времени и только на основании положительного запроса пользователя (например, явного запуска вашего приложения), учитывая потребление батареи, связанное с поддержанием GPS-радио.

Документация по requestLocationUpdates() определенно сбивает с толку в плане синхронизации - я только недавно понял, что минимальное время не обязательно соблюдается.

1 голос
/ 28 июня 2011

Поскольку вы вызываете элемент Main UI во внешнем потоке, поэтому поток MainUI сделает исключение, используя это при вызове Toast или любого другого компонента UI: -

Сделайте обработчик следующим образом: -

Handler progressHandler = new Handler() {
    public void handleMessage(Message msg) {
        // display UI , Update UI
        /* To do your UI updation here */
    }
};

Теперь создайте свою тему следующим образом: -

Thread background = new Thread (new Runnable() {
    @Override
    public void run() {
        // this will be done in the Pipeline Thread
        /* Do your GPS task here */
        // active the update handler
        progressHandler.sendMessage(progressHandler.obtainMessage());
    }
});

// start the background thread
background.start();

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

1 голос
/ 29 декабря 2010

Я заметил в трассировке стека утверждение о «Не могу создать обработчик внутри потока, который не вызвал Looper.prepare () .......», который напоминает мне об ошибке типа перекрестного потока или ситуации, в которойобъект еще не завершил настройку своего внутреннего состояния.

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

...