16

I know this sort of question exists but I'm confused here. I'm using this code:

    public class NewWaitAppActivity extends Activity {
    private Handler mHandler;
    @Override
        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mHandler = new Handler();
        lcmgr = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
        Thread LocThread = new Thread(mLocationUpdater);
        Log.d("TAG","About to start worker thread");
        LocThread.start();
}

public void startTimer(View v) {
        if (mStartTime == 0L) {
            mStartTime = System.currentTimeMillis();
            mHandler.removeCallbacks(mUpdateTimeTask);
            mHandler.postDelayed(mUpdateTimeTask, 100);
        }
    }

private Runnable mUpdateTimeTask = new Runnable() {
        public void run() {
            final long start = mStartTime;
            long millis = System.currentTimeMillis() - start;
            int seconds = (int) (millis / 1000);
            int minutes = seconds / 60;
            seconds = seconds % 60;

            TextView timer = (TextView) findViewById(R.id.time_elapsed);

            if (seconds < 10) {
                timer.setText("" + minutes + ":0" + seconds);
            } else {
                timer.setText("" + minutes + ":" + seconds);
            }

            mHandler.postDelayed(this, 1000);
        }
    };
LocationListener locationListener = new LocationListener() {

        public void onLocationChanged(Location location) {
          // Called when a new location is found by the network location provider.
          mStopTimer();
        }
};


private Runnable mLocationUpdater = new Runnable(){
        public void run(){

            Log.d("TAG","Inside worker thread");
            lcmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    }
};
}

I am basically trying to stop the timer of the main thread when a location updates. The application doesn't even start, it gives the error mentioned above during runtime. The error is due to requestLocationUpdates(). It seems like I can't call stopTimer() inside onLocationChanged(). How can I correct this?

sgarg
  • 2,340
  • 5
  • 30
  • 42

3 Answers3

81

No need to even write a complicated solution:

locationManager.requestLocationUpdates(provider, 5000, 0, mylistener, Looper.getMainLooper());

This will work just fine.

Oliver Spryn
  • 16,871
  • 33
  • 101
  • 195
Robby Lebotha
  • 1,211
  • 11
  • 9
6

whats the need of calling "lcmgr.requestLocationUpdates(....)" from the thread you created, when it is itself an asynchronous callback based mechanism?
Just move this code in the onCreate() of your activity and things should work fine.

Also this error comes when you try to create a handler inside a thread which is not intended to loop at all (ie. the threads that dont call Looper.prepare, as your stack trace states also).

More explanation about this error can be found in this site also.
But a good explanation is also given here.
http://www.aviyehuda.com/2010/12/android-multithreading-in-a-ui-environment/

akkilis
  • 1,904
  • 14
  • 21
  • While it's true that using the main thread putting it inside the onCreate() is going to work... It's not useless to call `lcmgr.requestLocationUpdates(....)` from a thread, it depends on what the app is doing. In case the app needs to request location updates from a background service when there's no Activity open... The onCreate() solution won't work... And RobbyLebotha's solution is the way to go – Rafael Muynarsk Feb 16 '21 at 16:44
0

You can't access/generate Event thread specific events, and you don't need to request location updates in a thread, instead you can use service to achieve the same.

jeet
  • 29,001
  • 6
  • 52
  • 53