0

I am getting the "can't create handler inside thread that not called looper.prepare" error when trying to call,

locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);

However if I don't call it inside a thread( the run() ) it works fine..What should I do?

Edit: MyAlarmService.java

private Handler handler = new Handler(){

    @Override
    public void handleMessage(Message msg) {
        // TODO Auto-generated method stub
        super.handleMessage(msg);
        System.out.println("Handle MSGGGGGGGGGG");

    }

};

@Override
public void onStart(Intent intent, int startId) {
 // TODO Auto-generated method stub
 super.onStart(intent, startId);

 WorkerThreads WT1 = new WorkerThreads("Thread1");
 WorkerThreads WT2 = new WorkerThreads("Thread2");
    WT1.start();
    WT2.start();
}

class WorkerThreads extends Thread{

    public WorkerThreads(String string) {
        // TODO Auto-generated constructor stub
        super(string);
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();

        if(getName().equals("Thread1")){
            System.out.println("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
            GetAlarmCoordinates gcc = new GetAlarmCoordinates();
            gcc.init(getApplicationContext(),handler);
            /*try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/

              System.out.println(MyAlarmService.currentLatLon[0] + "   " + MyAlarmService.currentLatLon[1] );

        }else if(getName().equals("Thread2")){

        }


    }


}

GetAlarmCoordinates.java

public void init(Context cont, Handler handler){

    mHandler = handler;
    locManager = (LocationManager) cont.getSystemService(Context.LOCATION_SERVICE);
    onClick();
}

 public void onClick() {
//  progress.setVisibility(View.VISIBLE);
    // exceptions will be thrown if provider is not permitted.
    System.out.println("GetCurrentLocation");
    try {
        gps_enabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {
    }
    try {
        network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex) {
    }

    System.out.println("gps_enabled : "+gps_enabled+ " network_enabled : "+network_enabled);


    if (gps_enabled) {
        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
    }

    if (network_enabled) {
        locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
    }
}

     class MyLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location location) {
        if (location != null) {
            // This needs to stop getting the location data and save the battery power.
            locManager.removeUpdates(locListener); 
            //locationManager.requestLocationUpdates(GPS_PROVIDER, intervall, distance, listener);


            latitude =  location.getLatitude();
            londitude = location.getLongitude();

            MyAlarmService.currentLatLon[0] = latitude;
            MyAlarmService.currentLatLon[1] = londitude;


            System.out.println("Alarm Coodinates lat : "+latitude+"  lon : "+londitude);
            mHandler.sendEmptyMessage(0);
        //notify();



        } 
    }
user340
  • 375
  • 12
  • 28
  • Egor's answer is correct. And the reason is that you cannot perform such operation in a non UI thread. – Carnal Aug 20 '12 at 11:37
  • I have a BG service which get called every 5 mins, when the alarm gets called I need to do two things. Check noise from mic and check location. So I created two threads and called the functions. Then only this error is happening..how to do it in this particular situation? – user340 Aug 20 '12 at 11:45
  • The only thing you can do is to call it in the main thread, not create one yourself. But if you have to create a thread, then you can either run it in the UI Thread with the method that Egor gave, or using a Handler and passing the result with sendMessage(); method. – Carnal Aug 20 '12 at 11:48
  • can you show some example in using the Handler within the Thread. I have the location checking in a separate class. From the thread I call this class.. – user340 Aug 20 '12 at 11:53
  • http://thedevelopersinfo.wordpress.com/2009/10/19/using-handler-for-long-time-operations-in-android/ <-- and look at the first 2 example, one for sending message and another for receiving.. actually in receiving you perform your operation! don't need to anything with message, just send whatever you want. – Carnal Aug 20 '12 at 11:56
  • Thanks I'll try it. Here is my location checking class http://stackoverflow.com/questions/12031162/notify-when-onlocationchanged-is-called you think this can be done with threads/ handler? – user340 Aug 20 '12 at 11:59
  • Yeah you could try, but I would implement the location listener in the activity itself or in the BG service itself. But try it out =) – Carnal Aug 20 '12 at 12:05
  • Do you know how to get a notification when onLocationChanged() is called? – user340 Aug 20 '12 at 12:11
  • That's nothing I would recommend, because it can be called multiple times, in your case it is called every second :P but yes, you can of course do that. Take a look here -> http://www.vogella.com/articles/AndroidNotifications/article.html – Carnal Aug 20 '12 at 12:13
  • Err..well thats not what I meant. I only get the correct values inside the onLocationChanged(). but this method returns a void. I want to get the values collected in this method in to my service.. – user340 Aug 20 '12 at 12:21
  • The Handler still gives the err :( – user340 Aug 20 '12 at 12:23
  • just create the variable yourself, and then a method that returns them.. you will need to update those value in onLocationChanged – Carnal Aug 20 '12 at 12:29
  • error? that strange? have u followed the guide? – Carnal Aug 20 '12 at 12:29
  • yes..I created the handler with the handleMesg(), passed the handler object to the location class and in the onLocationChanged() retuned an empty msg still gets the err.. – user340 Aug 20 '12 at 12:38
  • Strange, is hard for me to know what you are doing when I'm not next to you. – Carnal Aug 20 '12 at 12:47
  • yeah sure you can do that and I'll do my best. – Carnal Aug 20 '12 at 12:52
  • The handler must be in the same class as where you call it, you can't have it in one class and pass that into another – Carnal Aug 21 '12 at 10:52
  • did u get the log "handle MSGGGG" ? – Carnal Aug 21 '12 at 10:52

3 Answers3

1

You can use the Activity.runOnUiThread() method to avoid this exception, here's the snippet:

activity.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                    locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
            }
        });

Hope this helps.

Egor
  • 39,695
  • 10
  • 113
  • 130
1

I'm guessing locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener); has to run in the UI thread.

Solutions:

Just run it in the UI thread without creating a new thread.

If you are running

`locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);`

from another class, then you can run the code via an activity instance:

activity.runOnUiThread(new Runnable() {

@Override
public void run() {
// Your code
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
}
});

I hope this helps.

Luke Taylor
  • 9,481
  • 13
  • 41
  • 73
0

You can use getMainLooper in Context , just send context to your class as a parameter and user lopper

locationManager.requestLocationUpdates(getProviderName(), time, meter, locationUpdateListener,context.getMainLooper());
Vahid Rajabi
  • 191
  • 3
  • 3