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);
}
});
Related
Really weird bug - I can get location updates working like this:
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, new LocationListener() {
//On location changed code here
}
But not like this:
Global variables:
LocationManager lManager;
LocationListener lListener;
In my code:
lManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lListener = new LocationListener() {
//On location changed code goes here...
}
lManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, lListener);
Why are lListener/lManager global? One, they're used in the code elsewhere for other location polling. Two, I need them global so I can properly quit the locationservice on pause.
Anyone have any ideas? I'm stumped!
EDIT: One more thing: There are no errors, but the app right now just gets the location once, rather than polling every 2 seconds!
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()
);
I have a class implementing the LocationListener
public class GetLocation implements LocationListener {
#Override
public void onLocationChanged(Location location) {
Log.i("GetLocation", "Location changed: " + location.getLatitude()
+ ", " + location.getLongitude());
}
In my activity,
final LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
final GetLocation locationListener = new GetLocation();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, locationListener);
..... //Check whether the location is changed
locationManager.removeUpdates(locationListener);
updateGPStoServer();
After onLocationChanged() is called once, I want to do a upload task and cancel the listener, so I am asking how can I wait for the onLocationChanged() then do my tasks?
After onLocationChanged() is called once, I want to do a upload task
and cancel the listener, so I am asking how can I wait for the
onLocationChanged() then do my tasks?
I think you need to move the call to updateGPStoServer() into your Listener.onLocationChanged method; that would implement the "waiting" that you're looking for. (On a separate note: updateGPStoServer() should be implemented to create a background Thread to do the updates to the server. But you knew that, right? :-)
Also, it sounds like you really want to be calling LocationManager.requestSingleUpdate instead of LocationManager.requestLocationUpdates. That would remove the need to call locationManager.removeUpdates(locationListener).
I have been working for 2 days looking for this bug. I have searched stackoverflow and Android documentation with no luck.
My onLocationChanged code has a counter in it that counts how many times it has been called and if I back arrow out of the activity screen on the phone and return, the counter will go up by 2 for each update. If I back arrowing out and update the GPS, the counter records that onLocationChanged is still getting called even though the screen is in the background and onPause has been called. If I go in and out of the activity with the backarrow, I can get more than two updates per GPS input send depending on how many times the activity screen is entered.
All the GPS code works but these multiple instances can't be good and they mess up other things I am trying to do, like distance traveled between two updates.
Here is what I think is the relevant parts of my code. Obviously I left out the main part but the point is that after returning to this screen after back-arrowing out then a single send of a GPS data point increments the n variable by more than one depending on how many times I have returned to the screen.
I must be doing something obvious but I can't find it.
public class Data extends Activity {
protected LocationListener ll;
protected LocationManager lm;
static int n = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.data);
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new mylocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);
}
class mylocationlistener implements LocationListener{
#Override
public void onLocationChanged(Location location) {
if (location != null){
n = n + 1;
textData.setText("\n" + n);
}
}
and
#Override
protected void onPause() {
if(lm != null) {
lm.removeUpdates(ll);
}
ll = null;
lm = null;
super.onPause();
}
The only clue I have is that if I take the lm.removeUpdates(ll) out of the if(lm != null) then the code crashes which makes me think that lm must be null and that lm.removeUpdates(ll) must not be correct but it matches the all the examples I could find as well as the Android documentation as far as I can tell.
Please help.
LocationListener ll = new mylocationlistener();
This LocationListener is local to your method onCreate().So is your LocationManager lm.So when you are removing updates its not working with the manager and listener that you declared as the class variable.
Just write as
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
ll = new mylocationlistener(); in your onCreate().
How do I unsubscribe a LocationListener from recieving updates from the LocationManager?
Here is how I'm setting it up
mLocationManager = (LocationManager)this.getSystemService(LOCATION_SERVICE);
mListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.i("LocationListener", "Logging Change");
}
}
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
5000, 1, mListener);
After I have exited the the view that created the LocationListener I am still getting log messages in the LogCat window.
I understand that this is because I am orphaning the listener but I cannot see any destroy method on the LocationListener nor can I see any "remove listener" style methods on the LocationManager object.
Call removeUpdates on LocationManager, passing your location listener.
mLocationManager.removeUpdates(mListener);
I think removeUpdates should help.
mLocationManager.removeUpdates(mListener)