I'm quite new in Android and I need a help. I'm developing an app like Runkeeper, Nike Running Club etc. So I want to know how to add line which shows route you passed on Google Map.Like that. I have already tried many methods from here, here and here , but I can't understand them. I know that I have to use onLocationChanged drawpolyline, but I don't know how and I can't find anywhere explanation of it.
Here is how I was trying to do it, but it always crashes
GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
TextView textAutoUpdateLocation;
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COARSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private Boolean mLocationPermissionGranted = false;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
private GoogleMap mMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
private static final float DEFAULT_ZOOM = 15f;
private PolylineOptions polylineOptions;
private ArrayList<LatLng> arrayPoints;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textAutoUpdateLocation = (TextView) findViewById(R.id.autoupdatelocation);
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
getLocationPermission();
}
private void initMap() {
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync((OnMapReadyCallback) this);
}
private void getDeviceLocation() {
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
try {
if (mLocationPermissionGranted) {
final Task location = mFusedLocationProviderClient.getLastLocation();
location.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
Location currentLocation = (Location) task.getResult();
moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()), DEFAULT_ZOOM);
} else {
}
}
});
}
} catch (SecurityException e) {
}
}
private void moveCamera(LatLng latLng, float zoom) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (mLocationPermissionGranted) {
getDeviceLocation();
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;
}
mMap.setMyLocationEnabled(true);
}
this.init();
}
private void init() {
String coordinates[] = { "37.517180", "127.041268" };
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
LatLng position = new LatLng(lat, lng);
GooglePlayServicesUtil.isGooglePlayServicesAvailable(
MainActivity.this);
// 맵 위치이동.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(position, 15));
}
private void getLocationPermission() {
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
if (ContextCompat.checkSelfPermission(this.getApplicationContext(), FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(), COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
initMap();
} else {
ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE);
}
} else {
ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE);
}
}
public void RequestPermissionResult(int requestCode, @NonNull String[]permissions, @NonNull int[]grantResults) {
switch (requestCode){
case LOCATION_PERMISSION_REQUEST_CODE:{
if (grantResults.length > 0) {
for (int i = 0; i<grantResults.length;i++){
if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
mLocationPermissionGranted=false;
return;
}
}
mLocationPermissionGranted=true;
initMap();
}
}
}
}
@Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
@Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions marker = new MarkerOptions();
marker.position(latLng);
mMap.addMarker(marker);
polylineOptions = new PolylineOptions();
polylineOptions.color(Color.RED);
polylineOptions.width(5);
arrayPoints.add(latLng);
polylineOptions.addAll(arrayPoints);
mMap.addPolyline(polylineOptions);
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
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.
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Toast.makeText(MainActivity.this,
"onConnectionFailed: \n" + connectionResult.toString(),
Toast.LENGTH_LONG).show();
}
}
Please help and explain it to me. Thanks beforehand.
LOGCAT 08-03 13:51:02.605 20065-20065/? E/Zygote: isWhitelistProcess - Process is Whitelisted 08-03 13:51:03.125 20065-20065/com.mcarrow.myapplication E/zygote64: The String#value field is not present on Android versions >= 6.0 08-03 13:51:03.810 20065-20065/com.mcarrow.myapplication E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mcarrow.myapplication, PID: 20065 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object reference at com.mcarrow.myapplication.MainActivity.onLocationChanged(MainActivity.java:209) at com.google.android.gms.internal.location.zzay.notifyListener(Unknown Source:4) at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:8) at com.google.android.gms.common.api.internal.ListenerHolder$zza.handleMessage(Unknown Source:16) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6938) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
You have NOT initialized
arrayPoints
. In your code, changearrayPoints
declaration to this