public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
// data
private final List<StationModel> list = new ArrayList<>();
private final StationAdapter adapter = new StationAdapter(this, list);
// component
private FusedLocationProviderClient mc_fused;
private BottomSheetBehavior mc_behaviour;
// view
private Button mv_show;
private LinearLayout mv_sheet;
private RecyclerView mv_recyler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mc_fused = LocationServices.getFusedLocationProviderClient(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mv_show = findViewById(R.id.button_bottom_map_show);
mv_sheet = findViewById(R.id.bottom_container);
mv_recyler = findViewById(R.id.recycler_bottom_map_station);
setupBottomSheet();
setupRecycler();
if (mapFragment != null)
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap map) {
getLocation(map);
}
private void setupBottomSheet() {
mc_behaviour = BottomSheetBehavior.from(mv_sheet);
mv_show.setOnClickListener(new OnClickResult());
}
private void setupRecycler() {
mv_recyler.setAdapter(adapter);
mv_recyler.setLayoutManager(new LinearLayoutManager(this));
}
private void getLocation(GoogleMap googleMap) {
Dexter
.withActivity(this)
.withPermissions(
Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new CurrentLocationListener(googleMap))
.check();
}
class CurrentLocationListener implements MultiplePermissionsListener {
private final GoogleMap map;
private CurrentLocationListener(GoogleMap map) {
this.map = map;
}
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (report.areAllPermissionsGranted()) {
mc_fused
.getLastLocation()
.addOnSuccessListener(new LocationListener());
}
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
}
class LocationListener implements OnSuccessListener<Location> {
@Override
public void onSuccess(Location location) {
MarkerOptions marker = new MarkerOptions()
.title("You")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_android_deep_orange_500_24dp))
.position(new LatLng(location.getLatitude(), location.getLongitude()));
map.addMarker(marker);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12));
new StationFinder(map, new GeoPoint(location.getLatitude(), location.getLongitude()));
}
}
}
class OnClickResult implements View.OnClickListener {
@Override
public void onClick(View v) {
if (mc_behaviour.getState() != BottomSheetBehavior.STATE_EXPANDED) {
mc_behaviour.setState(BottomSheetBehavior.STATE_EXPANDED);
mv_show.setText(R.string.text_hide);
} else {
mc_behaviour.setState(BottomSheetBehavior.STATE_COLLAPSED);
mv_show.setText(R.string.text_show);
}
}
}
class StationFinder implements GeoQueryEventListener {
private final GoogleMap map;
private StationFinder(GoogleMap map, GeoPoint point) {
this.map = map;
CollectionReference reference = FirebaseFirestore.getInstance().collection("stations_index");
GeoFirestore geo = new GeoFirestore(reference);
GeoQuery query = geo.queryAtLocation(point, 7);
query.addGeoQueryEventListener(this);
}
@Override
public void onGeoQueryError(Exception e) {
}
@Override
public void onGeoQueryReady() {
}
@Override
public void onKeyEntered(String s, GeoPoint geoPoint) {
if (s != null && geoPoint != null) {
FirebaseFirestore
.getInstance()
.document("stations/" + s)
.get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
StationModel model = documentSnapshot.toObject(StationModel.class);
if (model != null) {
list.add(model);
adapter.notifyDataSetChanged();
GeoPoint point = model.getPoint();
// mark model station on the map
LatLng station = new LatLng(point.getLatitude(), point.getLongitude());
MarkerOptions marker = new MarkerOptions()
.title(model.getName())
.position(station);
map.addMarker(marker);
}
}
});
}
}
@Override
public void onKeyExited(String s) {
}
@Override
public void onKeyMoved(String s, GeoPoint geoPoint) {
}
}
}
型
import com.google.firebase.firestore.GeoPoint;
public class StationModel {
private String name;
private String address;
private String country;
private String contact;
private GeoPoint point;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public GeoPoint getPoint() {
return point;
}
public void setPoint(GeoPoint point) {
this.point = point;
}
}
日志猫:
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'double android.location.Location.getLatitude((' com.exzray.womensafetyapp.MapsActivity$CurrentLocationListener$LocationListener.onSuccess(MapsActivity.java:141( at com.exzray.womensafetyapp.MapsActivity$CurrentLocation
当我打开位置时,它显示最近的车站,但是当我关闭位置并重新打开时,它会显示此错误。我需要清除缓存才能再次获得最近的警察局。请指导我
您需要在类LocationListener
public void onSuccess(Location location) {...}
检查location != null
,因为location
可以null
。像这样:
...
class LocationListener implements OnSuccessListener<Location> {
@Override
public void onSuccess(Location location) {
if (location != null) {
MarkerOptions marker = new MarkerOptions()
.title("You")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_android_deep_orange_500_24dp))
.position(new LatLng(location.getLatitude(), location.getLongitude()));
map.addMarker(marker);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12));
new StationFinder(map, new GeoPoint(location.getLatitude(), location.getLongitude()));
}
}
}
...