Antony  Prudyus Antony Prudyus - 1 month ago 8
Android Question

My simple program shows my location, but doesn't show the polyline to the location selected in spinner

My simple program should show my location and draw a polyline to the location selected in spinner. It currently shows only my location, but I don't know why. Maybe the problem is with permissions introduced in Android Marshmallow.
Here is my code:

public class MapsActivity extends FragmentActivity {

private final LatLng MainHousing = new LatLng(49.83511, 24.01446);
private final LatLng FirstHousing = new LatLng(49.83533, 24.01004);
private final LatLng FifthHousing = new LatLng(49.835, 24.00824);
private static final int REQUEST_LOCATION = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
GoogleMap googleMap;
Location location;
LatLng myPosition;
Spinner spinner;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
List<String> list = new ArrayList<>();
list.add("Головний корпус");
list.add("I корпус");
list.add("V корпус");

spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(dataAdapter);

showMyLocation();
}


private void showMyLocation() {
// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment fm = (SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.map);

// Getting GoogleMap object from the fragment
googleMap = fm.getMap();

// Enabling MyLocation Layer of Google Map
googleMap.setMyLocationEnabled(true);

// Getting LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();

// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
PERMISSIONS_STORAGE, REQUEST_LOCATION);
}

location = locationManager.getLastKnownLocation(provider);

if (location != null) {
// Getting latitude of the current location
double latitude = location.getLatitude();

// Getting longitude of the current location
double longitude = location.getLongitude();

// Creating a LatLng object for the current location
LatLng latLng = new LatLng(latitude, longitude);

myPosition = new LatLng(latitude, longitude);

googleMap.addMarker(new MarkerOptions().position(myPosition).title("Start"));

final PolylineOptions pOptions = new PolylineOptions();

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (spinner.getSelectedItemPosition()) {
case 0:
pOptions.add(myPosition).add(MainHousing).width(5).color(Color.BLUE).geodesic(true);
googleMap.addPolyline(pOptions);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MainHousing, 13));
break;
case 1:
pOptions.add(myPosition).add(FirstHousing).width(5).color(Color.BLUE).geodesic(true);
googleMap.addPolyline(pOptions);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(FirstHousing, 13));
break;
case 2:
pOptions.add(myPosition).add(FifthHousing).width(5).color(Color.BLUE).geodesic(true);
googleMap.addPolyline(pOptions);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(FifthHousing, 13));
break;
}
}

@Override
public void onNothingSelected(AdapterView<?> parent) {

}
});
}
}


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case REQUEST_LOCATION:
if (grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
} else {
// Permission Denied
Toast.makeText(MapsActivity.this, "LOCATION Denied", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}


So, what is my problem? It can be a stupid one, because I'm new to android. Thanks in advance.

Answer

First of all you need to implement OnMapReady interface, as well as ConnectionCallbacks, because it takes some time to load maps and move your logic into the onConnected() method, where you going to ask user for his location and setup your spinner with polylines.

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.*;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.*;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;

import java.util.ArrayList;
import java.util.List;

public class MapsActivity extends FragmentActivity
    implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private final LatLng MainHousing = new LatLng(49.83511, 24.01446);
    private final LatLng FirstHousing = new LatLng(49.83533, 24.01004);
    private final LatLng FifthHousing = new LatLng(49.835, 24.00824);
    private static final int REQUEST_LOCATION = 1;

    GoogleMap googleMap;
    LatLng myPosition;
    Spinner spinner;
    PolylineOptions pOptions;
    Marker currLocationMarker;
    SupportMapFragment mFragment;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        List<String> list = new ArrayList<>();
        list.add("Головний корпус");
        list.add("I корпус");
        list.add("V корпус");

        spinner = (Spinner) findViewById(R.id.spinner);
        pOptions = new PolylineOptions();

        ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(this,
            android.R.layout.simple_spinner_item, list);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(dataAdapter);

        mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mFragment.getMapAsync(this);

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
        switch (requestCode) {
            case REQUEST_LOCATION:
                if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted
                    Toast.makeText(SOMapsActivity.this, "LOCATION Accepted", Toast.LENGTH_SHORT)
                        .show();
                } else {
                // Permission Denied
                    Toast.makeText(SOMapsActivity.this, "LOCATION Denied", Toast.LENGTH_SHORT)
                        .show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        this.googleMap = googleMap;
        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
            ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
            ) {

            ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                REQUEST_LOCATION);
        }

        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
        if (mLastLocation != null) {

            myPosition = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(myPosition);
            markerOptions.title("Current Position");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
            currLocationMarker = googleMap.addMarker(markerOptions);
        }

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000); //5 seconds
        mLocationRequest.setFastestInterval(3000); //3 seconds
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    //mLocationRequest.setSmallestDisplacement(0.1F); //1/10 meter

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                switch (spinner.getSelectedItemPosition()) {
                    case 0:
                        pOptions.add(myPosition).add(MainHousing).width(5).color(Color.BLUE).geodesic(true);
                        googleMap.addPolyline(pOptions);
                        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MainHousing, 17));
                        break;
                    case 1:
                        pOptions.add(myPosition).add(FirstHousing).width(5).color(Color.BLUE).geodesic(true);
                        googleMap.addPolyline(pOptions);
                        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(FirstHousing, 17));
                        break;
                    case 2:
                        pOptions.add(myPosition).add(FifthHousing).width(5).color(Color.BLUE).geodesic(true);
                        googleMap.addPolyline(pOptions);
                            googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(FifthHousing, 17));
                        break;
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                }
            });
        }
//......
}

P.s. this code works, but it could be improved, so make sure to spend some time to analyze it and modify to your own purposes.

P.p.s. in this sample poly lines are not removed, so you might also write some code that remove them.

Cheers.

Comments