如何从 OnMarkerClickListener 内的 Firebase 数据库中获取特定值?
Posted
技术标签:
【中文标题】如何从 OnMarkerClickListener 内的 Firebase 数据库中获取特定值?【英文标题】:How to get the specific value from Firebase database inside OnMarkerClickListener? 【发布时间】:2020-01-29 15:46:53 【问题描述】:我正在从 firebase 数据库中获取数据并在地图上显示标记。 当我从 OnMarkerClickListener 内部查询时,我无法从 firebase 获取值。 我想要做的是从数据库中获取特定标记的 id,然后将其保存在一个字符串中,并通过意图将该字符串发送到另一个活动。 一切正常,我只是无法从 OnMarkerClickListener 内的数据库中获取 id。 这是代码。
public class NearbyEventsActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener, GoogleMap.OnMarkerClickListener
String selectedCategory;
List<Event> eventList;
private GoogleMap mMap;
private ChildEventListener mChildEventListener;
Marker marker;
LocationManager manager;
Criteria mCriteria;
String bestProvider;
Location mLocation;
String eventid, eventTitle;
FirebaseAuth auth;
FirebaseDatabase database;
DatabaseReference eventRef;
Query query, q;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nearby_events);
getSupportActionBar().setTitle("Nearby Events");
selectedCategory = getIntent().getStringExtra("selectedCategory");
eventList = new ArrayList<>();
auth = FirebaseAuth.getInstance();
database = FirebaseDatabase.getInstance();
eventRef = database.getReference("events");
query = database.getReference("events")
.orderByChild("event_category")
.equalTo(selectedCategory);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
@Override
public void onMapReady(GoogleMap googleMap)
mMap = googleMap;
googleMap.setOnMarkerClickListener(this);
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
Dexter.withActivity(this)
.withPermissions(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_COARSE_LOCATION)
.withListener(new MultiplePermissionsListener()
@Override
public void onPermissionsChecked(MultiplePermissionsReport report)
// check if all permissions are granted
if (report.areAllPermissionsGranted())
// do you work now
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
// TODO: Consider calling
// Activity#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
mMap.setMyLocationEnabled(true);
mMap.setTrafficEnabled(true);
mMap.setBuildingsEnabled(true);
mMap.setIndoorEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
// check for permanent denial of any permission
if (report.isAnyPermissionPermanentlyDenied())
// permission is denied permenantly, navigate user to app settings
showSettingsDialog();
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token)
token.continuePermissionRequest();
).onSameThread().check();
// when map gets ready, set the camera to current location of the user.
manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
mCriteria = new Criteria();
bestProvider = String.valueOf(manager.getBestProvider(mCriteria, true));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
// TODO: Consider calling
// Activity#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
mLocation = manager.getLastKnownLocation(bestProvider);
if (mLocation != null)
Log.e("TAG", "GPS is on");
final double currentLatitude = mLocation.getLatitude();
final double currentLongitude = mLocation.getLongitude();
LatLng loc1 = new LatLng(currentLatitude, currentLongitude);
mMap.addMarker(new MarkerOptions().position(loc1).title("Your Current Location"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 15));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11), 2000, null);
query.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
eventList.clear();
if (dataSnapshot.exists())
for (DataSnapshot snapshot : dataSnapshot.getChildren())
Event event = snapshot.getValue(Event.class);
eventList.add(event);
for (int i = 0; i < eventList.size(); i++)
Event mEvent = eventList.get(i);
Double lat = mEvent.getLat();
Double lng = mEvent.getLng();
LatLng loc = new LatLng(lat, lng);
mMap.addMarker(new MarkerOptions().position(loc).title(mEvent.getEvent_title()))
.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
);
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
@Override
public boolean onMarkerClick(Marker marker)
eventTitle = marker.getTitle();
q = database.getReference("events")
.orderByChild("event_title")
.equalTo(eventTitle);
q.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
for (DataSnapshot snapshot : dataSnapshot.getChildren())
Event e = snapshot.getValue(Event.class);
eventid = e.getEvent_id();
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
);
Intent intent = new Intent(NearbyEventsActivity.this, EventDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putString("eventid", eventid);
intent.putExtras(bundle);
startActivity(intent);
return false;
);
@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;
private void showSettingsDialog()
AlertDialog.Builder builder = new AlertDialog.Builder(NearbyEventsActivity.this);
builder.setTitle("Need Permissions");
builder.setMessage("This app needs permission to use this feature. You can grant them in app settings.");
builder.setPositiveButton("GOTO SETTINGS", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
dialog.cancel();
openSettings();
);
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
dialog.cancel();
);
builder.show();
private void openSettings()
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 101);
我的 firebase 数据库就像普通的数据库一样
events
-Lp08gX8tEQBjXIGwm
- event_title : "Abc"
- event_id : "Lp08gX8tEQBjXIGwm"
. . .
【问题讨论】:
请将您的数据库结构添加为 JSON 文件或至少作为屏幕截图。除此之外,“只是在从 OnMarkerClickListener 内的数据库中获取 id 时遇到问题”是什么意思? 【参考方案1】:看起来直到您获得事件 ID,您的 EventDetailActivity 已经启动。 所以尝试在 forloop 中记录 eventid 并在 onDataChange 方法中启动 EventDetailActivity。
q.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
for (DataSnapshot snapshot : dataSnapshot.getChildren())
Event e = snapshot.getValue(Event.class);
eventid = e.getEvent_id();
Log.v("eventid",eventid);
Intent intent = new Intent(NearbyEventsActivity.this,
EventDetailActivity.class);
Bundle bundle = new Bundle();
bundle.putString("eventid", eventid);
intent.putExtras(bundle);
startActivity(intent);
【讨论】:
你是对的,活动在获取值之前开始。我添加了代码 if(eventid != null) startActivity(intent);并在第一次点击它不会打开活动,但在第二次点击它打开它罚款。有什么办法可以解决这个问题? 您必须调试并检查是否在第一次点击时获得 eventid以上是关于如何从 OnMarkerClickListener 内的 Firebase 数据库中获取特定值?的主要内容,如果未能解决你的问题,请参考以下文章
如何从外部从 GitHub 加载 JavaScript 文件? [复制]