Hi I'm trying to requestLocationUpdates from a Thread other than the UI Thread, I'm getting a RuntimeExeption in the following line:
// request location updates using Cellular
lm.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
0,
0,
locationListener);
Then reading the documentation it says that it Throws:
IllegalArgumentException if provider is null or doesn't exist on this device
IllegalArgumentException if listener is null
RuntimeException if the calling thread has no Looper
SecurityException if no suitable permission is present
So it seems to be that my thread has no Looper, but the problem is that I don't know what they mean by a "Looper". Thanks in advance!
Change your run() code to
#Override
public void run()
{
Looper.prepare();
// The rest of your code
Looper.loop();
}
U can try this :
lm.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
0,
0,
locationListener,
Looper.myLooper()
);
Related
in my app I have a Background server and inside server class I have timer and inside timer I have a locationManager to find location :
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 5000, 10,
locationListener);
but here I got this error :
java.lang.runtimeexception can't create handler inside thread that has not called looper.prepare();
my question here how to use locationManager inside timer ?
Look Background service different with Activity when you use runOnUiThread this is just possible with activity be careful OR if you use thread inside Service class you can do this like this :
inside service class write this :
static Activity ac;
public static void setActivity(Activity a) {
ac = a;
}
and in your activity class do this :
MyService.setActivity(this);
now this thread just like this :
(ac).runOnUiThread(new Runnable() {
#Override
public void run() {});
I strongly recommend it to you do like what I did .
The exception message may seem arcane if you don't know what Looper threads are, but it basically means exactly what it says: you can't create a Handler (or any object that contains a Handler) in a thread that is not a Looper. Timer threads are not Loopers. Many things in Android are intended to be created only on the UI thread, which is a Looper.
Trying to use a LocationListener "inside" a Timer doesn't make much sense, anyway. The LocationListener's methods are called by the system, not by your code. I suggest searching and reading up on event-driven programming.
((Activity) getBaseContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 5000, 10,
locationListener);
}
});
1. Looper.prepare();
2. Handler mHandler = new Handler() {
3. public void handleMessage(Message msg) {}
4. };
5. mHandler.post(gpsLocationListenerThread);
6. Looper.loop();
7.
I'm calling a Thread class from AsyncTask. When i call it using code from 1-6, it creates the Thread and runs it. But AsyncTask get stucked there. I need to run this other Thread without blocking my AsyncTask. How to make it happen?
public GPSLocationListenerThread(Context context){
this.context = context;
mlocManager = (LocationManager)context.getSystemService(context.LOCATION_SERVICE);
mlocListener = new GPSLocationListener();
}
public void setHandler(Handler _h){
this.mHandler = _h;
}
public void run(){
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 100, mlocListener); // in 1000 mseconds or in 100m change
mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 100, mlocListener); // in 1000 mseconds or in 100m change
//mHandler.getLooper().quit();
while (DataHolder.getDataHolderObject().isTripStarted()){
try {
this.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mlocManager.removeUpdates(mlocListener);
}
Well you need to call Looper.quit(); anyway or it will never quit. Where you need to call it i have no idea unless you post a bit more code :)
Contrary to the documentation, it's not always needed to quit a looper.
And if you insist - you must call it on the same thread of the looper.
See my elaborate answer here.
I have a method which registers a listener and requests location updates. I would like to the location coordinates in the current method itself, not in the onLocationChanged method.
My code is:-
myclass {
onCreate {
location_Manager = (LocationManager) getSystemService (Context.LOCATION_SERVICE);
locLstnr = new myLocationlistener();
locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, Loc_listener.MINIMUM_TIME_BETWEEN_UPDATES, Loc_listener.MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, locLstnr);
}
class myLocationListener () {
onLocationChanged() { ... }
onProviderDisabled() { ... }
onProviderEnabled() { ... }
}
}
I know i can get getLastKnownLocation() , but incase it is not available, isn't it possible to get the location at all? This and this are a similar questions, but doesn't help me. I don't have problems with using onLocationChanged method, but i need to have the location in the onCreate method. Is that possible? One way might be to store the location onto a variable in the myLocationListener and access it, but is there an alternative or a better solution?
I think if getLastKnownLocation() gives null then you have to wait for call back....
just can do can make request for update
locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
http://devdiscoveries.wordpress.com/2010/02/04/android-use-location-services/
from link
getLastKnownLocation() is faster after a connection has been established with the GPS satellite. For the first time, it will return null, or no value till no connection is established. You can add a GpsListener to know when the location is obtained. Search about "how to get a gps fix" and you might get answer to your question
and refer link
I have a thread that attempts to get the user location.
When the location is received "handler.sendMessage(msg)" is called, and it returns true, but handleMessage is never called.
There are no errors or warnings in logcat.
The code:
public class LocationThread extends Thread implements LocationListener {
// ... Other (non-relevant) methods
#Override
public void run() {
super.run();
Looper.prepare();
mainHandler = new Handler(Looper.myLooper()) {
#Override
public void handleMessage(Message msg) {
// This method is never called
}
};
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, this);
Looper.loop();
}
#Override
public void onLocationChanged(Location location) {
// SendMessage is executed and returns true
mainHandler.sendMessage(msg);
if (mainHandler != null) {
mainHandler.getLooper().quit();
}
locationManager.removeUpdates(this);
}
}
Most likely this is happening because you are calling Looper.quit() immediately after posting the message to the Handler. This effectively terminates the message queue operation before the Handler has a chance to process it. Sending a message to the Handler simply posts it to the message queue. The handler will retrieve the message on the next iteration of the Looper. If your goal is to terminate the thread after a location update is received, it would probably be better to call Looper.quit() from inside handleMessage().
Editorial
Furthermore, if the only purpose for standing up this thread is to wait for the location update to come in, it's unnecessary. LocationManager.requestLocationUpdates() is an inherently asynchronous process (your main thread isn't blocked while the location fix is obtained). You can safely have your Activity/Service implement LocationListener directly and receive the location value there.
HTH
Can I use the same locationManager for requesting updates for the gps and network provider, or should I create two locationManagers and separate onLocation changed functions etc. I got really confused about this
You will want to check and see which one is available in the order you want to use them and then use the corresponding one:
if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_UPDATE_MIN_TIME, LOCATION_UPDATE_MIN_DISTANCE, locationListener);
}
else if(mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, LOCATION_UPDATE_MIN_TIME, LOCATION_UPDATE_MIN_DISTANCE, locationListener);
}
You can use the same listener because all the listener's methods take as a parameter a Location object which is source agnostic:
#Override
public void onLocationChanged(Location location) {
// updateLocation();
}