简体   繁体   English

向Google地图添加标记 - Android(JAVA)

[英]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. 我正在尝试构建一个应用程序,它使用Firebase从实时数据库中检索经度和纬度。 After retrieving the location saved in the database, I want to add a marker which shows the air quality index (AQI). 检索保存在数据库中的位置后,我想添加一个显示空气质量指数(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 我的实时数据库使用firebase

This is my java code: 这是我的java代码:

 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. 将下面的代码放在OnMapReady方法中。

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. 在onMapReady方法中写下所有逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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