从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(“跟踪”,“停止位置更新:从未请求过更新,无操作”);
返回;
}
//当活动处于暂停或暂停状态时,删除位置请求是一种很好的做法
//停止状态。这样做有助于电池性能,尤其是
//建议用于要求频繁更新的应用程序