Greetings,
I am trying to implement a timer that sends GPS coordinates to my server every 10 seconds.
Here is the code snippet from the Service I'm implementing:
@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;
}
Now the problem is that anything inside run() causes my app to force closed.
Here is the LogCat dump:
12-28 18:44:18.284: ERROR/AndroidRuntime(6537): FATAL EXCEPTION: Timer-0 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): at android.os.Handler.(Handler.java:121) 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): at prestocab.driver.Background$2.(Background.java:83) 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): at prestocab.driver.Background.sendCoords(Background.java:83) 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): at prestocab.driver.Background$3.run(Background.java:114) 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): at java.util.Timer$TimerImpl.run(Timer.java:289) 12-28 18:44:18.554: ERROR/WindowManager(1310): return in removeWindowLocked
Can anyone suggest a fix for this?
I've tried using the locationManager onLocationChanged() function, but I can't set the interval to 10 seconds. Apparently the time specified is only a guidance and the OS determines what's best. Even when I set the interval to 100 seconds, it gives me the location every second or so. Hence the reason for me using a timer.
I hope someo开发者_Python百科ne can suggest something.
Thanks in advance,
I am trying to implement a timer that sends GPS coordinates to my server every 10 seconds.
That is unrealistic. You may not get any fixes at all. You may not get fixes until well past 10 seconds. For example, I am in the process of testing a service designed to help developers poll for location updates on a much lower frequency (e.g., once an hour), and it can easily take over a minute to get a fix, even from a phone sitting at a window.
Here is the code snippet from the Service I'm implementing:
That is flawed. getLastKnownLocation()
will generally return null
, for starters, beyond your Timer
/TimerTask
issue.
I hope someone can suggest something.
I would start by redesigning your app to get rid of the 10 second concept as a hard requirement.
Then, use requestLocationUpdates()
. If you get too many readings, ignore ones you do not want and don't send them to the server. And, of course, please only run this for a short period of time and only based on a positive user request (e.g., running your app explictly), given the battery consumption involved in keeping the GPS radio on.
The documentation for requestLocationUpdates()
is definitely confusing on the timing front -- I only recently realized that the minimum time is not necessarily honored.
I noticed in the stack trace the statement about "Can't create handler inside thread that has not called Looper.prepare() ......." which reminds me of a cross thread type error or a situation whereby an object hasn't finished setting up its interal state yet.
I saw a video a couple weeks back whereby the presenter was doing something similar ... sending in data from the GPS based on a Timer but I can't seem to find it right now. Try doing a search on that ... it was about an hour long video, but worth the time.
As you are calling the Main UI element with in external thread so the MainUI thread will make the exception use this while invoking the Toast or any other UI component :-
Make the Handler like this :-
Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
// display UI , Update UI
/* To do your UI updation here */
}
};
Now make your thread like this :-
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();
Hope this will help you.
精彩评论