简体   繁体   中英

Adding markers to Google Map - Android (JAVA)

I'm trying to build an app where it retrieves the longitude and latitude from the Real time database using Firebase. After retrieving the location saved in the database, I want to add a marker which shows the air quality index (AQI). I tried to implement this, but there is no markers on the map and there's no errors in the code. (It shows the map without markers)

This is how the data in my database look like:

my real time database using firebase

This is my java code:

 public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener,GoogleMap.OnMarkerClickListener  {

private final String TAG = "TAG";
private static final int REQUEST_ACCESS_FINE_LOCATION = 13112;
private static final int REQUEST_CHECK_SETTINGS = 13119;

private boolean mLocationPermissionGranted;
private SupportMapFragment mSupportMapFragment;
private GoogleMap mGoogleMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
private LocationRequest mLocationRequest;
private LocationCallback mLocationCallback;
private boolean mFirstRender = true;

private GoogleMap mMap;
private Marker mMarker;
private ChildEventListener mChildEventListener;
private DatabaseReference mUsers;



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

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    if (mapFragment != null) {
        mapFragment.getMapAsync(this);
    } else {
        Toast.makeText(getApplicationContext(), "mapFragment != null", Toast.LENGTH_LONG).show();
    }
    ChildEventListener mChildEventListener;
    mUsers= FirebaseDatabase.getInstance().getReference("airvisual-e9c40");
    mUsers.push().setValue(mMarker);

    Window window = getWindow();
    window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);


    mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    mSupportMapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {

            if (locationResult == null) {
                return;
            }

            if (mMarker != null) {
                mMarker.remove();
            }

            for (final Location location : locationResult.getLocations()) {
                final LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                mMarker = mGoogleMap.addMarker(new MarkerOptions().position(latLng)
                        .title("Lahore"));

               // mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(mMarkerBitmap));

                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17.0f);

                if (mFirstRender) {
                    mGoogleMap.animateCamera(cameraUpdate);
                    mFirstRender = false;
                }
            }
        }

        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            super.onLocationAvailability(locationAvailability);
        }
    };

    getPermissions();

}


/**
 * 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.
 */

@SuppressLint("MissingPermission")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
    switch (requestCode) {
        case REQUEST_CHECK_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // All required changes were successfully made
                    if (mLocationPermissionGranted) {
                        mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
                                mLocationCallback, null);
                    }
                    break;
                case Activity.RESULT_CANCELED:
                    // The user was asked to change settings, but chose not to
                    new AlertDialog.Builder(MapsActivity.this)
                            .setTitle("Need Location")
                            .setMessage("Hi there! We can't show your current location without the" +
                                    " location service, could you please enable it?")
                            .setPositiveButton("Yep", new DialogInterface.OnClickListener() {
                                @RequiresApi(api = Build.VERSION_CODES.M)
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    checkLocationAvailability();
                                }
                            })
                            .setNegativeButton("No thanks", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    Toast.makeText(getApplicationContext(), ":(", Toast.LENGTH_LONG).show();
                                    finish();
                                }
                            }).show();
                    break;
                default:
                    break;
            }
            break;
    }
}

@Override
public void onRequestPermissionsResult(
        int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_ACCESS_FINE_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay! Do what you want . . .
                mLocationPermissionGranted = true;
                mSupportMapFragment.getMapAsync(this);
            } else {
                // permission denied, boo! :(
                // Show an explanation to the user why this permission is required
                displayDialog();
            }

            return;
        }
    }
}

@SuppressLint("MissingPermission")
@Override
public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;

    googleMap.setOnMarkerClickListener(this);
    googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

    messLocation();
}

private void messLocation() {

    DatabaseReference currentDBcordinates = FirebaseDatabase.getInstance().getReference().child("airvisual-e9c40");

    currentDBcordinates.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            //Create an array of markers
            int size = (int) dataSnapshot.getChildrenCount();
            Marker[] allMarkers = new Marker[size];
            mMap.clear();   //Assuming you're using mMap
            for(DataSnapshot s : dataSnapshot.getChildren()) {
                //Specify your model class here
                AQIModel cordinatesModel = new AQIModel();
                //lets create a loop
                for(int i=0;i<=size;i++) {
                    try {
                        Toast.makeText(getApplicationContext(), i, Toast.LENGTH_LONG).show();
                        //assuming you've set your getters and setters in the Model class
                        cordinatesModel.setLatitude(s.getValue(AQIModel.class).getLatitude());
                        cordinatesModel.setLongitude(s.getValue(AQIModel.class).getLongitude());
                        cordinatesModel.setAqi(s.getValue(AQIModel.class).getAqi());
                        //lets retrieve the coordinates and other information
                        Double latitude1 = cordinatesModel.getLatitude();
                        Double longitude1 = cordinatesModel.getLongitude();
                        String brandName=String.valueOf(cordinatesModel.getAqi());
                        //convert the coordinates to LatLng
                        LatLng latLng = new LatLng(latitude1, longitude1);
                        mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                        //Now lets add updated markers

                        //lets add updated marker
                        allMarkers[i] = mMap.addMarker(new MarkerOptions()
                                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)).position(latLng).title(brandName));
                    }catch (Exception ex){}
                }


            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private void checkLocationAvailability() {
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
    builder.addLocationRequest(mLocationRequest);

    SettingsClient settingsClient = LocationServices.getSettingsClient(this);
    Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(builder.build());
    task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {

        @SuppressLint("MissingPermission")
        @Override
        public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
            try {
                LocationSettingsResponse response = task.getResult(ApiException.class);
                // All location settings are satisfied.
                if (mLocationPermissionGranted) {
                    mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
                            mLocationCallback, null);
                }

            } catch (ApiException exception) {
                switch (exception.getStatusCode()) {
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the
                        // user a dialog.
                        try {
                            // Cast to a resolvable exception.
                            ResolvableApiException resolvable = (ResolvableApiException) exception;
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            resolvable.startResolutionForResult(
                                    MapsActivity.this,
                                    REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        } catch (ClassCastException e) {
                            // Ignore, should be an impossible 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 getPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

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

            // Permission is not granted
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {

                // Show an explanation to the user why this permission is required
                displayDialog();
            } else {
                // No explanation needed; request the permission
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        REQUEST_ACCESS_FINE_LOCATION);
            }
        } else {
            // Permission has already been granted
            mLocationPermissionGranted = true;
            mSupportMapFragment.getMapAsync(this);
        }
    } else {
        // Android SDK Version is below Marshmallow.
        // You don't need runtime permission, Do what you want . . .
        mLocationPermissionGranted = true;
        mSupportMapFragment.getMapAsync(this);
    }
}


private void displayDialog() {
    new AlertDialog.Builder(MapsActivity.this)
            .setTitle("Location Permission")
            .setMessage("Hi there! We can't show your current location without the" +
                    " location permission, could you please grant it?")
            .setPositiveButton("Yep", new DialogInterface.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    requestPermissions(new String[]{
                                    Manifest.permission.ACCESS_FINE_LOCATION},
                            REQUEST_ACCESS_FINE_LOCATION);
                }
            })
            .setNegativeButton("No thanks", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    Toast.makeText(getApplicationContext(), ":(", Toast.LENGTH_LONG).show();
                    finish();
                }
            }).show();
}

@Override
public void onLocationChanged(Location location) {

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}

@Override
public boolean onMarkerClick(Marker marker) {
    return false;
}
 }

I am looking for something like this:

Expectations

Put Below code in OnMapReady method.

ChildEventListener mChildEventListener;
    mUsers= FirebaseDatabase.getInstance().getReference("airvisual-e9c40");
    mUsers.push().setValue(mMarker);

    Window window = getWindow();
    window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);


    mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    mSupportMapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {

            if (locationResult == null) {
                return;
            }

            if (mMarker != null) {
                mMarker.remove();
            }

            for (final Location location : locationResult.getLocations()) {
                final LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                mMarker = mGoogleMap.addMarker(new MarkerOptions().position(latLng)
                        .title("Lahore"));

               // mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(mMarkerBitmap));

                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17.0f);

                if (mFirstRender) {
                    mGoogleMap.animateCamera(cameraUpdate);
                    mFirstRender = false;
                }
            }
        }

        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            super.onLocationAvailability(locationAvailability);
        }
    };

    getPermissions();

Write all the logic in onMapReady method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM