在移动的汽车中跟踪 Android phone 的最佳方式

Best way to track Android phone in a moving car

我正在创建一个应用程序,它会在位置发生变化时发送 GPS 坐标。我只需要在车辆行驶时发送数据。我怎么才能知道这个。我有两个选择

  1. 使用onLocationChanged, getSpeed();
  2. 使用加速度计

最好的方法是什么?

onLocationChanged 可能是您最好的选择。这对电池来说可能很重,所以要小心你的频率。如果我没记错的话,加速度计用于检测沿 3 轴的运动,例如设备旋转。行驶中的汽车听起来不是一个合适的用例。

正如@BiGGZ 的回答所说,OnLocationChanged() 是最好的方法。我在这里包含示例代码,它在服务中运行以在后台跟踪位置。

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!!


}

}

并且我已经将跟踪位置的频率设置为 1 秒,如果您想节省电量,请将其更改为 5 或 10 秒。

编辑:

要计算您设备的速度,请使用以下方法计算您的 2 个跟踪坐标之间的差异(以米为单位),然后将其除以您的跟踪频率(例如,如果您每 5 秒跟踪一次位置,则除以 5。 ).这将使您在 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.


}

希望对您有所帮助:)

在不需要太多设备电池的情况下实现您想要的效果的最佳方法是使用 Awareness API.

检测用户何时在车内

要检查用户当前的 activity(运行、步行、驾驶等),您应该像这样检索:

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());
            }
        });

使用这个API时记得在你的AndroidManifest中声明com.google.android.gms.permission.ACTIVITY_RECOGNITION权限,并在运行时检查用户的权限。