如何从 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 数据库中获取特定值?的主要内容,如果未能解决你的问题,请参考以下文章

使用聚类时如何禁用android地图标记单击自动居中?

如何从其他面板从 JTextField 获取输入

如何从外部从 GitHub 加载 JavaScript 文件? [复制]

如何将数据从回收器适配器发送到片段 |如何从 recyclerview 适配器调用片段函数

如何从 Firebase 获取所有设备令牌?

如何直接从类调用从接口继承的方法?