I want to get the speed out of the LocationManager in my app. I have a Criteria with setSpeedRequired(true) attribute. I am doing location.getSPeed(), but it gives me 0 all the time. Below is the code for the GPS which I am running as a Service.
public class Tracking extends Service implements LocationListener {
protected LocationManager locationManager;
Location location;
double latitude;
double longitude;
float velocity;
String provider;
private static final long minDist = 0;
private static final long minTime = 0;
LocationDatabaseHandler ldb;
#Override
public void onCreate() {
ldb = new LocationDatabaseHandler(this);
getLocation();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent,flags,startId);
//because we do not want to stop the service unless we explicitly say so.
return START_STICKY;
}
public Location getLocation() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setSpeedRequired(true);
provider = locationManager.getBestProvider(criteria, false);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDist,
this);
location = locationManager.getLastKnownLocation(provider);
if(location != null) {
onLocationChanged(location);
}
return location;
}
#Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
batteryP = getBatteryPerc();
velocity = location.getSpeed();
insertIntoDb(latitude, longitude, velocity, "onchanged");
}
public void insertIntoDb(double latitude, double longitude, float velocity, String where) {
Date date = new Date();
String dateStr = date.toString();
ldb.addLocation(new Locations(latitude, longitude, dateStr, velocity));
}
}
When I see my database, the velocity is always 0.0. Is there something I am missing?
locationManager.requestLocationUpdates(provider, minTime, minDist, this);
Related
I'm looking a way to get distance travelled by the user. On purpose I try services like this
public class GPSService extends Service {
private LocationListener listener;
private LocationManager locationManager;
private List<Location> locationList = new ArrayList<>();
private float distancetracking = 0;
private int j = 0;
private float finaldist = 0;
String provider;
public IBinder onBind(Intent intent){
return null;
}
#SuppressLint("MissingPermission")
#Override
public void onCreate() {
super.onCreate();
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
locationList.add(location);
Intent i = new Intent("location_update");
while (j < locationList.size() - 1) {
Location loc1 = locationList.get(j);
Location loc2 = locationList.get(j + 1);
distancetracking += loc1.distanceTo(loc2);
j++;
}
Log.d("service", String.valueOf(distancetracking));
finaldist = distancetracking/1000;
i.putExtra("coordinates", finaldist);
sendBroadcast(i);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
locationManager.requestLocationUpdates(provider,0,0,listener);
}
#Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null){
locationManager.removeUpdates(listener);
}
locationList.clear();
}
}
But when my app goes in background the location didn't receive any location...I was aware of some limitation but actually I didn't understand what to do. I'have to do that on purpose to calculta CO2 from the distance travelled
I'm trying to program an application which is using the current location from the user and calculating the distance and writes it into my listview.
The location doesn't have to be very accurate and i only want to fetch a new location when the list is refreshed or on app start, not continously.
My problem is that the locationlistener with gps takes too long to find a location and i have to update my list a lot before it is showing the right distance.
I was thinking about implementing a background task which gets the location and updates the list automatically when it found the position. Would that be a solution?
Is there any option to get a location faster, even if it is not as accurate as gps?
what i have so far on my location listener:
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lng = location.getLongitude();
myLoc.setLatitude(lat);
myLoc.setLongitude(lng);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
in this method i'm calling the locationmanager and listener and creating the listview with the distance
public void getList(){
locationManager = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
//... creating the list with distance and so on
}
i hope you can give me some hints how i can implement this that i will work as described above or tell me what i should use instead.
thanks :)
1). You can use LocationManager.NETWORK_PROVIDER
This provider determines location based on availability of cell tower and WiFi access points. Results are retrieved by means of a network lookup. Requires either of the permissions android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION.
eg:- locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 50, locationListener);
2). If you want to use background task then use this service
public class LocationFinder extends Service {
public static double lat, lng;
LocationManager locationManager;
public void onDestroy() {
super.onDestroy();
if (locationManager != null && locationListener != null) {
locationManager.removeUpdates(locationListener);
}
}
#Override
public void onCreate() {
Log.v("location", "===>location ed onCreate " + lat);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.v("location", "===>location ed onStartCommand " + lat + "==>" + lng);
new Handler().post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
getLocation();
}
});
return START_STICKY;
}
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
private void getLocation() {
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager) getSystemService(context);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
if (locationManager != null) {
String provider = locationManager.getBestProvider(criteria, true);
if (provider != null) {
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
locationManager.requestLocationUpdates(provider, 500, 50, locationListener);
} else {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 50, locationListener);
} else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 50, locationListener);
} else if (locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 500, 50, locationListener);
}
}
}
}
private void updateWithNewLocation(Location location) {
if (location != null) {
Log.v("location", "===>location ed " + lat);
lat = location.getLatitude();
lng = location.getLongitude();
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
I get location of android phone as:
android.location.Location locationA;
LocationManager locationManager;
Criteria cri = new Criteria();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String tower = locationManager.getBestProvider(cri, false);
locationA = locationManager.getLastKnownLocation(tower);
if (locationA != null) {
// lat = (double) (locationA.getLatitude() * 1E6);
// longi = (double) (locationA.getLongitude() * 1E6);
double lat = locationA.getLatitude();
double longi = locationA.getLongitude();
TextView txt = (TextView) findViewById(R.id.textView1);
String td = String.valueOf(lat) + "," + String.valueOf(longi);
txt.setText(td);
}
Why current location of android phone don't change when i change location and get again current location?
check the time of your location using locationA.getTime(). if it was not up to date wait for a new location and then stop.
private static Location currentLocation;
private static Location prevLocation;
public void yourMethod()
{
locationManager.requestLocationUpdates(provider, MIN_TIME_REQUEST,
MIN_DISTANCE, locationListener);
}
private static LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onLocationChanged(Location location) {
gotLocation(location);
}
};
private static void gotLocation(Location location) {
prevLocation = currentLocation == null ?
null : new Location(currentLocation);
currentLocation = location;
if (isLocationNew()) {
// do something
locationManager.removeUpdates(locationListener);
}
}
private static boolean isLocationNew() {
if (currentLocation == null) {
return false;
} else if (prevLocation == null) {
return false;
} else if (currentLocation.getTime() == prevLocation.getTime()) {
return false;
} else {
return true;
}
}
I want to keep my application running in background
I have an application that sends the user's location to our server
I have the following code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(criteria, true);
updateWithNewLocation(null);
locationManager.requestLocationUpdates(provider, (10*60*1000), 10,
locationListener);
}
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider){
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider){ }
public void onStatusChanged(String provider, int status,
Bundle extras){ }
};
public void updateWithNewLocation(Location location) {
if (location != null) {
Dbhelper helper = new Dbhelper(this);
final SQLiteDatabase db = helper.getWritableDatabase();
long time = System.currentTimeMillis();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
final String curTime = df.format(time);
final double lat = location.getLatitude();
final double lng = location.getLongitude();
final double alt = location.getAltitude();
System.out.println(lat);
System.out.println(lng);
System.out.println(alt);
db.execSQL("INSERT INTO location (longitude,latitude,altitude,tgl_buat) VALUES " +
"('"+lng+"','"+lat+"','"+alt+"','"+curTime+"')");
db.close();
/*Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run(){
db.execSQL("INSERT INTO location (longitude,latitude,altitude,tgl_buat) VALUES " +
"('121.2149012','-6.217837','0.0','2012-05-07 10:20:01')");
db.close();
}
}, 10*60*1000, 10*60*1000);*/
}
}
I want my applicatioin to be running in the background. I want it to launch automatically when the phone is turned on
A very simple answer for your problem is to use Service. It will allow you to perform variety of tasks while being in background and is your best bet for sending your location to server silently.
Read this answer for help.
You can keep your application running in the background using Service
I hope this link will help you
Please read the documentation for further details
Run your background logic in a Service, and if you want to give a good UX experience (and to also have an higher priority) post a Notification to status-bar (using NotificationManager).
GrabLocationDetails.java
Use this code as your GrabLocationDetails.java
public class GrabLocationDetails extends Service implements LocationListener {
double lat,lng;
private LocationManager locationManager;
private String provider;
boolean isGps;
private ArrayList<String> mList;
Context GLDContext;
public GrabLocationDetails(Context cont){
this.GLDContext=cont;
}
public GrabLocationDetails(){}
#Override
public void onCreate() {
super.onCreate();
mList = new ArrayList<String>();
isGps = false;
lat=0.0;
lng=0.0;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//super.onStart(intent, startId);
try {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!enabled) {
isGps = false;
ListAddItem(isGps);
SendBroadcast();
} else {
isGps = true;
Location location = locationManager.getLastKnownLocation(provider);
lat=(location.getLatitude());
lng=(location.getLongitude());
ListAddItem(true);
SendBroadcast();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
} catch (Exception e) {
ListAddItem(isGps);
SendBroadcast();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
//locationManager.removeUpdates(this);
}
public void SendBroadcast(){
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(CommandExecutionModule.LocationDetails);
broadcastIntent.putExtra("Data", mList);
sendBroadcast(broadcastIntent);
}
public void ListAddItem(boolean GPS) {
//if(!GPS)
//mList.add("0");
//else
//mList.add("1");
mList.add(Double.toString(lat));
mList.add(Double.toString(lng));
}
/**************************************************************************************************************/
#Override
public void onLocationChanged(Location location){
locationManager.requestLocationUpdates(provider, 400, 1, this);
mList.clear();
lat = (location.getLatitude());
lng = (location.getLongitude());
ListAddItem(isGps);
SendBroadcast();
locationManager.removeUpdates(this);
stopSelf();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
#Override
public void onProviderEnabled(String provider){
isGps=true;
}
#Override
public void onProviderDisabled(String provider){
isGps=false;
lat=0.0;
lng=0.0;
mList.clear();
ListAddItem(isGps);
//SendBroadcast();
}
You should use a Service and a BroadcastReceiver
I'm building a service that will let me know if the location hasn't change in a period of time for a certain amount of metres.
Then thing is I have the event onLocationChanged on my Listener.. but I don't know how to do the opposite.. that is, send a broadcast if the location is within the distance I provided after some minutes.
This is the code I have so far
LocationService
public class LocationService extends Service {
public static final String LOC_INTENT = "com.xxx.intent.action.LOCATION";
private Thread triggerService;
protected LocationManager locationManager;
protected MyLocationListener MyLocationListener;
protected Criteria criteria;
public static final int MIN_TIME = 300000; // 5 Minutes
public static final long MIN_DISTANCE_MOTOR = 50; // 50 Metres
private SharedPreferences settings;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
settings = getSharedPreferences(getString(R.string.settings_prefsName), 0);
addLocationListener();
return START_STICKY;
}
private void addLocationListener()
{
triggerService = new Thread(new Runnable(){
public void run(){
try{
Looper.prepare();//Initialise the current thread as a looper.
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
final String PROVIDER = locationManager.getBestProvider(criteria, true);
updateLocation(getLastBestLocation(MIN_TIME, MIN_DISTANCE_MOTOR));
MyLocationListener = new MyLocationListener();
locationManager.requestLocationUpdates(PROVIDER, MIN_TIME, MIN_DISTANCE_MOTOR, MyLocationListener);
Log.d("LOC_SERVICE", "Service RUNNING! ("+PROVIDER+")");
Looper.loop();
}catch(Exception ex){
ex.printStackTrace();
}
}
}, "LocationThread");
triggerService.start();
}
public Location getLastBestLocation(int minDistance, long minTime) {
Location bestResult = null;
float bestAccuracy = Float.MAX_VALUE;
long bestTime = Long.MIN_VALUE;
List<String> matchingProviders = locationManager.getAllProviders();
for (String provider: matchingProviders) {
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
if ((time > minTime && accuracy < bestAccuracy)) {
bestResult = location;
bestAccuracy = accuracy;
bestTime = time;
}
else if (time < minTime && bestAccuracy == Float.MAX_VALUE && time > bestTime) {
bestResult = location;
bestTime = time;
}
}
}
return bestResult;
}
public static void updateLocation(Location location)
{
Context appCtx = MyApplication.getAppContext();
double latitude, longitude;
float speed;
latitude = location.getLatitude();
longitude = location.getLongitude();
speed = location.getSpeed();
Intent filterRes = new Intent();
filterRes.setAction(LOC_INTENT);
filterRes.putExtra("latitude", latitude);
filterRes.putExtra("longitude", longitude);
filterRes.putExtra("speed", speed);
appCtx.sendBroadcast(filterRes);
}
class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location location)
{
if(settings.getBoolean("active", false))
updateLocation(location);
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
Set a timer for however long you want to test this. When it goes off, check if the last location you got in onLocationChanged is older than the timer length.
EDIT
Here is how I would imagine your service looking
Service starting
requestLocationUpdates called with appropriate minimum time and minimum distance that that you will be notified after
Repeating task set where you check if an update was received (check out Timer.scheduleAtFixedRate
Service running
Perform necessary actions when your timer goes off or onLocationChanged is called
Service stopping
Remove location updates with removeUpdates
Stop your timer