Mock location not working on Google map - android

I have used code from this. I have changed it a bit. Below is my code snippet. The problem is Google Map is not showing proper location which i have mocked.
public class MockGpsProviderActivity extends Activity implements LocationListener {
public static final String LOG_TAG = "MockGpsProviderActivity";
private static final String MOCK_GPS_PROVIDER_INDEX = "GpsMockProviderIndex";
private MockGpsProvider mMockGpsProviderTask = null;
private Integer mMockGpsProviderIndex = 0;
/** Called when the activity is first created. */
/*
* (non-Javadoc)
*
* #see android.app.Activity#onCreate(android.os.Bundle)
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** Use saved instance state if necessary. */
if (savedInstanceState instanceof Bundle) {
/** Let's find out where we were. */
mMockGpsProviderIndex = savedInstanceState.getInt(MOCK_GPS_PROVIDER_INDEX, 0);
}
/** Setup GPS. */
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
// // use real GPS provider if enabled on the device
// locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
// }
// else if(!locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) {
// otherwise enable the mock GPS provider
locationManager.addTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER, false, false, false, false, true, true, true, Criteria.POWER_LOW,
Criteria.ACCURACY_FINE);
locationManager.setTestProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER, true);
locationManager.setTestProviderStatus(LocationManager.GPS_PROVIDER, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
// }
if (locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) {
locationManager.requestLocationUpdates(MockGpsProvider.GPS_MOCK_PROVIDER, 0, 0, this);
/** Load mock GPS data from file and create mock GPS provider. */
try {
// create a list of Strings that can dynamically grow
List<String> data = new ArrayList<String>();
/**
* read a CSV file containing WGS84 coordinates from the 'assets' folder (The website http://www.gpsies.com offers downloadable
* tracks. Select a track and download it as a CSV file. Then add it to your assets folder.)
*/
InputStream is = getAssets().open("mock_gps_data.csv");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
// add each line in the file to the list
String line = null;
while ((line = reader.readLine()) != null) {
data.add(line);
}
// convert to a simple array so we can pass it to the AsyncTask
String[] coordinates = new String[data.size()];
data.toArray(coordinates);
// create new AsyncTask and pass the list of GPS coordinates
mMockGpsProviderTask = new MockGpsProvider();
mMockGpsProviderTask.execute(coordinates);
} catch (Exception e) {
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
// stop the mock GPS provider by calling the 'cancel(true)' method
try {
mMockGpsProviderTask.cancel(true);
mMockGpsProviderTask = null;
} catch (Exception e) {
}
// remove it from the location manager
try {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.removeTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER);
} catch (Exception e) {
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// store where we are before closing the app, so we can skip to the location right away when restarting
savedInstanceState.putInt(MOCK_GPS_PROVIDER_INDEX, mMockGpsProviderIndex);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onLocationChanged(Location location) {
// show the received location in the view
TextView view = (TextView) findViewById(R.id.text);
view.setText("index:" + mMockGpsProviderIndex + "\nlongitude:" + location.getLongitude() + "\nlatitude:" + location.getLatitude()
+ "\naltitude:" + location.getAltitude());
}
#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
}
/** Define a mock GPS provider as an asynchronous task of this Activity. */
private class MockGpsProvider extends AsyncTask<String, Integer, Void> {
public static final String LOG_TAG = "GpsMockProvider";
public static final String GPS_MOCK_PROVIDER = LocationManager.GPS_PROVIDER;
/** Keeps track of the currently processed coordinate. */
public Integer index = 0;
#Override
protected Void doInBackground(String... data) {
// process data
for (String str : data) {
// skip data if needed (see the Activity's savedInstanceState functionality)
if (index < mMockGpsProviderIndex) {
index++;
continue;
}
// let UI Thread know which coordinate we are processing
publishProgress(index);
// retrieve data from the current line of text
Double latitude = null;
Double longitude = null;
Double altitude = null;
try {
String[] parts = str.split(",");
latitude = Double.valueOf(parts[0]);
longitude = Double.valueOf(parts[1]);
altitude = Double.valueOf(parts[2]);
} catch (NullPointerException e) {
break;
} // no data available
catch (Exception e) {
continue;
} // empty or invalid line
// translate to actual GPS location
Location location = new Location(GPS_MOCK_PROVIDER);
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAltitude(altitude);
location.setAccuracy(1);
location.setTime(System.currentTimeMillis());
location.setBearing(0F);
location.setSpeed(0.0F);
// show debug message in log
Log.d(LOG_TAG, location.toString());
// provide the new location
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.setTestProviderLocation(GPS_MOCK_PROVIDER, location);
// sleep for a while before providing next location
try {
Thread.sleep(200);
// gracefully handle Thread interruption (important!)
if (Thread.currentThread().isInterrupted())
throw new InterruptedException("");
} catch (InterruptedException e) {
break;
}
// keep track of processed locations
index++;
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
Log.d(LOG_TAG, "onProgressUpdate():" + values[0]);
mMockGpsProviderIndex = values[0];
}
}
}

Try adding:
location.setAccuracy(16F);
location.setAltitude(0D);
location.setBearing(0F);

I think you can call mock location also in your permissions (Manifest.xml), in order to work. Do you have that,in your permissions?
Because when I used it with this,it worked.
(Sorry I couldn't leave it as a comment because I don't have enough reputation)

Did you turn on Allow_Mock_Location in the setting of your physical device? It's under developer options.

Also add for your mock location
location.setSpeed(5);
speed more than 1, like 5 or 10

Related

Show splash screen instead of black screen while location user Android

Hi I have a service in which I find the user location co-ordinates. This service is started in onCreate in my MainActivity. however until it finds the values as I know GPS can take some time to find the co-ordinates the screen is black. I have created a splash screen which I would like to show but I am not sure on how to implement. My code will explain more:
My service:
public class LocationService extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener {
public static double curlat;
public static double curlong;
IBinder mBinder = new LocalBinder();
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
// Flag that indicates if a request is underway.
private boolean mInProgress;
public static final String BROADCAST_ACTION = "com.example.fusedlocation.displayevent";
Intent intent;
private Boolean servicesAvailable = false;
public class LocalBinder extends Binder {
public LocationService getServerInstance() {
return LocationService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
mInProgress = false;
// Create the LocationRequest object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
// Set the update interval to 5 seconds
mLocationRequest.setInterval(Constants.UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
mLocationRequest.setFastestInterval(Constants.FASTEST_INTERVAL);
servicesAvailable = servicesConnected();
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
mLocationClient = new LocationClient(this, this, this);
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
public int onStartCommand (Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
return START_STICKY;
setUpLocationClientIfNeeded();
if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress)
{
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Started", Constants.LOG_FILE);
mInProgress = true;
mLocationClient.connect();
}
return START_STICKY;
}
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
private void setUpLocationClientIfNeeded()
{
if(mLocationClient == null)
mLocationClient = new LocationClient(this, this, this);
}
// Define the callback method that receives location updates
#Override
public void onLocationChanged(android.location.Location location) {
// Report to the UI that the location was updated
String msg = Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
Log.d("debug", msg);
curlat = location.getLatitude();
curlong = location.getLongitude();
// Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
appendLog(msg, Constants.LOCATION_FILE);
intent.putExtra("Latitude", location.getLatitude());
intent.putExtra("Longitude", location.getLongitude());
sendBroadcast(intent, null);
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public String getTime() {
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mDateFormat.format(new Date());
}
public void appendLog(String text, String filename)
{
File logFile = new File(filename);
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onDestroy(){
// Turn off the request flag
mInProgress = false;
if(servicesAvailable && mLocationClient != null) {
mLocationClient.removeLocationUpdates(this);
// Destroy the current location client
mLocationClient = null;
}
// Display the connection status
// Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Stopped", Constants.LOG_FILE);
super.onDestroy();
}
/*
* Called by Location Services when the request to connect the
* client finishes successfully. At this point, you can
* request the current location or start periodic updates
*/
#Override
public void onConnected(Bundle bundle) {
// Request location updates using static settings
mLocationClient.requestLocationUpdates(mLocationRequest, this);
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Connected", Constants.LOG_FILE);
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
#Override
public void onDisconnected() {
// Turn off the request flag
mInProgress = false;
// Destroy the current location client
mLocationClient = null;
// Display the connection status
// Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected", Constants.LOG_FILE);
}
/*
* Called by Location Services if the attempt to
* Location Services fails.
*/
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
mInProgress = false;
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
// If no resolution is available, display an error dialog
} else {
}
}
}
MainActivity ( Only the relevant parts):
public class MainActivity extends Activity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener{
// Google Map & markers
private GoogleMap googleMap;
private Circle mCircle;
private Marker mMarker;
double radiusInMeters;
long start_time, countUp, timeDialogShown = 0;
double latitude, longitude, startLongitude, startLatitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting the layout
setContentView(R.layout.activity_main);
try {
// Loading map
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
startService(new Intent(this, LocationService.class));
} // end onCreate
//Checking the latest location updates
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
latitude = extras.getDouble("Latitude");
longitude = extras.getDouble("Longitude");
LatLng latLng = new LatLng(latitude, longitude);
if (mCircle == null || mMarker == null) {
drawMarkerWithCircle(latLng);
} else {
updateMarkerWithCircle(latLng);
}
getDistance();
//Getting the current weather conditions
//if (condDescr.getText().equals(" ")){
// getWeatherConditions();
//}
//Check if the user has breached the Geofence boundaries
checkBoundaries();
}
};
Check my answer here:
Android SplashScreen
Basically creating a theme background will deal with the black screen till you set the content.
Create a splash_screen activity. Set it as start-up activity.
In this splash_screen activity's onCreate() u can start a service to get location update.
Once u r done with location update, start ur MainAcitivity.class.
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen_layout);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
// start the service to get location update
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
// start the main activity
}
});
t1.start();
}

Unable to get current location from LocationListener

I have a LocationService which starts onResume() of the MainActivity and stops onDestroy().
#Override
protected void onResume() {
super.onResume();
//Start the service using alaram manager
//If its not running currently
if (isLocationServiceRunning(this)) {
am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, LocationService.class);
pi = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), 1 * 60 * 1000, pi);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (isLocationServiceRunning(this)) {
stopService(new Intent(this, LocationService.class));
if (am != null && pi != null) {
am.cancel(pi);
}
}
}
LocationService.java
public class LocationService extends Service implements LocationListener {
public static double curLat = 0.0;
public static double curLng = 0.0;
private LocationManager mgr;
private String best;
private Location location;
private Location currentBestLocation;
private static final int TWO_MINUTES = 1000 * 60 * 2;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean gps_enabled = mgr
.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (gps_enabled) {
// If GPS is enabled, set criteria as ACCURACY_FINE
// and get the best provider(which usually will be GPS_PROVIDER)
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
best = mgr.getBestProvider(criteria, true);
// getLastKnownLocation so that user don't need to wait
location = mgr.getLastKnownLocation(best);
if (location == null) {
// request for a single update, and try again.
// Later will request for updates every 10 mins
mgr.requestSingleUpdate(criteria, this, null);
location = mgr
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
if (location != null) {
// If the GPS gives a location, update curLat and curLng
dumpLocation(location);
} else {
// If the location is still null, go for NETWORK_PROVIDER
best = LocationManager.NETWORK_PROVIDER;
location = mgr.getLastKnownLocation(best);
if (location != null) {
// If the NETWORK gives a location, update curLat and curLng
dumpLocation(location);
}
}
// Register the Location Manager for updates, with both the
// providers
// Since GPS updates are expensive, we ask update every 10 mins and
// unregister updates if GPS is disabled in onProviderDisabled
// callback
mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
10 * 60 * 1000, 50, this);
// NETWORK_PROVIDER updates every 20 secs
mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
20 * 1000, 0, this);
return START_NOT_STICKY;
} else {
// If GPS is disables, go with NETWORK_PROVIDER
best = LocationManager.NETWORK_PROVIDER;
location = mgr.getLastKnownLocation(best);
if (location != null) {
dumpLocation(location);
}
// Register NETWORK_PROVIDER for updates every 20 secs
mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
20 * 1000, 0, this);
return START_NOT_STICKY;
}
}
private void dumpLocation(Location l) {
// Called to update the curLat and curLng.
currentBestLocation = l;
SimpleDateFormat s = new SimpleDateFormat("dd/MM/yyyy:hh:mm:ss",
Locale.ENGLISH);
String format = s.format(l.getTime());
try {
Geocoder coder = new Geocoder(this);
List<Address> address;
Address location = null;
address = coder.getFromLocation(l.getLatitude(), l.getLongitude(),
1);
location = address.get(0);
} catch (Exception e) {
Log.e("Exception while getting address", e.getMessage() + "");
}
curLat = l.getLatitude();
curLng = l.getLongitude();
}
#Override
public void onLocationChanged(Location location) {
// called when location is changed, since we registered Location
// Providers
// for updates
if (isBetterLocation(location, currentBestLocation)) {
dumpLocation(location);
} else {
Log.d("Not a Better Location", "Ignore");
}
}
#Override
public void onProviderDisabled(String provider) {
// Check if best(the currently being used provider) is not null
if (best != null) {
// if best and disabled provider are same, the remove updates
if ((provider.equalsIgnoreCase(LocationManager.GPS_PROVIDER) && best
.equals(LocationManager.GPS_PROVIDER))
|| provider
.equalsIgnoreCase(LocationManager.NETWORK_PROVIDER)
&& best.equals(LocationManager.NETWORK_PROVIDER)) {
if (mgr != null) {
mgr.removeUpdates(this);
}
}
}
}
#Override
public void onProviderEnabled(String provider) {
// This will be taken care in the onStartCommand where if gps_enabled
// case is used.
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// No need to care about, because any thing like OUT_OF_SERVICE occurs,
// location being fetched will be null and such cases are handled above.
if ((provider.equals(LocationManager.GPS_PROVIDER))
&& (LocationProvider.OUT_OF_SERVICE == status)) {
if (mgr != null) {
mgr.removeUpdates(this);
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
// triggered when we call stopService(LocationService);
// which is done in onDestroy of MainActivity
// Because LocationService must be stopped
// when application is closed to avoid data usage
if (mgr != null) {
mgr.removeUpdates(this);
}
}
protected boolean isBetterLocation(Location location,
Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use
// the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be
// worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Not significantly newer or older, so check for Accuracy
if (isMoreAccurate) {
// If more accurate return true
return true;
} else if (isNewer && !isLessAccurate) {
// Same accuracy but newer, return true
return true;
} else if (isNewer && !isSignificantlyLessAccurate
&& isFromSameProvider) {
// Accuracy is less (not much though) but is new, so if from same
// provider return true
return true;
}
return false;
}
// Checks whether two providers are the same
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
}
The service surely starts and stops as expected and I can see the location details in log, which are fine.
The problem if when I move to a complete different location(300 miles), the curLat and curLng values still remain as that of the old, when I open the application.
Is it because I am not running the service when the device is in motion(because my application is not running)?
Because when I open some other application like FourSquare(which gets the correct location) and then reopen my application, then it shows the correct location.
What else should I do to refresh the location properly.
I think your problem is here
best = mgr.getBestProvider(criteria, true);
// getLastKnownLocation so that user don't need to wait
location = mgr.getLastKnownLocation(best);
if (location == null) {
// request for a single update, and try again.
// Later will request for updates every 10 mins
mgr.requestSingleUpdate(criteria, this, null);
location = mgr
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
because there was previously a location location = mgr.getLastKnownLocation(best); returns that location without starting the provider (see the android documentation. So the location is not null and mgr.requestSingleUpdate(criteria, this, null); is never run.
To get up to date location data a provider must be started.
so a correction could be:
best = mgr.getBestProvider(criteria, true);
// getLastKnownLocation so that user don't need to wait
mgr.requestSingleUpdate(best, this, null);
location = mgr.getLastKnownLocation(best);
Also I'm not sure if it is intended but this service will use the network provider even when GPS data is available and more accurate (due to the 10 minute and 2 minute times chosen for GPS updates and data obsolescence.
P.S. Is there a specific reason you do not want to use FusedLocationProvider that is part of Google Play Services? I have found it to be simpler and it is supposedly optimized for selected best providers and conserving battery.
You code looks perfectly fine if you want to get the location in the foreground. I have gone through in the deep and get to know that in the onDestroy you have stopped the service and alarms also. hence as and when the current app is going to background and the onDestroy is called by system then the code fails to update the location in the background. more over when you launch the application again it will start the service and very first time get the older location which was cached.
when other application updates the location you will get that location according to documentation of the mgr.getLastKnownLocation(best).
Hence to solve this problem do not use alarm here to start service in repeating manner or destory it.
simply start the service and in the onStartCommand ask for the update of the location. and if you want to get rid of the location updates, use removeLocationUpdates(LocationListener) .
Examples are given here http://developer.android.com/training/location/receive-location-updates.html
My best guess is dump "isBetterLocation" and try without it to see what will happen. Based on those checks (which are rather complicated), I think the mistake is either in "isSignificantlyOlder" or in the last return statement (otherwise you would get the new location, correct?)
Have you debugged it to check if the current logic is correct, and if it is, for what distances?
Here is an example to receive location update using Google Play Services
This is MyActivity class
public class MyActivity extends Activity implements
ConnectionCallbacks, OnConnectionFailedListener {
public static final int PLAY_SERVICES_NOT_AVAILABLE_REQUEST = 9000;
public static final int CONNECTION_FAILED_REQUEST = 1000;
private LocationClient mLocationClient;
private LocationRequest mLocationrequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_myactivity);
LocationManager mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationClient = new LocationClient(this, this, this);
boolean isGPSEnabled = mLocationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean isNetworkEnabled = mLocationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Toast.makeText(this, "GPS: " + isGPSEnabled, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "Network: " + isNetworkEnabled, Toast.LENGTH_SHORT)
.show();
if (isGooglePlayServicesAvailable()) {
mLocationClient.connect();
} else {
// play services not available
}
}
private void defineLocationRequest() {
mLocationrequest = new LocationRequest();
mLocationrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(5000);
}
private PendingIntent getCallBackIntent() {
return PendingIntent
.getService(getApplicationContext(), 0, new Intent(this,
MyIntentService.class),
PendingIntent.FLAG_UPDATE_CURRENT);
}
private boolean isGooglePlayServicesAvailable() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode == ConnectionResult.SUCCESS) {
Log.d("Car Tracking", "play services available.");
return true;
} else {
Log.d("Car Tracking", "play services not available(resultCode:) "
+ resultCode);
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_NOT_AVAILABLE_REQUEST).show();
return false;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case PLAY_SERVICES_NOT_AVAILABLE_REQUEST:
if (resultCode == Activity.RESULT_OK) {
// check again
}
break;
case CONNECTION_FAILED_REQUEST:
if (resultCode == Activity.RESULT_OK) {
// try to connect LocationClient Againg
}
break;
}
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
if (arg0.hasResolution()) {
try {
arg0.startResolutionForResult(this, CONNECTION_FAILED_REQUEST);
} catch (SendIntentException e) {
Log.d("TAG",
"Exception in resolving connection failed: "
+ e.toString());
}
}
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
defineLocationRequest();
mLocationClient.requestLocationUpdates(mLocationrequest,
getCallBackIntent());
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
mLocationClient.removeLocationUpdates(getCallBackIntent());
super.onDestroy();
}
}
Now, this is MyIntentService Class's onHandleIntent Method.
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
if (intent != null) {
Bundle extra = intent.getExtras();
Location location = (Location) extra
.get(LocationClient.KEY_LOCATION_CHANGED);
}
Here, the location object will give you most recent location update
Also add
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
in your manifest
You can use the LocationClient from Google Play Services, its easy to use and proven very efficient.
Here is the link to example
Use Fused Location Provider (new feature available since 4.2 - https://developer.android.com/google/play-services/location.html) - it just gets fast current location and sending updates.
Example: http://www.motta-droid.com/2013/11/location-requests-for-your-app-how-to.html
Just run singleton above in a Service and adjust location update params to your needs.
The only issue You should care about - if it can't determine your current location at all. For example, if just GPS location provider available to your device and you're indoors.
I observed your code..You are updating the location but you are not receiving the updated location information. here is the code how to get the location from a Service
// Send an Intent with an action named "custom-event-name". The Intent sent
// should
// be received by the ReceiverActivity.
private static void sendMessageToActivity(Location l, String msg) {
Intent intent = new Intent("GPSLocationUpdates");
// You can also include some extra data.
intent.putExtra("Status", msg);
Bundle b = new Bundle();
b.putParcelable("Location", l);
intent.putExtra("Location", b);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
in you main activity or which has to receive the location Info write this code.
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
mMessageReceiver, new IntentFilter("GPSLocationUpdates"));
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle b = intent.getBundleExtra("Location");
lastKnownLoc = (Location) b.getParcelable("Location");
if (lastKnownLoc != null) {
tvLatitude.setText(String.valueOf(lastKnownLoc.getLatitude()));
tvLongitude
.setText(String.valueOf(lastKnownLoc.getLongitude()));
}
}
};
I hope this will work...
I you do not mind waiting for GPS to achieve a first-fix this might help you. The first-fix should only be a matter of seconds if a fix have been found recently.
I have implemented some code that sends callback as soon as there is a first-fix and on locationchange based on GPSTracker from http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/.
With this implementation you can do:
private GPSTracker gps;
private FirstFixListener firstFixListener;
private LocationUpdateListener locationUpdateListener;
private void startGPS() {
gps = GPSTracker.getInstance(context);
// create listeners
firstFixListener = new MyFirstFixListener();
locationUpdateListener = new MyLocationUpdateListener();
// start the gps
gps.startUsingGPS(firstFixListener, locationUpdateListener);
}
private void stopGPS() {
// stop the gps and unregister callbacks
gps.stopUsingGPS(firstFixListener, locationUpdateListener);
}
private class MyFirstFixListener implements FirstFixListener {
#Override
public void onFirsFixChanged(boolean hasGPSfix) {
if (hasGPSfix == true) {
// accurate position
Location position = gps.getLocation();
}
}
}
private class MyLocationUpdateListener implements LocationUpdateListener {
#Override
public void onLocationChanged(Location location) {
// hand you each new location from the GPS
// you do not need this if you only want to get a single position
}
}
And here is my implementation of GPSTracker:
public class GPSTracker extends Service implements LocationListener {
private static final String TAG = "GPSTracker";
/**
* Register to receive callback on first fix status
*
* #author Morten
*
*/
public interface FirstFixListener {
/**
* Is called whenever gps register a change in first-fix availability
* This is valuable to prevent sending invalid locations to the server.
*
* #param hasGPSfix
*/
public void onFirsFixChanged(boolean hasGPSfix);
}
/**
* Register to receive all location updates
*
* #author Morten
*
*/
public interface LocationUpdateListener {
/**
* Is called every single time the GPS unit register a new location
* The location param will never be null, however, it can be outdated if hasGPSfix is not true.
*
* #param location
*/
public void onLocationChanged(Location location);
}
private Context mContext;
// flag for GPS status
private List<FirstFixListener> firstFixListeners;
private List<LocationUpdateListener> locationUpdateListeners;
boolean isGPSFix = false;
boolean isGPSEnabled = false;
private GPSFixListener gpsListener;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
long mLastLocationMillis;
private boolean logLocationChanges;
// Declaring a Location Manager
protected LocationManager locationManager;
/** removed again as we need multiple instances with different callbacks **/
private static GPSTracker instance;
public static GPSTracker getInstance(Context context) {
if (instance != null) {
return instance;
}
return instance = new GPSTracker(context);
}
private GPSTracker(Context context) {
this.mContext = context;
gpsListener = new GPSFixListener();
firstFixListeners = new ArrayList<GPSTracker.FirstFixListener>();
locationUpdateListeners = new ArrayList<GPSTracker.LocationUpdateListener>();
}
public boolean hasGPSFirstFix() {
return isGPSFix;
}
private void addFirstFixListener(FirstFixListener firstFixListener) {
this.firstFixListeners.add(firstFixListener);
}
private void addLocationUpdateListener(
LocationUpdateListener locationUpdateListener) {
this.locationUpdateListeners.add(locationUpdateListener);
}
private void removeFirstFixListener(FirstFixListener firstFixListener) {
this.firstFixListeners.remove(firstFixListener);
}
private void removeLocationUpdateListener(
LocationUpdateListener locationUpdateListener) {
this.locationUpdateListeners.remove(locationUpdateListener);
}
public void setLogLocationChanges(boolean logLocationChanges) {
this.logLocationChanges = logLocationChanges;
}
public Location getLocation() {
return location;
}
private Location startLocationListener() {
canGetLocation = false;
try {
locationManager = (LocationManager) mContext
.getSystemService(Service.LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, this);
locationManager.addGpsStatusListener(gpsListener);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
} else {
showSettingsAlert();
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS(FirstFixListener firstFixListener,
LocationUpdateListener locationUpdateListener) {
if (firstFixListener != null)
removeFirstFixListener(firstFixListener);
if (locationUpdateListener != null)
removeLocationUpdateListener(locationUpdateListener);
stopUsingGPS();
}
/**
* Stop using GPS listener Calling this function will stop using GPS in your
* app
* */
public void stopUsingGPS() {
Log.d("DEBUG", "GPS stop");
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
location = null;
if (gpsListener != null) {
locationManager.removeGpsStatusListener(gpsListener);
}
}
isGPSFix = false;
location = null;
}
public void startUsingGPS(FirstFixListener firstFixListener,
LocationUpdateListener locationUpdateListener) {
Log.d("DEBUG", "GPS start");
if (firstFixListener != null)
addFirstFixListener(firstFixListener);
if (locationUpdateListener != null)
addLocationUpdateListener(locationUpdateListener);
startLocationListener();
}
/**
* Function to get latitude
* */
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
} else {
Log.e("GPSTracker", "getLatitude location is null");
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
} else {
Log.e("GPSTracker", "getLongitude location is null");
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
*
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog On pressing Settings button will
* lauch Settings Options
* */
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS settings");
// Setting Dialog Message
alertDialog
.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
if ( location == null)
return;
this.location = location;
mLastLocationMillis = SystemClock.elapsedRealtime();
canGetLocation = true;
if (isGPSFix) {
if (locationUpdateListeners != null) {
for (LocationUpdateListener listener : locationUpdateListeners) {
listener.onLocationChanged(location);
}
}
}
}
#Override
public void onProviderDisabled(String provider) {
canGetLocation = false;
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
private boolean wasGPSFix = false;
// http://stackoverflow.com/questions/2021176/how-can-i-check-the-current-status-of-the-gps-receiver
// answer from soundmaven
private class GPSFixListener implements GpsStatus.Listener {
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
if (isGPSFix != wasGPSFix) { // only notify on changes
wasGPSFix = isGPSFix;
for (FirstFixListener listener : firstFixListeners) {
listener.onFirsFixChanged(isGPSFix);
}
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
// Do something.
break;
}
}
}
}

android mock gps does not work on real device

I have added:
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
and the code below:
public class MockGpsProviderActivity extends Activity implements LocationListener {
public static final String LOG_TAG = "MockGpsProviderActivity";
private static final String MOCK_GPS_PROVIDER_INDEX = "GpsMockProviderIndex";
private MockGpsProvider mMockGpsProviderTask = null;
private Integer mMockGpsProviderIndex = 0;
/** Called when the activity is first created. */
/* (non-Javadoc)
* #see android.app.Activity#onCreate(android.os.Bundle)
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** Use saved instance state if necessary. */
if(savedInstanceState instanceof Bundle) {
/** Let's find out where we were. */
mMockGpsProviderIndex = savedInstanceState.getInt(MOCK_GPS_PROVIDER_INDEX, 0);
}
/** Setup GPS. */
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
// use real GPS provider if enabled on the device
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
else if(!locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) {
// otherwise enable the mock GPS provider
locationManager.addTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER, false, false,
false, false, true, false, false, 0, Criteria.ACCURACY_HIGH);
locationManager.setTestProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER, true);
}
if(locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) {
locationManager.requestLocationUpdates(MockGpsProvider.GPS_MOCK_PROVIDER, 0, 0, this);
/** Load mock GPS data from file and create mock GPS provider. */
try {
// create a list of Strings that can dynamically grow
List<String> data = new ArrayList<String>();
/** read a CSV file containing WGS84 coordinates from the 'assets' folder
* (The website http://www.gpsies.com offers downloadable tracks. Select
* a track and download it as a CSV file. Then add it to your assets folder.)
*/
InputStream is = getAssets().open("mock_gps_data.csv");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
// add each line in the file to the list
String line = null;
while ((line = reader.readLine()) != null) {
data.add(line);
}
// convert to a simple array so we can pass it to the AsyncTask
String[] coordinates = new String[data.size()];
data.toArray(coordinates);
// create new AsyncTask and pass the list of GPS coordinates
mMockGpsProviderTask = new MockGpsProvider();
mMockGpsProviderTask.execute(coordinates);
}
catch (Exception e) {}
}
}
#Override
public void onDestroy() {
super.onDestroy();
// stop the mock GPS provider by calling the 'cancel(true)' method
try {
mMockGpsProviderTask.cancel(true);
mMockGpsProviderTask = null;
}
catch (Exception e) {}
// remove it from the location manager
try {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.removeTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER);
}
catch (Exception e) {}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// store where we are before closing the app, so we can skip to the location right away when restarting
savedInstanceState.putInt(MOCK_GPS_PROVIDER_INDEX, mMockGpsProviderIndex);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onLocationChanged(Location location) {
// show the received location in the view
TextView view = (TextView) findViewById(R.id.text);
view.setText( "index:" + mMockGpsProviderIndex
+ "\nlongitude:" + location.getLongitude()
+ "\nlatitude:" + location.getLatitude()
+ "\naltitude:" + location.getAltitude() );
}
#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
}
/** Define a mock GPS provider as an asynchronous task of this Activity. */
private class MockGpsProvider extends AsyncTask<String, Integer, Void> {
public static final String LOG_TAG = "GpsMockProvider";
public static final String GPS_MOCK_PROVIDER = "GpsMockProvider";
/** Keeps track of the currently processed coordinate. */
public Integer index = 0;
#Override
protected Void doInBackground(String... data) {
// process data
for (String str : data) {
// skip data if needed (see the Activity's savedInstanceState functionality)
if(index < mMockGpsProviderIndex) {
index++;
continue;
}
// let UI Thread know which coordinate we are processing
publishProgress(index);
// retrieve data from the current line of text
Double latitude = null;
Double longitude = null;
Double altitude= null;
try {
String[] parts = str.split(",");
latitude = Double.valueOf(parts[0]);
longitude = Double.valueOf(parts[1]);
altitude = Double.valueOf(parts[2]);
}
catch(NullPointerException e) { break; } // no data available
catch(Exception e) { continue; } // empty or invalid line
// translate to actual GPS location
Location location = new Location(GPS_MOCK_PROVIDER);
//location.setLatitude(latitude);
//location.setLongitude(longitude);
location.setLatitude(39.794952);
location.setLongitude(116.515134);
location.setAltitude(10);
//location.setAccuracy(4);
location.setTime(System.currentTimeMillis());
// show debug message in log
Log.d(LOG_TAG, location.toString());
// provide the new location
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.setTestProviderLocation(GPS_MOCK_PROVIDER, location);
// sleep for a while before providing next location
try {
Thread.sleep(200);
// gracefully handle Thread interruption (important!)
if(Thread.currentThread().isInterrupted())
throw new InterruptedException("");
} catch (InterruptedException e) {
break;
}
// keep track of processed locations
index++;
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
Log.d(LOG_TAG, "onProgressUpdate():"+values[0]);
mMockGpsProviderIndex = values[0];
}
}
}
I start the mockgps app, then press the home button to make it background. then I write another test application, and it can read the Latitude, Longitude, Altitude. But when I open the google map application, the google map always says that "can not locate". what's the problem?
thanks.

Find out the speed of the User in android Using GPS

I tried to find out the speed of User, while user is moving with device. Here, I followed one link with sample code. i.e: Here SpeedDemo.
The problem is, by using location.getSpeed() method, we are finding the speed. So, for that I changed the location values in device, but every time the value of the location.getspeed() return '0' only. Why it happen, even changing the location itself.
Can any one known about this?
You have to track location Updates, and when the method onLocationChanged(Location location) triggers, you can call location.getSpeed(); it will give you correct speed, if your phone is actually moving.
But if you are testing it on Simulator, and sending location by emulator controller, it will always return 0.
Updated with Example
public class LocationService implements LocationListener {
LocationService locationService;
LocationManager locationManager;
Location lastLocation;
private final String TAG = "LocationService" ;
private final String MOCK_LOCAION_PROVIDER = "FAKE_PROVIDER";
LocationService(Context ctx) {
LocationManager locationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
String mocLocationProvider = MOCK_LOCAION_PROVIDER;
if (locationManager.getProvider(mocLocationProvider) != null) {
locationManager.removeTestProvider(mocLocationProvider);
}
locationManager.addTestProvider(mocLocationProvider, false, false, false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);
locationManager.requestLocationUpdates(mocLocationProvider, 0, 0,
this);
try {
List<String> data = new ArrayList<String>();
InputStream is = ctx.getAssets().open("data.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
data.add(line);
}
// Log.e(TAG, data.size() + " lines");
new MockLocationProvider(locationManager, mocLocationProvider, data).start();
} catch (IOException e) {
e.printStackTrace();
}
}
class MockLocationProvider extends Thread {
private List<String> data;
private LocationManager locationManager;
private String mocLocationProvider;
private String LOG_TAG = "MockLocationProvider";
public MockLocationProvider(LocationManager locationManager, String mocLocationProvider, List<String> data) throws IOException {
this.locationManager = locationManager;
this.mocLocationProvider = mocLocationProvider;
this.data = data;
}
#Override
public void run() {
for (String str : data) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Set one position
String[] parts = str.split(",");
Double latitude = Double.valueOf(parts[0]);
Double longitude = Double.valueOf(parts[1]);
float speed = Float.valueOf(parts[2]);
Location location = new Location(mocLocationProvider);
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setSpeed(speed);
// location.setAltitude(altitude);
// Log.d(LOG_TAG, location.toString());
// set the time in the location. If the time on this location
// matches the time on the one in the previous set call, it will
// be
// ignored
location.setTime(System.currentTimeMillis());
locationManager.setTestProviderLocation(mocLocationProvider, location);
}
}
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Log.e(TAG, "onLocationChanged");
// Get Location Speed Here
Log.d(TAG, "Speed " +location.getSpeed());
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
// Log.e(TAG, "onProviderDisabled : "+provider);
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
// Log.e(TAG, "onProviderEnabled : "+provider);
}
public void onStatusChanged(String provider, int status, Bundle arg2) {
// TODO Auto-generated method stub
// Log.e(TAG, "onStatusChanged : "+status);
}
}
The Above code is actually a location service class, when you make an instance of this class, it register a fake Location Service(other than GPS, and Network) provider, and input some fake location parameters by a given file.
Below is the data.txt file which has latitude,longitude,speed the above class read this data.txt file and input fake lat,lon, and speed in the location, as well as trigger time to change location is also implemented by Thread.sleep() call.
Data.txt file
24.856449265609735,67.04308920288086,1.64
24.856749265609735,67.04408920288086,7.64
24.856949265609735,67.04508920288086,11.64
24.857649265609735,67.04716920288086,13.64
24.857949265609735,67.04736920288086,12.64
24.857949265609735,67.04742520288086,8.64
24.857949265609735,67.04747020288086,4.64
24.856749265609735,67.04408920288086,6.11
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.1
24.856949265609735,67.04508920288086,2.13
24.857249265609735,67.04608920288086,0.6
24.856949265609735,67.04508920288086,1.19
24.857249265609735,67.04608920288086,1.6
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.15
24.857849265609735,67.04729920288086,17.64
24.857949265609735,67.04736920288086,12.64
24.857949265609735,67.04739920288086,16.64
24.857949265609735,67.04742520288086,8.64
24.857949265609735,67.04747020288086,4.64
24.856749265609735,67.04408920288086,6.11
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.1
24.856949265609735,67.04508920288086,2.13
24.857249265609735,67.04608920288086,0.6
24.856949265609735,67.04508920288086,1.19
24.857249265609735,67.04608920288086,1.6
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.15
24.857849265609735,67.04729920288086,17.64
24.857949265609735,67.04736920288086,12.64
24.857949265609735,67.04739920288086,16.64
24.857949265609735,67.04742520288086,8.64
24.857949265609735,67.04747020288086,4.64
24.856749265609735,67.04408920288086,6.11
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.1
24.857849265609735,67.04729920288086,17.64
24.857949265609735,67.04736920288086,12.64
24.857949265609735,67.04739920288086,16.64
24.857949265609735,67.04742520288086,8.64
24.857949265609735,67.04747020288086,4.64
24.856749265609735,67.04408920288086,6.11
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.15
24.856949265609735,67.04508920288086,2.13
24.857249265609735,67.04608920288086,0.6
24.856949265609735,67.04508920288086,1.19
24.857249265609735,67.04608920288086,1.6
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.15
24.856949265609735,67.04508920288086,2.13
24.857249265609735,67.04608920288086,0.6
24.856949265609735,67.04508920288086,1.19
24.857249265609735,67.04608920288086,1.6
24.856949265609735,67.04508920288086,2.12
24.857249265609735,67.04608920288086,1.15
I think getSpeed() will work only if the particular location have speed component available with GPS. Otherwise it will returned 0.0 all the time.
For that you can check that using condition location.hasSpeed() method. If true then do your stuff else think another way.
First we need to check whether the Gps Enabled or not using location manager.
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Then , you need to implement GpsStatus.Listener to get the Gps updates. It will return the Gps location updates.
GPSManager.locationListener = new LocationListener() {
#Override
public void onLocationChanged(final Location location) {
if (GPSManager.gpsCallback != null) {
GPSManager.gpsCallback.onGPSUpdate(location);
}
}
#Override
public void onProviderDisabled(final String provider) {
}
#Override
public void onProviderEnabled(final String provider) {
}
#Override
public void onStatusChanged(final String provider, final int status, final Bundle extras) {
}
};
From that location you can able to get the current speed.
speed = location.getSpeed();
Refer to my website here for further details : http://velmm.com/get-current-user-speed-using-gps-android/

android Async Task for proper usage of ui thread

Below is my prepared code which listens for location updates and once the location is within a designated area, it will connect to a server and will start sending it's locations and time stamps until it exit the area.
I was advised that the different methods may stress out the ui thread and that i need to have the network connection to run in the background or on a separate thread to prevent slow down in the application.
I was reading about Async Task in the android documentation.
Here are my questions:
I guess i need to put in a separate thread the part after the app determines that it is inside the designated area (rectangle) and the moment that it is trying to connect and send to the server?
How will i do that ?
public class GpsActivity extends Activity {
private LocationManager lm;
private LocationListener locationListener;
public static TelephonyManager tm;
public static TextView tv;
public static Socket s;
public static PrintWriter out;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* retrieve a reference to provide access to information about the telephony services on the device
*/
tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
setContentView(R.layout.main);
/**
* retrieve a reference to provide access to the system location services
*/
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
/**
* explicitly select the provider, create a set of Criteria and let android choose the best provider available
*/
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 = lm.getBestProvider(criteria, true);
/**
* This method takes in four parameters:
provider: The name of the provider with which you register
minTime: The minimum time interval for notifications, in milliseconds.
minDistance: The minimum distance interval for notifications, in meters.
listener: An object whose onLocationChanged() method will be called for each location update.
*/
locationListener = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
tv = (TextView) findViewById(R.id.textView1);
tv.setText("I currently have no Location Data.");
}
/**
* Connects the Android Client to a given server
*
* #param name
* The name of the remote server
* #param port
* Port number to connect to at the remote server.
* #throws IOException
* #throws UnknownHostException
*/
public static void connect(String name, int port)
throws UnknownHostException, IOException
{
s = new Socket(name, port);
out = new PrintWriter(s.getOutputStream(), true);
}
/**
* Sends a string message to the server.
*
* #param msg
* The message to be sent.
* #throws IOException
*/
public static void send(String msg) throws IOException
{
if (!s.isClosed() && msg != null)
{
out.println(msg);
if (msg.contains("CMD_QUIT"))
{
out.close();
s.close();
Log.i("ServerConnection", "Client Disconnected.");
}
}
}
//Used for receiving notifications from the LocationManager when the location has changed
private class MyLocationListener implements LocationListener{
#Override
public void onLocationChanged(Location loc) {
String txt = "Latitude:" + loc.getLatitude() + "/nLongitude:" + loc.getLongitude();
Log.i("GeoLocation", "My current location is:\n " + txt);
tv.setText("My current location is:\n" + txt);
final String msg = loc.getLongitude() + "\n" + loc.getLatitude() + "\n"
+ loc.getTime();
//determines if the location is within a designated area (rectangle)
double lat0 = 14.618572;
double long0 = 120.993816;
double lat1 = 14.619652;
double long1 = 120.992770;
double lat2 = 14.620285;
double long2 = 120.993451;
double lat3 = 14.619242;
double long3 = 120.994497;
double rel1 = (loc.getLongitude()- long0)*(lat1 - lat0)- ((loc.getLatitude()-lat0)*(long1-long0));
double rel2 = (loc.getLongitude()- long1)*(lat2 - lat1)- ((loc.getLatitude()-lat1)*(long2-long1));
double rel3 = (loc.getLongitude()- long2)*(lat3 - lat2)- ((loc.getLatitude()-lat2)*(long3-long2));
double rel4 = (loc.getLongitude()- long3)*(lat0 - lat3)- ((loc.getLatitude()-lat3)*(long0-long3));
// if yes, it will connect to server and send the location and timestamp
if (rel1 >= 0 && rel2 >= 0 && rel3 >= 0 && rel4 >= 0 )
{
try
{
connect("IP address", 27960);
send("CMD_HELLO");
send(msg);
tv.setText("Location is inside the road network...sending coordinates to server");
send("CMD_QUIT");
} catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
tv.setText("Current location is outside the road network");
}
}
#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
}
}
}
Just fyi you could use runnOnUIThread(Runnable R) to change the Text.
Anyway with AsyncTask is better because you don't freeze the UI while connecting.
Was able to do it and it worked by following the tutorial.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* retrieve a reference to provide access to information about the telephony services on the device
*/
tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
setContentView(R.layout.main);
/**
* retrieve a reference to provide access to the system location services
*/
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
/**
explicitly select the GPS provider, create a set of Criteria and let android choose
the best provider available
*/
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 = lm.getBestProvider(criteria, true);
/**
* This method takes in four parameters:
provider: The name of the provider with which you register
minTime: The minimum time interval for notifications, in milliseconds.
minDistance: The minimum distance interval for notifications, in meters.
listener: An object whose onLocationChanged() method will be called for each location update.
*/
locationListener = new MyLocationListener();
lm.requestLocationUpdates(provider, 1000, 1, locationListener);
tv = (TextView) findViewById(R.id.textView1);
tv.setText("I currently have no Location Data.");
}
/**
* Connects the Android Client to a given server
*
* #param name
* The name of the remote server
* #param port
* Port number to connect to at the remote server.
* #throws IOException
* #throws UnknownHostException
*/
public static void connect(String name, int port)
throws UnknownHostException, IOException
{
s = new Socket(name, port);
out = new PrintWriter(s.getOutputStream(), true);
}
/**
* Sends a string message to the server.
*
* #param msg
* The message to be sent.
* #throws IOException
*/
public static void send(String outmsg) throws IOException
{
if (!s.isClosed() && outmsg != null)
{
out.println(outmsg);
out.close();
s.close();
}}
//Used for receiving notifications from the LocationManager when the location has changed
private class MyLocationListener implements LocationListener{
#Override
public void onLocationChanged(Location loc) {
String txt = "Latitude:" + loc.getLatitude() + "/nLongitude:" + loc.getLongitude();
Log.i("GeoLocation", "My current location is:\n " + txt);
tv.setText("My current location is:\n" + txt);
String msg=loc.getLongitude() + "\n" + loc.getLatitude() + "\n"
+ loc.getTime();
tv1 = (TextView) findViewById(R.id.textView2);
tv2 = (TextView) findViewById(R.id.textView3);
//determines if the location is within a designated area (rectangle)
double lat0 = 14.609794;
double long0 = 120.986018;
double lat1 = 14.608966;
double long1 = 120.986037;
double lat2 = 14.609031;
double long2 = 120.984991;
double lat3 = 14.609877;
double long3 = 120.985069;
double rel1 = (loc.getLongitude()- long0)*(lat1 - lat0)- ((loc.getLatitude()-lat0)*(long1-long0));
double rel2 = (loc.getLongitude()- long1)*(lat2 - lat1)- ((loc.getLatitude()-lat1)*(long2-long1));
double rel3 = (loc.getLongitude()- long2)*(lat3 - lat2)- ((loc.getLatitude()-lat2)*(long3-long2));
double rel4 = (loc.getLongitude()- long3)*(lat0 - lat3)- ((loc.getLatitude()-lat3)*(long0-long3));
// if yes, it will connect to server and send the location and timestamp
if (rel1 >= 0 && rel2 >= 0 && rel3 >= 0 && rel4 >= 0 )
{
tv1.setText("Location is inside the road network...");
**new connectSend().execute(msg);**
}
else
{
tv1.setText("Current location is outside the road network");
}
}
#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
}
**public class connectSend extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... msg) {
// TODO Auto-generated method stub
String result;
try
{
connect("ip address", port);
send(msg[0]);
result = "SUCCESSFUL coordinates sent to server";
} catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
result = "NOT SUCCESSFUL ";
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
result = "NOT SUCCESSFUL ";
}
return result;}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
tv2.setText("result");
}**
}
}
}

Categories

Resources