senps
senps

Reputation: 594

Best way to track Android phone in a moving car

I am creating an app which send GPS coordinates once location is change. I need to send data only when the vehicle is moving. How can I get to know this. I got two options

  1. Using onLocationChanged, getSpeed();
  2. Using the Accelerometer

What is the best way to do this?

Upvotes: 0

Views: 1565

Answers (3)

Kaushal28
Kaushal28

Reputation: 5557

As the answer of @BiGGZ says, OnLocationChanged() is best way to do that. Here I'm including sample code, Which runs in Service to track location in background.

public class GPSService extends Service implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,LocationListener {


private int i=0;
private GoogleApiClient mGoogleApiClient;
private DatabaseHelper myDb;
private LocationRequest mLocationRequest;
private int uniqueInt=0;
private PowerManager.WakeLock wakeLock;
private String templat, templong;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}


@Override
public void onCreate() {
    super.onCreate();


    PowerManager mgr = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
    wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
    wakeLock.acquire();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
    myDb =new DatabaseHelper(this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    mGoogleApiClient.connect();

    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {


    mGoogleApiClient.disconnect();
    wakeLock.release();
    super.onDestroy();



}



@Override
public void onConnected(Bundle bundle) {
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(1000); // Update location every second

    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {
    Toast.makeText(this,"GoogleApiClient connection has been suspend",Toast.LENGTH_SHORT).show();
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Toast.makeText(this,"GoogleApiClient connection has failed",Toast.LENGTH_SHORT).show();
}

@Override
public void onLocationChanged(Location location) {
    double lat = location.getLatitude(), lon = location.getLongitude();
  //  Toast.makeText(this,lat+"--->"+lon,Toast.LENGTH_SHORT).show();

   //Do your task here!!


}

}

And I've taken frequency of tracking location 1 second, If you want to save battery, Change it to 5 or 10 seconds.

EDIT:

For calculate speed of your device, use following method for calculate difference between your 2 tracked coordinates(in meter) and then divide this by your tracking frequency(ex. divide by 5 if you are tracking location every 5 sec.). Which will give you speed in m/s.

    public double distance(String lat1, String lon1, String lat2, String lon2){

    double earthRadius = 6378.137;
    double dLat = Double.parseDouble(lat2)*Math.PI/180 - Double.parseDouble(lat1)*Math.PI/180;
    double dLon = Double.parseDouble(lon2)*Math.PI/180 - Double.parseDouble(lon1)*Math.PI/180;

    double a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(Double.parseDouble(lat1)*Math.PI/180) * Math.cos(Double.parseDouble(lat2)*Math.PI/180)*
            Math.sin(dLon/2) * Math.sin(dLon/2);

    double c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
    double d = earthRadius*c;
    return d*1000;  //distance in meter.


}

Hope this helps :)

Upvotes: 2

BMacedo
BMacedo

Reputation: 778

The best way to achieve what you want without requiring too much battery of the device is to detect when the user is in a car by using the Awareness API.

To check the user's current activity (running, walking, driving, etc), you should retrieve like this:

Awareness.SnapshotApi.getDetectedActivity(mGoogleApiClient)
        .setResultCallback(new ResultCallback<DetectedActivityResult>() {
            @Override
            public void onResult(@NonNull DetectedActivityResult detectedActivityResult) {
                if (!detectedActivityResult.getStatus().isSuccess()) {
                    Log.e(TAG, "Could not get the current activity.");
                    return;
                }
                ActivityRecognitionResult ar = detectedActivityResult.getActivityRecognitionResult();
                DetectedActivity probableActivity = ar.getMostProbableActivity();
                Log.i(TAG, probableActivity.toString());
            }
        });

When using this API remember to declare the com.google.android.gms.permission.ACTIVITY_RECOGNITION permission in your AndroidManifest, and check the user's permission at runtime.

Upvotes: 2

BiGGZ
BiGGZ

Reputation: 503

onLocationChanged is probably your best bet. This can be quite heavy on the battery, so be careful with your frequency. If im not mistaken, the accelerometer is used to detect movement along 3 axis, like device rotation. A moving car doesnt sound like an apporpriate use case.

Upvotes: 3

Related Questions