I wrote a GPSDataCollectService to collect location data every 10 seconds, but it did not report location in my HTC mobile phone, any wrong? could anyone help me?
package com.android.example;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class GPSDataCollectorService extends Service {
private static final String TAG = GPSDataCollectorService.class
.getSimpleName();
LocationManager locationManager;
LocationListener gpsLocationListener;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private Timer timer;
private TimerTask collectTask = new TimerTask() {
#Override
public void run() {
Log.i(TAG, "Timer task doing work: "
+ Calendar.getInstance().getTimeInMillis());
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 10 * 1000L, 0,
gpsLocationListener);
}
};
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service creating");
timer = new Timer("GPSDataCollectorTimer");
timer.schedule(collectTask, 1000L, 10 * 1000L);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
locationManager.removeUpdates(gpsLocationListener);
timer.cancel();
timer = null;
}
private class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged: " + location.toString());
locationManager.removeUpdates(gpsLocationListener);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + status);
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
}
If your location is changed every 10 sec then only your LocationManager will track the new location. Otherwise it will use the same last known location.
Instead of using a LocationListener, you may want to use a Timer, within the TimerTask, maybe you can do something like this:
LocationManager lm = yourActivityReference.getSystemService(Context.LOCATION_SERVICE);
String provider = lm.getBestProvider(new Criteria(),true);
Location loc = lm.getLastKnownLocation (provider);
I haven't checked it, but if I do I will let know...
Regards.
EDIt: Let me try again with the "classic" approach.
public class GPSDataCollectorService extends Service {
private static final String TAG = GPSDataCollectorService.class
.getSimpleName();
LocationManager locationManager;
LocationListener gpsLocationListener;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10 * 1000L, 0, gpsLocationListener);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
locationManager.removeUpdates(gpsLocationListener);
}
private class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged: " + location.toString());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + status);
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
}
I don't think you need any Timer, since the Location updates will call your listener asynchronally and you can set the timeout. I haven't played much with GPS in Android, but there must be plenty of examples out there.
The location update interval can be controlled using the minTime parameter. The elapsed time between location updates will never be less than minTime, although it can be more depending on the Location Provider implementation
Use
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 20 * 1000, 0, this);
more details refer Location Manager
Related
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
public class LocationService extends Service {
private LocationDatabaseHelper mLocationDatabaseHelper;
private LocationModel mLocationModel;
private Date mDate;
private Handler mHandler = new Handler();
private Timer mTimer = null;
private int mCount = 0;
public static final long NOTIFY_INTERVAL = 30 * 1000;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// cancel if already existed
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
mLocationModel = LocationModel.getInstance();
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
#Override
public void onDestroy() {
mTimer.cancel();
}
private class TimeDisplayTimerTask extends TimerTask implements LocationListener {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
//I send message to draw map here
sendMessage();
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
TimeDisplayTimerTask.this);
}
});
}
#Override
public void onLocationChanged(Location location) {
// I get location and do work here
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
private void sendMessage() {
Intent intent = new Intent("my-event");
intent.putExtra("message", "data");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
What I want is to get user location after every 30 seconds but this code does not work as I expected. It gets location very fast (I think every second).
I tried to get location this way because it can get my current location immediately after I start my app.I have tried getLastKnowLocation before, but it give me the last known location which is very far from where I am.
Please show me how fix this.Thank you!
in requestLocationUpdates method second parameter is minimum time interval between location updates, in milliseconds, So you just need to do this:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 0, TimeDisplayTimerTask.this);
According to Android Developer Reference Documentation
http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener)
public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)
When registering for location updates the LocationManager is invoking LocationListener onLocationChanged(Location) method with latest Location object.
And the second parameter of requestLocationUpdates method is
minTime The minimum time interval between location updates, in milliseconds
This does not mean that you will get location updates every 30 seconds constantly, because if the location cannot be obtained you will not get updates also, if the location is not being changed you will again not get any updates.
Anyway, if you would like to get location updates every 30 seconds constantly, you can keep latest location and send it using your scheduler, while updating it when the onLocationChanged method is called.
try using
TimerTask scanTask;
final Handler handler = new Handler();
mTimer = new Timer();
public void sendSMS(){
scanTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
//your method here which you want to call every 30 sec
}
});
}};
mTimer.schedule(scanTask, 30000, 30000);
}
This app will beep whenever the user's location changes. The problem is, the app will continue monitoring the user's location even after they have left the app and it is in the background.
How do I stop the location listener, once the app goes into the background?
I think I have to add something to the OnPause(), but I can't make it work.
package com.example.locationbeeper;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity implements LocationListener {
LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set up location manager
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(bestProvider);
if (location != null) {
onLocationChanged(location);
}
locationManager.requestLocationUpdates(bestProvider, 200, 5, this); // time in miliseconds, distance in meters (Distance drains battry life) originally set to 20000 and 0
}
#Override
public void onLocationChanged(Location location) {
// beep when location changed
final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
tg.startTone(ToneGenerator.TONE_PROP_BEEP);
}
#Override
public void onSaveInstanceState(Bundle outState) {
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onPause(){
super.onPause();
locationManager = null;
}
}
Based on your requirement, you can add below lines either in onPause() or onStop() callback method of your activity.
if(locationManager !=null)
locationManager.removeUpdates(this);
Use LocationManager.removeUpdates to stop receiving updates from LocationManager when Activity is stop:
#Override
public void onStop(){
super.onStop();
if(locationManager !=null)
locationManager.removeUpdates(this);
}
I'm pretty new to android, and this is my first post here, so please be kind! :-)
I'm trying to create a service which runs in the background and does a location update every x minutes. To run it every x minutes I'm using the AlarmManager, as described here: Alarm Manager Example
Here's what I've got:
package com.example.service1;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
public class Scheduler extends BroadcastReceiver{
LocationManager locationManager;
LocationListener locationListener;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
//Code which is executed every X seconds/minutes
getLocation(context);
//End of Code
wl.release();
}
public void setScheduler(Context context) {
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Scheduler.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 20, pi);
}
//Method to get the Location
public void getLocation(Context context) {
Log.e("null","getLocation");
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Log.e(null, "location change");
makeUseOfLocation(location);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
};
}
//Method to work with the location Data; Instance of Point is created
public void makeUseOfLocation(Location location) {
Log.e(null,"makeuse");
Log.e(null,location.getLatitude() + "");
}
}
getLocation() is called every 20 seconds, but then it never runs onLocationChanged() (I use the EmulatorControl in Eclipse to change the location).
I had the same problem before when I used the ScheduledExecutorService instead of the AlarmManager.
Can anyone help me?
Looking at your code I never see the call to locationManager.requestLocationUpdates() with your listener as an argument.
This means that your listener is never registered with the location manager, and therefore does not get called.
You probably only want to register one listener, instead of registering a new one every time.
Try this..
protected void updateNotification() {
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new MyLocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, normallocationwait, 0.250f, locationListener);
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
private class MyLocationlistener implements LocationListener {
public void onLocationChanged(Location location){
if(location!=null){
if(location.hasAccuracy()){
dumpLocation(location);
}else{
dumpLocation(location);
}
}
}
public void onProviderDisabled(String provider){
Log.v("Loc Update","\nProvider disabled: " + provider);
}
public void onProviderEnabled(String provider){
Log.v("Loc Update","\nProvider enabled: " + provider);
}
public void onStatusChanged(String provider, int status, Bundle extras){
Log.v("Loc Update","\nProvider status changed: " + provider + ", status="
+ status + ", extras=" + extras);
}
Here is the code.
How can I be sure, that location is returned alwasys instead of null.
package com.test.location;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
public class NotifyOnBoot extends Service {
Location location;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
updateNotification();
Thread th = new Thread(null, task, "myService");
th.start();
}
private Runnable task = new Runnable() {
public void run() {
if(location == null)
{
Log.d("location","No location");
}
else
Log.d("location",location.toString());
NotifyOnBoot.this.stopSelf();
}
};
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand (Intent intent, int flags, int startId){
return START_STICKY;
}
protected void updateNotification()
{
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new MyLocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
private class MyLocationlistener implements LocationListener{
public void onLocationChanged(Location location){}
public void onProviderDisabled(String provider){}
public void onProviderEnabled(String provider){}
public void onStatusChanged(String provider, int status, Bundle extras){}
}
}
I recommend to create a call back interface and use onLocationChanged which notifies that call back on the moment the location initiate for the first time.
LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
// Or use LocationManager.GPS_PROVIDER
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
I have created one service and also added it in manifest. When I use timer to call this service periodically and in timer I have used location manager to get location of user contin. But there is error like that:
05-11 11:57:17.574:
ERROR/AndroidRuntime(3305):
java.lang.RuntimeException: Can't
create handler inside thread that has
not called Looper.prepare()
Tell me where is problem in my code.
code is here
package com.collabera.labs.sai;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class SimpleService extends Service {
Timer mytimer;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show();
mytimer = new Timer();
mytimer.schedule(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
//getdata();
LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
mlocListener);
}
},0,1000);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_LONG).show();
}
public void getdata()
{
}
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
loc.getLatitude();
loc.getLongitude();
String Text = "My current location is: " + "Latitude = "
+ loc.getLatitude() + "Longitude = " + loc.getLongitude();
/*Toast.makeText(getApplicationContext(), Text, Toast.LENGTH_SHORT)
.show();*/
Log.d("TAG", "Starting..");
}
#Override
public void onProviderDisabled(String provider) {
/*Toast.makeText(getApplicationContext(), "Gps Disabled",
Toast.LENGTH_SHORT).show();*/
}
#Override
public void onProviderEnabled(String provider) {
/*Toast.makeText(getApplicationContext(), "Gps Enabled",
Toast.LENGTH_SHORT).show();*/
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}/* End of Class MyLocationListener */
}
Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_LONG).show();
You can't modify UI from the non-UI thread. Services are never executed on the UI thread. Log this instead of making a Toast.