我是Android开发的新手,目前正在尝试构建汽车追踪应用。汽车标记位于当前位置,随着我移动,它将与折线一起移动。我已经实现了所有内容,但折线并未在标记后面画线,在我出错时需要一些建议。预先谢谢你!
public class Map extends FragmentActivity implements OnMapReadyCallback,
GoogleMap.OnInfoWindowClickListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private static final int REQUEST_LOCATION = 0;
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
private LocationRequest mLocationRequest;
private static final String TAG = "";
private GoogleMap mMap;
private int markerCount;
TextView locationText;
String lat, longi, address1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map17);
locationText = (TextView) findViewById(R.id.locationText);
markerCount = 0;
//Check If Google Services Is Available
if (getServicesAvailable()) {
// Building the GoogleApi client
buildGoogleApiClient();
createLocationRequest();
Toast.makeText(this, "Google Service Is Available!!", Toast.LENGTH_SHORT).show();
}
//Create The MapView Fragment
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
startTrackerService();
}
private void startTrackerService() {
startService(new Intent(this, TrackerService.class));
}
/**
* GOOGLE MAPS AND MAPS OBJECTS
*/
// After Creating the Map Set Initial Location
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
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.
return;
}
//Uncomment To Show Google Location Blue Pointer
// mMap.setMyLocationEnabled(true);
}
Marker mk = null;
// Add A Map Pointer To The MAp
public void addMarker(GoogleMap googleMap, double lat, double lon) {
if (markerCount == 1) {
animateMarker(mLastLocation, mk);
} else if (markerCount == 0) {
//Set Custom BitMap for Pointer
int height = 80;
int width = 45;
BitmapDrawable bitmapdraw = (BitmapDrawable) getResources().getDrawable(R.mipmap.icon_car);
Bitmap b = bitmapdraw.getBitmap();
Bitmap smallMarker = Bitmap.createScaledBitmap(b, width, height, false);
mMap = googleMap;
LatLng latlong = new LatLng(lat, lon);
mk = mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lon))
//.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin3))
.icon(BitmapDescriptorFactory.fromBitmap((smallMarker))));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlong, 16));
//Set Marker Count to 1 after first marker is created
markerCount = 1;
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
return;
}
//mMap.setMyLocationEnabled(true);
startLocationUpdates();
}
}
@Override
public void onInfoWindowClick(Marker marker) {
Toast.makeText(this, marker.getTitle(), Toast.LENGTH_LONG).show();
}
public boolean getServicesAvailable() {
GoogleApiAvailability api = GoogleApiAvailability.getInstance();
int isAvailable = api.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
} else if (api.isUserResolvableError(isAvailable)) {
Dialog dialog = api.getErrorDialog(this, isAvailable, 0);
dialog.show();
} else {
Toast.makeText(this, "Cannot Connect To Play Services", Toast.LENGTH_SHORT).show();
}
return false;
}
/**
* LOCATION LISTENER EVENTS
*/
@Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
// startLocationUpdates();
}
@Override
protected void onResume() {
super.onResume();
getServicesAvailable();
// Resuming the periodic location updates
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
@Override
protected void onPause() {
super.onPause();
}
//Method to display the location on UI
private void displayLocation() {
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
// Check Permissions Now
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
} else {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
String location = String.valueOf(mLastLocation);
Log.d("lat:", location);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
String loc = "" + latitude + " ," + longitude + " ";
Toast.makeText(this, loc, Toast.LENGTH_SHORT).show();
Constants.lat1 = String.valueOf(latitude);
Constants.lat2 = String.valueOf(longitude);
Log.d("lat:", lat1);
Log.d("lat:", lat2);
//Add pointer to the map at location
addMarker(mMap, latitude, longitude);
try {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude(), 1);
locationText.setText(locationText.getText() + "\n" + addresses.get(0).getAddressLine(0) + ", " +
addresses.get(0).getAddressLine(1) + ", " + addresses.get(0).getAddressLine(2));
address1 = String.valueOf(addresses.get(0).getAddressLine(0) + ", " +
addresses.get(0).getAddressLine(1) + ", " + addresses.get(0).getAddressLine(2));
Constants.address1 = address1;
Log.d("lat:", address1);
/* lat = String.valueOf(mLastLocation.getLatitude());
longi = String.valueOf(mLastLocation.getLongitude());
Log.d("lat:",lat);
Log.d("lat:","true1");
Log.d("longi:", longi);
Log.d("lat:","true2");
Constants.lattitude = lat;
Log.d("lat:",Constants.lattitude);
Log.d("lat:","true3");
Constants.longitude = longi;
Log.d("longi:", Constants.longitude);
Log.d("lat:","true4");
*/
} catch (Exception e) {
}
new ReplyAsync(getApplicationContext(), new ReplyAsync.getReplyAsyncCallback() {
@Override
public void onStart(boolean status) {
Log.e("Result true", "Result true................");
// progressDialog = new ProgressDialog(getApplicationContext());
// progressDialog.setTitle(Constants.company_name);
// progressDialog.setMessage(Constants.loadingMessage);
// progressDialog.show();
}
@Override
public void onResult(boolean result) {
if (result) {
Toast.makeText(Map.this, "Entered Successfully", Toast.LENGTH_SHORT).show();
Log.e("Result true", "Result true");
}
}
}).execute(Constants.latlonginsertlink);
} else {
Toast.makeText(this, "Couldn't get the location. Make sure location is enabled on the device",
Toast.LENGTH_SHORT).show();
}
}
}
// Creating google api client object
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
//Creating location request object
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(AppConstants.UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(AppConstants.FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(AppConstants.DISPLACEMENT);
}
//Starting the location updates
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
//Stopping location updates
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
/**
* Google api callback methods
*/
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
@Override
public void onConnected(Bundle arg0) {
// Once connected with google api, get the location
displayLocation();
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
@Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
public void onLocationChanged(Location location) {
// Assign the new location
mLastLocation = location;
Toast.makeText(getApplicationContext(), "Location changed!",
Toast.LENGTH_SHORT).show();
// Displaying the new location on UI
displayLocation();
}
public static void animateMarker(final Location destination, final Marker marker) {
if (marker != null) {
final LatLng startPosition = marker.getPosition();
final LatLng endPosition = new LatLng(destination.getLatitude(), destination.getLongitude());
final float startRotation = marker.getRotation();
final LatLngInterpolator latLngInterpolator = new LatLngInterpolator.LinearFixed();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(1000); // duration 1 second
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
try {
float v = animation.getAnimatedFraction();
LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, endPosition);
marker.setPosition(newPosition);
marker.setRotation(computeRotation(v, startRotation, destination.getBearing()));
} catch (Exception ex) {
// I don't care atm..
}
}
});
valueAnimator.start();
}
}
private static float computeRotation(float fraction, float start, float end) {
float normalizeEnd = end - start; // rotate start to 0
float normalizedEndAbs = (normalizeEnd + 360) % 360;
float direction = (normalizedEndAbs > 180) ? -1 : 1; // -1 = anticlockwise, 1 = clockwise
float rotation;
if (direction > 0) {
rotation = normalizedEndAbs;
} else {
rotation = normalizedEndAbs - 360;
}
float result = fraction * rotation + start;
return (result + 360) % 360;
}
private interface LatLngInterpolator {
LatLng interpolate(float fraction, LatLng a, LatLng b);
class LinearFixed implements LatLngInterpolator {
@Override
public LatLng interpolate(float fraction, LatLng a, LatLng b) {
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);
}
}
}
}