从android studio向服务器发布动态实时位置GPS坐标
我要做的是跟踪车辆的位置,在这里,我以固定的间隔/指定的距离跟踪车辆位置。下一件事是将位置详细信息发布到服务器上,我正在使用截击库将其发送给服务器,但是它只被发布到服务器上一次,而不是定期发布从android studio向服务器发布动态实时位置GPS坐标,android,android-maps-v2,Android,Android Maps V2,我要做的是跟踪车辆的位置,在这里,我以固定的间隔/指定的距离跟踪车辆位置。下一件事是将位置详细信息发布到服务器上,我正在使用截击库将其发送给服务器,但是它只被发布到服务器上一次,而不是定期发布 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void startBackgroundService() { if(!registered) { IntentFilter i = new I
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void startBackgroundService() {
if(!registered) {
IntentFilter i = new IntentFilter(JOB_STATE_CHANGED);
i.addAction(LOCATION_ACQUIRED);
LocalBroadcastManager.getInstance(this).registerReceiver(jobStateChanged, i);
}
JobScheduler jobScheduler =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
assert jobScheduler != null;
jobScheduler.schedule(new JobInfo.Builder(LocationJobService.LOCATION_SERVICE_JOB_ID,
new ComponentName(this, LocationJobService.class))
.setOverrideDeadline(500)
.setPersisted(true)
.setRequiresDeviceIdle(false)
.build());
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(30000);
mLocationRequest.setFastestInterval(15000);
mLocationRequest.setSmallestDisplacement(50);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
SettingsClient client = LocationServices.getSettingsClient(this);
Toast.makeText(this, "Location request created", Toast.LENGTH_SHORT).show();
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
bService.setVisibility(View.GONE);
startLocationUpdates();
}
});
task.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case CommonStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(MainActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sendEx) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way
// to fix the settings so we won't show the dialog.
break;
}
}
});
}
private void startLocationUpdates() {
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
Toast.makeText(MainActivity.this, "Starting Location Updates", Toast.LENGTH_SHORT).show();
for (Location location : locationResult.getLocations()) {
// Update UI with location data
// ...
updateMarker(location);
}
}
;
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
Toast.makeText(getApplicationContext(),"location permission required !!",Toast.LENGTH_SHORT).show();
return;
}
mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
mLocationCallback,
null /* Looper */);
button.setTag("f");
button.setText("STOP FOREGROUND TRACKING");
// Toast.makeText(getApplicationContext(),"Location update started",Toast.LENGTH_SHORT).show();
}
private void stopLocationUpdates() {
if (button.getTag().equals("s")) {
Log.d("TRACK", "stopLocationUpdates: updates never requested, no-op.");
return;
}
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
button.setTag("s");
button.setText("START FOREGROUND TRACKING");
bService.setVisibility(View.VISIBLE);
// Toast.makeText(getApplicationContext(),"Location update stopped.",Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
try {
if (registered) {
unregisterReceiver(jobStateChanged);
}
}catch (Exception e){
e.printStackTrace();
}
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if( requestCode == REQUEST_CHECK_SETTINGS) {
switch (resultCode) {
case Activity.RESULT_OK:
Log.i("Dash", "User agreed to make required location settings changes.");
createLocationRequest();
break;
case Activity.RESULT_CANCELED:
// showTimeoutDialog("Without location access, GreenPool Enterprise can't be used !!", true);
Log.i("Dash", "User choose not to make required location settings changes.");
break;
}
}else{
super.onActivityResult(requestCode, resultCode, data);
}
}
static void animateMarkerToICS(Marker marker, LatLng finalPosition) {
TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() {
@Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
return interpolate(fraction, startValue, endValue);
}
};
Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position");
ObjectAnimator animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);
animator.setDuration(3000);
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
handler.post(moveThread);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
animator.start();
}
public static LatLng interpolate(float fraction, LatLng a, LatLng b) {
// function to calculate the in between values of old latlng and new latlng.
// To get more accurate tracking(Car will always be in the road even when the latlng falls away from road), use roads api from Google apis.
// As it has quota limits I didn't have used that method.
double lat = (b.latitude - a.latitude) * fraction + a.latitude;
double lngDelta = b.longitude - a.longitude;
// Take the shortest path across the 180th meridian.
if (Math.abs(lngDelta) > 180) {
lngDelta -= Math.signum(lngDelta) * 360;
}
double lng = lngDelta * fraction + a.longitude;
return new LatLng(lat, lng);
}
private class MoveThread implements Runnable {
LatLng newPoint;
float zoom = 16;
void setNewPoint(LatLng latLng, float zoom){
this.newPoint = latLng;
this.zoom = zoom;
}
@Override
public void run() {
final CameraUpdate point = CameraUpdateFactory.newLatLngZoom(newPoint,zoom);
runOnUiThread(new Runnable() {
@Override
public void run() {
mMap.animateCamera(point);
}
});
}
}
private void updateMarker(final Location location) {
if(location == null){
return;
}
if(mMap!=null && mapLoaded){
if(carMarker==null) {
Toast.makeText(this, "Updating Marker Locations", Toast.LENGTH_SHORT).show();
oldLocation = location;
MarkerOptions markerOptions = new MarkerOptions();
BitmapDescriptor car = BitmapDescriptorFactory.fromResource(R.mipmap.ic_car);
markerOptions.icon(car);
markerOptions.anchor(0.5f, 0.5f); // set the car image to center of the point instead of anchoring to above or below the location
markerOptions.flat(true); // set as true, so that when user rotates the map car icon will remain in the same direction
markerOptions.position(new LatLng(location.getLatitude(),location.getLongitude()));
carMarker = mMap.addMarker(markerOptions);
if(location.hasBearing()){ // if location has bearing set the same bearing to marker(if location is acquired using GPS bearing will be available)
bearing = location.getBearing();
}else{
bearing = 0; // no need to calculate bearing as it will be the first point
}
carMarker.setRotation(bearing);
moveThread = new MoveThread();
moveThread.setNewPoint(new LatLng(location.getLatitude(),location.getLongitude()),16);
handler.post(moveThread);
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "abc.com/location";
JSONObject jsonBody = new JSONObject();
jsonBody.put("latitude", location.getLatitude());
jsonBody.put("longitude", location.getLongitude());
final String requestBody = jsonBody.toString();
Toast.makeText(this, "Locations are posted", Toast.LENGTH_SHORT).show();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
parseData(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
@Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
}else{
if(location.hasBearing()){// if location has bearing set the same bearing to marker(if location is acquired using GPS bearing will be available)
bearing = location.getBearing();
}else { // if not, calculate bearing between old location and new location point
bearing = oldLocation.bearingTo(location);
}
carMarker.setRotation(bearing);
moveThread.setNewPoint(new LatLng(location.getLatitude(),location.getLongitude()),mMap.getCameraPosition().zoom); // set the map zoom to current map's zoom level as user may zoom the map while tracking.
animateMarkerToICS(carMarker,new LatLng(location.getLatitude(),location.getLongitude())); // animate the marker smoothly
}
}else{
Log.e("map null or not loaded","");
}
}
private void parseData(String response){
try {
JSONObject object = new JSONObject(response);
if (object.getString("status").equals("true")){
Toast.makeText(this, "Successfully Location Details Posted to server", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@RequiresApi(api=Build.VERSION\u CODES.LOLLIPOP)
私有void startBackgroundService(){
如果(!已注册){
IntentFilter i=新的IntentFilter(作业状态已更改);
i、 addAction(获取位置);
LocalBroadcastManager.getInstance(this.registerReceiver)(jobStateChanged,i);
}
作业调度器作业调度器=
(JobScheduler)getSystemService(Context.JOB\u SCHEDULER\u服务);
断言作业调度器!=null;
jobScheduler.schedule(新JobInfo.Builder(LocationJobService.LOCATION\u SERVICE\u JOB\u ID、,
新组件名称(此,LocationJobService.class))
.SETOVERRIDEADLINE(500)
.setPersisted(true)
.setRequiresDeviceIdle(错误)
.build());
}
受保护的void createLocationRequest(){
mlLocationRequest=新位置请求();
mLocationRequest.setInterval(30000);
mlLocationRequest.setFastTestInterval(15000);
M定位请求。设置最小位移(50);
mLocationRequest.setPriority(位置请求.优先级高精度);
LocationSettingsRequest.Builder=新建LocationSettingsRequest.Builder()
.addLocationRequest(MLLocationRequest);
SettingsClient=LocationServices.getSettingsClient(此);
Toast.makeText(这是“创建的位置请求”,Toast.LENGTH_SHORT).show();
Task Task=client.checkLocationSettings(builder.build());
task.addOnSuccessListener(这个,新的OnSuccessListener(){
@凌驾
成功时公共无效(位置设置响应位置设置响应){
//满足所有位置设置。客户端可以初始化
//这里有位置请求。
// ...
bService.setVisibility(View.GONE);
startLocationUpdates();
}
});
task.addOnFailureListener(这是新的OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常e){
int statusCode=((ApiException)e).getStatusCode();
开关(状态代码){
案例CommonStatusCodes.RESOLUTION_要求:
//不满足位置设置,但可以修复此问题
//通过向用户显示一个对话框。
试一试{
//通过调用startResolutionForResult()显示对话框,
//并在onActivityResult()中检查结果。
ResolvableApiException resolvable=(ResolvableApiException)e;
可解析。开始解决结果(main activity.this,
请求检查设置);
}catch(IntentSender.SendIntentException sendEx){
//忽略错误。
}
打破
案例位置设置StatusCodes.SETTINGS\u CHANGE\u不可用:
//位置设置不满意。但是,我们没有办法
//修复设置,使我们不会显示对话框。
打破
}
}
});
}
private void startLocationUpdates(){
mlLocationCallback=新位置Callback(){
@凌驾
public void onLocationResult(LocationResult LocationResult){
Toast.makeText(MainActivity.this,“开始位置更新”,Toast.LENGTH_SHORT.show();
对于(位置:locationResult.getLocations()){
//使用位置数据更新用户界面
// ...
更新标记器(位置);
}
}
;
};
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS\u FINE\u LOCATION)!=PackageManager.permission\u已授予和&ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS\u LOCATION)!=PackageManager.permission\u已授予){
考虑到呼叫
//ActivityCompat#请求权限
//在此处请求缺少的权限,然后覆盖
//public void onRequestPermissionsResult(int-requestCode,字符串[]权限,
//int[]格兰特结果)
//处理用户授予权限的情况。请参阅文档
//对于ActivityCompat,请请求权限以获取更多详细信息。
Toast.makeText(getApplicationContext(),“需要位置权限!!”,Toast.LENGTH\u SHORT.show();
返回;
}
mFusedLocationProviderClient.RequestLocationUpdate(MLLocationRequest,
mLocationCallback,
空/*活套*/);
按钮。设置标签(“f”);
setText(“停止前景跟踪”);
//Toast.makeText(getApplicationContext(),“位置更新已开始”,Toast.LENGTH\u SHORT.show();
}
私有void stopLocationUpdates(){
if(button.getTag().equals(“s”)){
Log.d(“跟踪”,“停止位置更新:从未请求过更新,无操作”);
返回;
}
//当活动处于暂停或暂停状态时,删除位置请求是一种很好的做法
//停止状态。这样做有助于电池性能,尤其是
//建议用于要求频繁更新的应用程序