Colin Gray
Colin Gray

Reputation: 79

Android Fatal Exception Timer-0

Here is the errors I'm getting

11-03 03:03:02.380: W/dalvikvm(1381): threadid=9: thread exiting with uncaught exception (group=0x40015560)
11-03 03:03:02.400: E/AndroidRuntime(1381): FATAL EXCEPTION: Timer-0
11-03 03:03:02.400: E/AndroidRuntime(1381): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.os.Handler.<init>(Handler.java:121)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:173)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:173)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:579)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:446)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at com.colinlgray.MyService$1.run(MyService.java:84)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at java.util.Timer$TimerImpl.run(Timer.java:284)

Here is my service that I am trying to run with a timer inside of it to update GPS location which I was planning on using to send to a webserver

package com.colinlgray;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import java.util.Timer;
import java.util.TimerTask;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import com.google.android.maps.GeoPoint;

import android.content.Context;

public class MyService extends Service{
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();

GeoPoint geopoint;

private LocationManager lm;
private LocationListener locationListener;

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // We want this service to continue running until it is explicitly
    // stopped, so return sticky.
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    doSomethingRepeatedly();
    return START_STICKY;
}

private void doSomethingRepeatedly() {
    timer.scheduleAtFixedRate( new TimerTask() {
        public void run() {
            lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            class MyLocationListener implements LocationListener{

                public void onLocationChanged(Location location) {
                    geopoint = new GeoPoint(
                            (int) (location.getLatitude() * 1E6),
                            (int) (location.getLongitude() * 1E6));
                    double latitude = location.getLatitude();
                    double longitude = location.getLatitude();
                    double altitude = location.getAltitude();
                    double accuracy = location.getAccuracy();
                    Log.d("LONGITUDE", String.valueOf(longitude));
                    Log.d("LATITTUDE", String.valueOf(latitude));

                }

                public void onProviderDisabled(String provider) {
                    // TODO Auto-generated method stub

                }

                public void onProviderEnabled(String provider) {
                    // TODO Auto-generated method stub

                }

                public void onStatusChanged(String provider, int status,
                        Bundle extras) {
                    // TODO Auto-generated method stub

                }
            }

            locationListener= new MyLocationListener();
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListener);
        }
    }, 0, UPDATE_INTERVAL);
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (timer != null){
        timer.cancel();
    }
    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}

}

I would appreciate any help or suggestions at all. Thanks

Upvotes: 0

Views: 5932

Answers (2)

Orlymee
Orlymee

Reputation: 2357

The Async tasks are to be called from withinthe UI thread. Any thread that has not called Looper.prepare() will cause this problem.

I came across the same problem today so posting my work around(s) to see if this is the best solution(s).

First of all in your code do not do this inside run

lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

Instead move this to start of function dosomethingrepeatedly. e.g.

    public void dosomethingrepeatedly()
        {
            final Myclass x = new Myclass();
            ..........
        public void run()
        {
            x.somefunction()
        }
       }

Alternate approach: Findout the currentThread

Thread.currentThread().getClass();

if it is an instance of Timer you can call Looper.prepare(); Set a flag so that Looper.prepare is only called once. e.g.

    boolean looperCalled=false;
    ...
    ...
    ...
    public void dorepeatedly()
    {
        ....
        ....
        public void run()
        {
            if(Thread.currentThread().getName().equals(java.util.Timer$TimerImpl)
            {
                if(looperCalled){//do nothing}
                else {Looper.prepare(); looperCalled=true;}
            }
        }
    }

Upvotes: 1

frayab
frayab

Reputation: 2512

I had the same problem that you. I have solved the issue doing the locationrequestupdates out of the Timer and in the run method of Timer I send latitude and longitude to the web server.

Othe possible solution is don't use a Timer. With

public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)

You can tell the minTime between new updatelocation and in "onLocationChanged(Location location)" you can send the new Location.

Upvotes: 2

Related Questions