Android:后台服务中的计时器

时间:2010-12-28 18:47:26

标签: android timer gps

问候,

我正在尝试实施一个定时器,每10秒钟向我的服务器发送一次GPS坐标。

以下是我正在实施的服务的代码段:

@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):致命   例外:Timer-0 12-28 18:44:18.284:   ERROR / AndroidRuntime(6537):   java.lang.RuntimeException:不能   在具有的线程内创建处理程序   不叫做Looper.prepare()12-28   18:44:18.284:   错误/ AndroidRuntime(6537):at   android.os.Handler。(Handler.java:121)   12-28 18:44:18.284:   错误/ AndroidRuntime(6537):at   prestocab.driver.Background $ 2(Background.java:83)   12-28 18:44:18.284:   错误/ AndroidRuntime(6537):at   prestocab.driver.Background.sendCoords(Background.java:83)   12-28 18:44:18.284:   错误/ AndroidRuntime(6537):at   prestocab.driver.Background $ 3.run(Background.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:   ERROR / WindowManager(1310):返回   removeWindowLocked

有人可以建议修复此问题吗?

我已尝试使用locationManager onLocationChanged()函数,但我无法将间隔设置为10秒。显然,指定的时间只是一个指导,操作系统决定什么是最好的。即使我将间隔设置为100秒,它也会每隔一秒钟给我一个位置。因此我使用计时器的原因。

我希望有人能提出建议。

提前致谢,

3 个答案:

答案 0 :(得分:7)

  

我正在尝试实施一个定时器,每10秒钟向我的服务器发送一次GPS坐标。

这是不现实的。您可能根本没有得到任何修复。你可能不会得到修复,直到10秒钟。例如,我正在测试旨在帮助开发人员以更低的频率(例如,每小时一次)轮询位置更新的服务,并且即使从手机上也可以轻松地花费一分钟来修复坐在窗前。

  

以下是我正在实施的服务的代码段:

这是有缺陷的。对于初学者,getLastKnownLocation()通常会在null / Timer问题之后返回TimerTask

  

我希望有人能提出建议。

我首先要重新设计你的应用程序,以摆脱10秒概念作为一项艰难的要求。

然后,使用requestLocationUpdates()。如果读数太多,请忽略您不想要的读数,不要将它们发送到服务器。当然,请在短时间内运行,并且仅根据积极的用户请求(例如,明确地运行您的应用程序),考虑到保持GPS无线电所用的电池消耗。

requestLocationUpdates()的文档在时间方面肯定令人困惑 - 我最近才意识到最短时间不一定得到尊重。

答案 1 :(得分:1)

我在堆栈跟踪中注意到“无法在没有调用Looper.prepare().......”的线程内创建处理程序的语句,这让我想起了一个交叉线程类型错误或者情况一个对象尚未完成设置其内部状态。

几周前我看了一段视频,主持人做了类似的事情......基于计时器从GPS发送数据,但我现在似乎无法找到它。尝试搜索...这是一个长达一小时的视频,但值得花时间。

答案 2 :(得分:1)

当您在外部线程中调用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();

希望这会对你有所帮助。