I'm implementing Google Maps api in which I'm trying to get the initial location at the start at onMapReady().
mCurrentLocation should be the variable that stores the location so I tried to output that in log in onMapReady(), but at the start mCurrentLocation is null, so first I have to request a location. I'm not familiar with the api. I made a guess and put startLocationUpdates(this) in the front.
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.setMyLocationEnabled(true);
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 14.0f));
// Start the update??
startLocationUpdates(this);
// This is where I want to retrieve the location coordinates
Log.w("Location", "Current reading: " + mCurrentLocation.toString());
}
It didn't work. In stack trace it says java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.location.Location.toString()' on a null object reference. I also tried other methods like initLocation() and it didn't work either.
This is rest of the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
initLocations();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case ACCESS_FINE_LOCATION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, null /* Looper */);
}
return;
}
}
}
private void initLocations() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
ACCESS_FINE_LOCATION);
}
return;
}
}
private void startLocationUpdates(Context context) {
Intent intent = new Intent(context, LocationService.class);
mLocationPendingIntent = PendingIntent.getService(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Task<Void> locationTask = mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationPendingIntent);
if (locationTask != null) {
locationTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (e instanceof ApiException) {
Log.w("Main2Activity", ((ApiException) e).getStatusMessage());
} else {
Log.w("Main2Activity", e.getMessage());
}
}
});
locationTask.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d("Main2Activity", "restarting gps successful!");
}
});
}
}
}
private void stopLocationUpdates(){
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
#Override
protected void onResume() {
super.onResume();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
accelerometer.startAccelerometerRecording();
}
private Location mCurrentLocation;
private String mLastUpdateTime;
LocationCallback mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
mCurrentLocation = locationResult.getLastLocation();
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
Log.i("MAP", "new location " + mCurrentLocation.toString());
if (mMap != null)
mMap.addMarker(new MarkerOptions().position(new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()))
.title(mLastUpdateTime));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()), 14.0f));
}
};
What is the proper way to request a location?
I'm always use the LocationManager to get the current location also make sure that your current gps is turned on.
final LocationManager locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// this is where you get the location location.getLatitude(), location.getLongitude()
}
#Override public void onStatusChanged(String provider, int status, Bundle extras) { }
#Override public void onProviderEnabled(String provider) { }
#Override public void onProviderDisabled(String provider) { }
}, null);
You can use this approach :
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tracking_order);
mService = Common.geoCodeService();
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mapFrag = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
public void onMapReady(GoogleMap googleMap)
{
mMap=googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(120000); // two minute interval
mLocationRequest.setFastestInterval(120000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mMap.setMyLocationEnabled(true);
}
}
LocationCallback mLocationCallback = new LocationCallback(){
#Override
public void onLocationResult(LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
Log.i("MapsActivity", "Location: " + location.getLatitude() + " " + location.getLongitude());
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng yourLocation = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(yourLocation);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(yourLocation, 11));
//after add marker for your location add marker for this order
drawRoute(yourLocation,Common.currentRequest.getAddress());
}
}
};
Related
This is the error I'm getting: java.lang. Attempt to call the virtual method 'double android.location.Location.getLatitude()' on a null object reference results in a NullPointerException.Can anyone guide me on how to achieve this?
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks ,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
private ActivityMapsBinding binding;
private static final int MY_PERMISSION_REQUEST_CODE =71922 ;
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 300193;
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;
private Location mLastLocation ;
private static int UPDATE_INTERVAL =5000;
private static int FARTEST_INTERVAL =5000;
private static int DISPLACEMENT =10;
Marker marker;
DatabaseReference ref ;
GeoFire geoFire;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMapsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
ref = FirebaseDatabase.getInstance().getReference("Test");
setupLocation();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case MY_PERMISSION_REQUEST_CODE:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
if(checkPlayServices())
{
buildGoogleApiCLient();
createLocationRequest();
displayLocation();
}
}
break;
}
}
private void setupLocation() {
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED )
{
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, MY_PERMISSION_REQUEST_CODE);
}
else {
if(checkPlayServices())
{
buildGoogleApiCLient();
createLocationRequest();
displayLocation();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void displayLocation() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED )
{
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if(mLastLocation != null)
{
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
Log.d("EDMDEV",String.format("your location was changed: %f %f ",latitude,longitude));
// upDate to firebase
geoFire.setLocation("You", new GeoLocation(latitude, longitude), new GeoFire.CompletionListener() {
#Override
public void onComplete(String key, DatabaseError error) {
if(marker != null){
marker.remove(); //remove old marker
marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude,longitude))
.title("Ele"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longitude),12.0f));
}
}
});
}
else {
Log.d("EDMDEV","cannot get ur location");
}
}
private void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FARTEST_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void buildGoogleApiCLient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS)
{
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode))
GooglePlayServicesUtil.getErrorDialog(resultCode,this,PLAY_SERVICES_RESOLUTION_REQUEST).show();
else {
Toast.makeText(this, "this device is not support", Toast.LENGTH_SHORT).show();
finish();
}
return false ;
}
return true;
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// LatLng syd = new LatLng( -34,151);
// mMap.addMarker(new MarkerOptions().position(syd).title("mar in syd"));
// mMap.moveCamera(CameraUpdateFactory.newLatLng(syd));
//Create area
LatLng village = new LatLng(35.7533,-122.4056);
mMap.addCircle(new CircleOptions()
.center(village)
.radius(500) // in meter
.strokeColor(Color.BLUE)
.fillColor(0x220000FF)
.strokeWidth(5.0f)
);
// 0.5f = 0.5km = 500 m
GeoQuery geoQuery = geoFire .queryAtLocation(new GeoLocation(village.latitude,village.longitude),0.5f);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(String key, GeoLocation location) {
sendNotification("EDKDD",String.format("%s entered village area ",key ));
}
#Override
public void onKeyExited(String key) {
sendNotification("EDKDD",String.format("%s no longer village area ",key ));
}
#Override
public void onKeyMoved(String key, GeoLocation location) {
sendNotification("Move",String.format("%s moved within the village area [%f/%f]",key,location.latitude, location.longitude ));
}
#Override
public void onGeoQueryReady() {
}
#Override
public void onGeoQueryError(DatabaseError error) {
Log.e("Error","" + error);// 36.46
}
});
}
private void sendNotification(String title, String content) {
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(title)
.setContentText(content);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this,MapsActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_IMMUTABLE);
builder.setContentIntent(contentIntent);
Notification notification = builder.build();
notification.flags = Notification.DEFAULT_SOUND;
notificationManager.notify(new Random().nextInt(),notification);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
displayLocation();
startLocationUpdate();
}
private void startLocationUpdate() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED )
{
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,locationRequest,this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
displayLocation();
}
}
java.lang.NullPointerException Error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.newapp.elephantapplication, PID: 3267
java.lang.NullPointerException: Attempt to invoke virtual method 'com.firebase.geofire.GeoQuery com.firebase.geofire.GeoFire.queryAtLocation(com.firebase.geofire.GeoLocation, double)' on a null object reference
at com.newapp.elephantapplication.MapsActivity.onMapReady(MapsActivity.java:224)
at com.google.android.gms.maps.zzat.zzb(com.google.android.gms:play-services-maps##18.0.0:1)
at com.google.android.gms.maps.internal.zzaq.zza(com.google.android.gms:play-services-maps##18.0.0:5)
at com.google.android.gms.internal.maps.zzb.onTransact(com.google.android.gms:play-services-maps##18.0.0:3)
at android.os.Binder.transact(Binder.java:387)
at eg.aZ(:com.google.android.gms.dynamite_mapsdynamite#220920047#22.09.20 (040308-0):2)
at com.google.maps.api.android.lib6.impl.bk.run(:com.google.android.gms.dynamite_mapsdynamite#220920047#22.09.20 (040308-0):1)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Just getting used to Java and Android and I've got the above error.
Can anyone guide me on how to achieve this?
Am trying to set up an app that would notify the user when his/her location is with in the polygon.
I have read about using polyutils library but have not been successful in implementing them.
Here is what i Tried
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
mMap.setMapType(mMap.MAP_TYPE_SATELLITE);
mMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(48.146536, 16.291830)));
mMap.animateCamera(CameraUpdateFactory.zoomTo(18));
DrawPolygon();
// Log.i(TAG, "onLocationChanged: location" + latLng);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this, null);
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
}
private void DrawPolygon() {
mPolygon1 = mMap.addPolygon(new PolygonOptions()
.strokeColor(COLOR_PURPLE_ARGB)
.add(
new LatLng(48.146536, 16.291830),
new LatLng(48.146772, 16.290146),
new LatLng(48.147397, 16.290380),
new LatLng(48.147177, 16.291970)));
// Store a data object with the polygon, used here to indicate an arbitrary type.
mPolygon1.setTag("alpha");
// Style the polygon.
// stylePolygon(polygon1);
mPolygon2 = mMap.addPolygon(new PolygonOptions()
.strokeColor(COLOR_BLUE_ARGB)
.add(
new LatLng(48.146491, 16.290989),
new LatLng(48.146265, 16.290898),
new LatLng(48.146171, 16.291819),
new LatLng(48.146359, 16.291870)));
mPolygon2.setTag("beta");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
for (Polygon polgon : getPolygons()) {
if (PolyUtil.containsLocation(latLng, polgon.getPoints(), true)) {
// found it open a info window
Log.i(LOG_TAG, "Your Currently in : " + polgon);
return;
}
}
}
public Collection<Polygon> getPolygons() {
Collection<Polygon> polygons = new ArrayList<Polygon>();
((ArrayList<Polygon>) polygons).add(1, mPolygon1);
((ArrayList<Polygon>) polygons).add(2, mPolygon2);
return polygons;
}
When i run the app the IDE throws an error pointing at the lines indexoutofBounds Exception and the app does not run.
I'm new creating apps and I want to show a drawn route in a Google Map starting from the current location. I've just found how to get the current location, but now I'm stuck in the second part, which is drawing the route from the current location to another marker point.
Here is my code:
`public class Trazo_Rutas extends FragmentActivity implements
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
GoogleApiClient googleApiClient;
LocationRequest locationRequest;
Location lastLocation;
Marker userLocation;
private static final int Request_User_Location_Code = 99;
PlaceAutocompleteFragment placeAutoComplete;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trazo__rutas);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkUserLocationPermission();
}
//Check if Google Play Services Available or not
if (!CheckGooglePlayServices()) {
Log.d("onCreate", "Finishing test case since Google Play Services are not available");
finish();
}
else {
Log.d("onCreate","Google Play Services available.");
}
//AutoComplete search bar
placeAutoComplete = (PlaceAutocompleteFragment) getFragmentManager().findFragmentById(R.id.place_autocomplete);
placeAutoComplete.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
Log.d("Maps", "Place selected: " + place.getName());
}
#Override
public void onError(Status status) {
Log.d("Maps", "An error occurred: " + status);
}
});
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
private boolean CheckGooglePlayServices() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if(result != ConnectionResult.SUCCESS) {
if(googleAPI.isUserResolvableError(result)) {
googleAPI.getErrorDialog(this, result,
0).show();
}
return false;
}
return true;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
//get latlong for corners for specified place
LatLng corner1 = new LatLng(25.64379, -103.60966);
LatLng corner2 = new LatLng(25.64317, -103.20935);
LatLng corner3 = new LatLng(25.43872, -103.61104);
LatLng corner4 = new LatLng(25.43748, -103.20866);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(corner1);
builder.include(corner2);
builder.include(corner3);
builder.include(corner4);
LatLngBounds bounds = builder.build();
//add them to builder
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
// 20% padding
int padding = (int) (width * 0.20);
//set latlng bounds
mMap.setLatLngBoundsForCameraTarget(bounds);
//move camera to fill the bound to screen
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding));
//set zoom to level to current so that you won't be able to zoom out viz. move outside bounds
mMap.setMinZoomPreference(mMap.getCameraPosition().zoom);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
public boolean checkUserLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)){
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION
}, Request_User_Location_Code);
} else {
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION
}, Request_User_Location_Code);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case Request_User_Location_Code:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (googleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
Toast.makeText(this, "Se requieren Permisos de Google", Toast.LENGTH_SHORT).show();
finish();
}
return;
}
}
protected synchronized void buildGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
lastLocation = location;
if (userLocation != null) {
userLocation.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.draggable(true);
markerOptions.title("Tu ubicaciĆ³n");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
userLocation = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
if (googleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1100);
locationRequest.setFastestInterval(1100);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}`
My concern is that I don't know how to implement the other marker and draw the route.
Thank you.
I have added a Support Place Autocomplete fragment inside a Map Fragment, and it does not seem to work properly for some reason. Whenever I search for a place, the map moves to the correct location for a split second, and automatically returns back to the user's current location for some reason.
This is the code of my map fragment:
public class MyMapFragment extends SupportMapFragment
implements OnMapReadyCallback {
GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
FusedLocationProviderClient mFusedLocationClient;
PlaceAutocompleteFragment mPlaceAutocompleteFragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.fragment_map,
container, false);
View v = super.onCreateView(inflater, container, savedInstanceState);
layout.addView(v, 0);
getChildFragmentManager().beginTransaction()
.replace(R.id.place_autocomplete, new SupportPlaceAutocompleteFragment())
.addToBackStack(SupportPlaceAutocompleteFragment.class.getName())
.commit();
mFusedLocationClient =
LocationServices.getFusedLocationProviderClient(getContext());
return layout;
}
#Override
public void onAttachFragment(Fragment childFragment) {
super.onAttachFragment(childFragment);
if (childFragment instanceof SupportPlaceAutocompleteFragment) {
((SupportPlaceAutocompleteFragment) childFragment).setOnPlaceSelectedListener(
new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
LatLng latLng = place.getLatLng();
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 12));
}
#Override
public void onError(Status status) {
}
});
}
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
mapFrag = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map));
mapFrag.getMapAsync(this);
}
private void setUpMapIfNeeded() {
if (mGoogleMap == null) {
getMapAsync(this);
}
}
#Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
}
#SuppressLint("RestrictedApi")
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setPadding(0,200, 0,0);
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(120000); // two minute interval
mLocationRequest.setFastestInterval(120000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mGoogleMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mGoogleMap.setMyLocationEnabled(true);
}
}
LocationCallback mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
List<Location> locationList = locationResult.getLocations();
if (locationList.size() > 0) {
//The last location in the list is the newest
Location location = locationList.get(locationList.size() - 1);
Log.i("MapsActivity", "Location: " + location.getLatitude() + " " + location.getLongitude());
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
//move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 12));
}
}
};
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new android.app.AlertDialog.Builder(getActivity())
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mGoogleMap.setMyLocationEnabled(true);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
Which methods do I have to include to my code to pass the data to list view?
I want to show the nearby places using ListView. It only show the nearby places on the map by clicking the buttons as shown below. When I click the "Nearby School" button it displays the nearby school on the map, now I want it to display the nearby schools using listview. How can I do that?
public class MapsActivity extends FragmentActivity implements com.google.android.gms.location.LocationListener, OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleMap mMap;
double latitude;
double longitude;
private int PROXIMITY_RADIUS = 10000;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
ListView lvMap;
ArrayList<HashMap<String, String>> placesListItems = new ArrayList<HashMap<String,String>>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
//Check if Google Play Services Available or not
if (!CheckGooglePlayServices()) {
Log.d("onCreate", "Finishing test case since Google Play Services are not available");
finish();
}
else {
Log.d("onCreate","Google Play Services available.");
}
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.maps);
mapFragment.getMapAsync(this);
}
private boolean CheckGooglePlayServices() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if(result != ConnectionResult.SUCCESS) {
if(googleAPI.isUserResolvableError(result)) {
googleAPI.getErrorDialog(this, result,
0).show();
}
return false;
}
return true;
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
Button btnRestaurant = (Button) findViewById(R.id.btnRestaurant);
btnRestaurant.setOnClickListener(new View.OnClickListener() {
String Restaurant = "restaurant";
#Override
public void onClick(View v) {
Log.d("onClick", "Button is Clicked");
mMap.clear();
String url = getUrl(latitude, longitude, Restaurant);
Object[] DataTransfer = new Object[2];
DataTransfer[0] = mMap;
DataTransfer[1] = url;
Log.d("onClick", url);
GetNearbyPlacesData getNearbyPlacesData = new GetNearbyPlacesData();
getNearbyPlacesData.execute(DataTransfer);
Toast.makeText(MapsActivity.this,"Nearby Restaurants", Toast.LENGTH_LONG).show();
}
});
Button btnHospital = (Button) findViewById(R.id.btnHospital);
btnHospital.setOnClickListener(new View.OnClickListener() {
String Hospital = "hospital";
#Override
public void onClick(View v) {
Log.d("onClick", "Button is Clicked");
mMap.clear();
String url = getUrl(latitude, longitude, Hospital);
Object[] DataTransfer = new Object[2];
DataTransfer[0] = mMap;
DataTransfer[1] = url;
Log.d("onClick", url);
GetNearbyPlacesData getNearbyPlacesData = new GetNearbyPlacesData();
getNearbyPlacesData.execute(DataTransfer);
Toast.makeText(MapsActivity.this,"Nearby Hospitals", Toast.LENGTH_LONG).show();
}
});
Button btnSchool = (Button) findViewById(R.id.btnSchool);
btnSchool.setOnClickListener(new View.OnClickListener() {
String School = "school";
#Override
public void onClick(View v) {
Log.d("onClick", "Button is Clicked");
mMap.clear();
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
String url = getUrl(latitude, longitude, School);
Object[] DataTransfer = new Object[2];
DataTransfer[0] = mMap;
DataTransfer[1] = url;
Log.d("onClick", url);
GetNearbyPlacesData getNearbyPlacesData = new GetNearbyPlacesData();
getNearbyPlacesData.execute(DataTransfer);
Toast.makeText(MapsActivity.this,"Nearby Schools", Toast.LENGTH_LONG).show();
}
});
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
private String getUrl(double latitude, double longitude, String nearbyPlace) {
StringBuilder googlePlacesUrl = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
googlePlacesUrl.append("location=" + latitude + "," + longitude);
googlePlacesUrl.append("&radius=" + PROXIMITY_RADIUS);
googlePlacesUrl.append("&type=" + nearbyPlace);
googlePlacesUrl.append("&sensor=true");
googlePlacesUrl.append("&key=" + "AIzaSyATuUiZUkEc_UgHuqsBJa1oqaODI-3mLs0");
Log.d("getUrl", googlePlacesUrl.toString());
return (googlePlacesUrl.toString());
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
Log.d("onLocationChanged", "entered");
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
latitude = location.getLatitude();
longitude = location.getLongitude();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
Toast.makeText(MapsActivity.this,"Your Current Location", Toast.LENGTH_LONG).show();
Log.d("onLocationChanged", String.format("latitude:%.3f longitude:%.3f",latitude,longitude));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
Log.d("onLocationChanged", "Removing Location Updates");
}
Log.d("onLocationChanged", "Exit");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
// contacts-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other permissions this app might request.
// You can add here other case statements according to your requirement.
}
}
}