Firebase/GeoQuery最大半径判断逻辑实现求助
解决方案:实现搜索半径上限自动终止并提示用户
我来帮你搞定这个自动终止搜索的问题!你当前代码的核心问题在于,每次搜索完没找到技工,就直接扩大半径继续递归搜索,但完全没判断是否已经达到你设定的max_radius上限,所以才会无限循环下去。
只需要在递归前加个判断:如果当前半径已经到顶了,就停止搜索并给用户反馈;否则继续扩大范围找。下面是修改后的完整代码,关键改动我都标了注释:
private int radius = 1; // 初始搜索半径(英里) private int max_radius = 15; // 最大搜索半径 private Boolean tradesmanFound = false; private String tradesmanFoundID; GeoQuery geoQuery; private void getClosestTradesman() { DatabaseReference tradesmanLocation = FirebaseDatabase.getInstance().getReference().child("TradesmanAvailable"); GeoFire geoFire = new GeoFire(tradesmanLocation); geoQuery = geoFire.queryAtLocation(new GeoLocation(customerLocation.latitude, customerLocation.longitude), radius); geoQuery.removeAllListeners(); geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { @Override public void onKeyEntered(String key, GeoLocation location) { if (!tradesmanFound && requestBol) { DatabaseReference customerDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child("Tradesman").child(key); customerDatabase.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { if (dataSnapshot.exists() && dataSnapshot.getChildrenCount() > 0) { Map<String, Object> tradesmanMap = (Map<String, Object>) dataSnapshot.getValue(); if (tradesmanFound) { return; } if (tradesmanMap.get("Trade").equals(tradeType)) { tradesmanFound = true; tradesmanFoundID = dataSnapshot.getKey(); DatabaseReference tradesmanRef = FirebaseDatabase.getInstance().getReference().child("Users").child("Tradesman").child(tradesmanFoundID).child("CustomerRequest"); String customerID = FirebaseAuth.getInstance().getCurrentUser().getUid(); HashMap map = new HashMap(); map.put("CustomerRequestID", customerID); tradesmanRef.updateChildren(map); getTradesmanLocation(); getTradesmanInfo(); isRequestFinished(); requestTradesmanBtn.setText("Looking for Tradesman's Location..."); } } } @Override public void onCancelled(DatabaseError databaseError) { // 加个错误日志,方便排查问题 Log.e("TradesmanSearch", "数据库查询失败: " + databaseError.getMessage()); } }); } } @Override public void onKeyExited(String key) {} @Override public void onKeyMoved(String key, GeoLocation location) {} @Override public void onGeoQueryReady() { if (!tradesmanFound) { // 关键改动:判断是否达到最大搜索半径 if (radius >= max_radius) { // 终止搜索,给用户提示 tradesmanFound = true; // 标记为已完成,防止重复触发 requestTradesmanBtn.setText("未找到" + max_radius + "英里范围内的可用技工"); Toast.makeText(getApplicationContext(), "抱歉,当前区域没有可用的匹配技工", Toast.LENGTH_LONG).show(); return; } // 没到上限就扩大半径继续搜 radius++; getClosestTradesman(); } } @Override public void onGeoQueryError(DatabaseError error) { // 搜索出错时也要给用户反馈 Log.e("TradesmanSearch", "Geo查询失败: " + error.getMessage()); Toast.makeText(getApplicationContext(), "搜索失败,请稍后重试", Toast.LENGTH_LONG).show(); } }); }
额外优化建议:
每次用户发起新的搜索请求时,记得重置搜索状态,避免上次的状态影响新搜索,比如在请求按钮的点击事件里加上:
requestTradesmanBtn.setOnClickListener(v -> { radius = 1; tradesmanFound = false; tradesmanFoundID = null; requestBol = true; requestTradesmanBtn.setText("正在寻找技工..."); getClosestTradesman(); });
内容的提问来源于stack exchange,提问作者rostacko1
相关产品推荐
相关产品推荐

