1

im already looking for the aswer in this forum but none working, im creating an android apps and im trying to get coordinate update from locationlistener in asyncTask (my asyncTask job only to update the latitute and longitude) while the main thread get the coodinate from the asyncTask via Location Manager, and it works yesterday, today its not working anymore, here's my asyncTask code :

 private class LoopMsg extends AsyncTask<String,Void,Void>{
        protected Void doInBackground(String... urls){

            Looper.prepare();

            LocationListener listen = new LocationListener() {

                @Override
                public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderEnabled(String arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderDisabled(String arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onLocationChanged(Location loc) {
                    // TODO Auto-generated method stub

                    Log.d(TAG,"Latitude :"+String.valueOf(loc.getLatitude()));
                    Log.d(TAG,"Longitude :"+String.valueOf(loc.getLongitude()));
                    Glatitude = loc.getLatitude();
                    Glongitude = loc.getLongitude();
                }
            };          
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen);
            Looper.loop();


            return null;

        }
    }

please help me what went wrong here? and how to fix this? it running good before the next day i got exception at Looper.prepare() it says that only one looper may be created per thread, then i delete Looper.prepare and Looper.loop Part, the error change become

*FATAL EXCEPTION: asyncTask #1
*java.lang.RuntimeException: an error occured while executing do in background

im really don't know why, coz im not update ui thread at my doInBackground method

why i know my app not working : 1.onLocationChanged never called again 2.the app crash if im not using looper.prepare and looper.loop

and I also tried like this :

lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen, Looper.getMainLooper());

and this :

Looper.Mylooper.prepare();
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen, Looper.getMyLooper());

but still no luck,the app still not running

this is the logCat i got after removing the Looper in AsyncTask (and the app always crash)

-Fatal Exception: AsyncTask#2
-java.lang.RuntimeException: An error occured while executing doInBackground()
-at android.os.AsyncTask$3.done(AsyncTask.java:299)
-at java.util.concurrent.FutureTask.finishCompletion(FutureTask.Java:219)
-at java.util.concurrent.FutureTask.run(FutureTask.Java:239)
-at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
-at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
-at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
-at java.lang.Thread.run(Thread.java:838)
-Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not  called Looper.prepare()
-at android.os.Handler.<init>(Handler.java:197)
-at android.os.Handler.<init>(Handler.java:111)
-at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:199)
-at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:199)
-at android.location.LocationManager.wrapListener(LocationManager.java:822)
-at android.location.LocationManager.requestLocationUpdates(LocationManager.java:835)
-at android.location.LocationManager.requestLocationUpdates(LocationManager.java:432)
-at android.location.ZTEPrivacyLocationManager.requestLocationUpdates(ZTEPrivacyLocationManager.java:107)
-at com.login.absen.MyService$LoopMsg.doInBackground(MyService.java:244)
-at com.login.absen.MyService$LoopMsg.doInBackground(MyService.java:1)
-at android.os.AsyncTask$2.call(AsyncTask.java:287)
-at java.util.concurrent.FutureTask.run(FutureTask.java:234)
-... 4 more

UPDATE

i guest i can simplyfy the problem Actually the problem was the onLocationChange method not called at (zte n986 - android 4.2) , im trying this code in another device (journey - android 2.3.3) the behavior was the same, asyncTask also stop running at Looper.loop BUT the onLocationChange method was running, so the location update still running

  • You shouldn't need `Looper` with `AsyncTask`, AFAIK. Post the full exception you get when you remove the `Looper` code. – codeMagic Jan 03 '14 at 04:35
  • Correct. You don't need `Looper` if you're already using `AsynTask`. – ChuongPham Jan 03 '14 at 06:02
  • @codeMagic and @ ChuongPham if i remove the looper the application will crash immeditely when the service start running, why is that? – user3155733 Jan 06 '14 at 09:26
  • Because `AsyncTask` needs to be called from the main `Thread`. You shouldn't need an `AsyncTask` for this. – codeMagic Jan 06 '14 at 14:12
  • i have tried not to using asyncTask,so i made a method protected void updateLoc() {} where this method contain the same code with the asyncTask class, and of course i need to use Looper.prepare and Looper.loop for this, the problem happen at here : lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen); Looper.loop(); -> here's the problem when it reach Looper.loop the app will only running the listener method over and over, and the main thread will never finished running(i put the listener in the middle of the apps), how to solve that problem? – user3155733 Jan 09 '14 at 03:13

4 Answers4

0

First there is no need of AsyncTask for listening for location update. LocationLintener itself run asynchronously so just register for location update and update the ui in

 public void onLocationChanged(Location loc) {
                    // TODO Auto-generated method stub


                }
CoolMonster
  • 2,258
  • 25
  • 50
  • i did,before im using asyncTask im just call a function that have location listener and it give exception java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare, and when i give looper it will give exception "only one looper may be created per thread",thats why im decided to use the asyncTask to avoid that exception, because as a service background this function will be called again and again, im thinking that's the cause of the exception "only one looper may be created per thread" – user3155733 Jan 03 '14 at 05:04
  • I dont think so. there is no need of any other steps for listening to location update. If u want I will prepare some code will make a display toast for every locaiton update. – CoolMonster Jan 03 '14 at 05:11
  • If you worry that the `LocationListener` class is consuming a bit of battery juice, use `AlarmManager` to schedule your task at specific time. – ChuongPham Jan 03 '14 at 06:01
  • @ CoolMonster at onLocationChanged method im already using log, so if the onLocationChanged method running the log will be written in the logCat, and no Toast needed and it will write latitude and longitude every 1 minute which the value will be taken by location manager and sent to server,but because the onLocationChanged method never called it never update the latitude and longitude, if im in debug mode, the debug will stop at Looper.loop() – user3155733 Jan 03 '14 at 06:16
  • are u using the device for testing this code or else emulator. – CoolMonster Jan 03 '14 at 06:18
  • im using device zte N986, oh and more info when im using asyncTask im also stuck at Looper.loop, perhaps its like looping forever there?but the main Service/main thread running well only it not get location update from the listener – user3155733 Jan 03 '14 at 06:36
0

Use Service and you can use Location Listner there,no ne

Amit
  • 391
  • 3
  • 15
  • this whole app was running in a background as a backgroundService – user3155733 Jan 03 '14 at 06:17
  • There is difference [http://stackoverflow.com/questions/3264383/difference-between-service-async-task-thread](check here) – Amit Jan 03 '14 at 06:29
  • ok im using service for the main Part, its running over and over getting the mac address,ssid, etc, and also getting the location(latitude and longitude) , this location need update i make it update every 1 minute (locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listener);) so i make asyncTask to running the listener coz if im running listener in the same place it will got an exception – user3155733 Jan 03 '14 at 06:43
0
public class LocateDeviceService extends Service {

private static final String TAG = "";

double lat = 0;
    double lng = 0;



@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    customHandler.postDelayed(updateTimerThread, 0);
    return super.onStartCommand(intent, flags, startId);
}

private Handler customHandler = new Handler();

private Runnable updateTimerThread = new Runnable() {

    public void run() {
        try {
            //send location

    LocationManager locman = (LocationManager) context
            .getSystemService(Context.LOCATION_SERVICE);

    Criteria criteria = new Criteria();
    String provider = locman.getBestProvider(criteria, false);
    Location location = locman.getLastKnownLocation(provider);

    if (location != null) {
        lat = location.getLatitude();
        lng = location.getLongitude();

    }

            customHandler.postDelayed(this,60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

};



public void sendLocationToServer(Double lat,Double lng )
        throws InterruptedException {
    //do ur job here

}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    if (null != customHandler && null != updateTimerThread) {
        customHandler.removeCallbacks(updateTimerThread);
    }
}
}
Amit
  • 391
  • 3
  • 15
  • when you will start LocateDeviceService , it will keep updating you with location in every 1 minute and once you stop service it will stop updating, try it, for me it works – Amit Jan 03 '14 at 07:25
  • Amit, can you explain to me how this update the location? while it doesn't have locationListener? right now im also get the location, only the location not updated because the listener not running – user3155733 Jan 03 '14 at 09:25
0

There is no need for AsyncTask to get location changes. Locations can be sent to your registered class running on main thread. If you want to upload the location to a server, then use AsynTask only for that portion.

Here are steps:
1. Implement "LocationListener" on your class that extends Service.
2. Then you need to implement the unimplemented methods in the LocationListener. Location is passed to you on is:


    @Override
    public void onLocationChanged(Location location) {
        //Use AsyncTask only to upload the location information
        uploadLocationToServerThroughAsyncTask(location);   
    }


3. Now, register with LocationManager to send the locations to your class when it changes as below:


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

    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_COARSE);
    String provider = lm.getBestProvider(criteria, true);
    if (provider == null || provider.trim().isEmpty()) {
        // No provider hence return.
        return;
        }
    // If there are any available provider, then register for location updates.
    lm.requestLocationUpdates(locProvider, 1000, 200, this); // 1 sec and 200 meter updates 



4. Unregister from location manager at the appropriate time as below:


    try {
        lm.removeUpdates(this);
        } catch (Exception e) {
        e.printStackTrace();
    } 

user2995358
  • 977
  • 11
  • 27