android - 将 GeoFire 查询加载到 RecyclerView 时应用程序崩溃
问题描述
我正在开发一个基于位置的聊天应用程序作为最终任务,但是有一个我无法自己解决的错误。目前,我打算将某个半径内的所有配置文件加载到回收站视图中,并仅向当前用户显示这些配置文件。
回收站视图工作正常并显示我的 Firebase 数据库中的每个用户,直到我添加 GeoFire 查询以限制仅出现在 2 公里半径内的用户。所有用户的纬度和经度都已成功更新到数据库中,所以我认为这不是问题的根源。
当我运行应用程序并且它崩溃时,我在 LogCat 中得到了这个异常:
“java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'double android.location.Location.getLatitude()'”
这让我很困惑,因为我数据库中的当前用户都没有为他们的经度或纬度存储空值。
所以我的主要问题是,我怎样才能只让当前用户 2 公里内的用户填充我的回收站视图,而不会导致应用程序崩溃?
当前源代码:
public class FindChatters extends Fragment {
private RecyclerView mUsersList;
private View mMainView;
private DatabaseReference mUsersDatabase;
private FirebaseUser mCurrentUser;
private LatLng myCurrentLocation;
private String mUserFound;
private static final int RADIUS = 2;
Location mLastLocation;
public FindChatters() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mMainView = inflater.inflate(R.layout.fragment_find_chatters, container, false);
mUsersDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
mUsersList = (RecyclerView) mMainView.findViewById(R.id.users_list);
mUsersList.setHasFixedSize(true);
mUsersList.setLayoutManager(new LinearLayoutManager(getContext()));
return mMainView;
}
//RETRIEVE DATA IN REALTIME
@Override
public void onStart() {
super.onStart();
startListening();
}
public void startListening() {
Query query = FirebaseDatabase.getInstance().getReference().child("Users").limitToLast(50);
FirebaseRecyclerOptions<Users> options = new FirebaseRecyclerOptions.Builder<Users>().setQuery(query, Users.class).build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Users, UserViewHolder>(options) {
@Override
public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// CREATE NEW INSTANCE OF VIEWHOLDER, USING CUSTOM LAYOUT (R.LAYOUT.MESSAGE)
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_single_layout, parent, false);
return new UserViewHolder(view);
}
@Override
protected void onBindViewHolder(final UserViewHolder holder, final int position, final Users model) {
// // //
//RETRIEVE CURRENT USERS LAT/LONG TO FIND USERS NEARBY
String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference myLoc = FirebaseDatabase.getInstance().getReference().child("Geo");
final GeoFire geoFire = new GeoFire(myLoc);
geoFire.setLocation(userID, new GeoLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude()));
myCurrentLocation = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
//RETRIEVE USERS ONLY FROM WITHIN A SPECIFIED RADIUS TO THE CURRENT USER
DatabaseReference findNearby = FirebaseDatabase.getInstance().getReference().child("Geo");
GeoFire geoFire2 = new GeoFire(findNearby);
//QUERY ALL NEARBY USERS IN THE DATABASE WITHIN 2KM OF CURRENT USER LAT/LONG
final GeoQuery geoQuery = geoFire2.queryAtLocation(new GeoLocation(myCurrentLocation.latitude, myCurrentLocation.longitude), RADIUS);
//QUERY TO RETRIEVE CLOSET USERS
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
//IF ANY USERS FOUND WITHIN RADIUS - ON KEY ENTERED IS CALLED
@Override
public void onKeyEntered(String key, GeoLocation location) {
if (geoQuery != null) {
mUserFound = key;
//BIND CHAT OBJECT TO CHATHOLDER
holder.setName(model.name);
holder.setUserStatus(model.status);
holder.setUserOnline(model.online);
holder.setUserImage(getContext(), model.image);
//CLICK ON A USER PROFILE TO ACCESS THEIR INFORMATION OR INITIATE CHAT
final String user_id = getRef(position).getKey();
//RETRIEVE CURRENT USER ID
String current_uid = mCurrentUser.getUid();
//PREVENT USER FROM BEING ABLE TO INITIATE A CONVERSATION WITH THEMSELF
if (!user_id.equals(current_uid)) {
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent profileIntent = new Intent(getActivity(), ProfileActivity.class);
profileIntent.putExtra("user_id", user_id);
startActivity(profileIntent);
}
});
} else {
holder.setName("You");
holder.setUserStatus("Tap someone to say hello!");
}
} else {
//CREATE TEXTVIEW TO INFORM USER THAT NO NEARBY USERS ARE PRESENT
}
}
@Override
public void onKeyExited(String key) {
}
@Override
public void onKeyMoved(String key, GeoLocation location) {
}
@Override
public void onGeoQueryReady() {
}
@Override
public void onGeoQueryError(DatabaseError error) {
}
});
// // //
}
};
mUsersList.setAdapter(adapter);
adapter.startListening();
}
我对编码还是很陌生,所以我非常感谢任何回复或帮助。谢谢!
安卓工作室 v3.1.3
解决方案
确保初始化mLastLocation
. 我可以看到您正在从中检索 lat 和 lng 但从未初始化
推荐阅读
- c# - 使用 Azure 函数进行日志记录 ~2.0
- python - 在交叉验证中是否需要在评分参数中使用 make_scorer 来为预定义的分数对象?
- r - 在R中按多个条件排列
- node.js - AWS Elastic Beanstalk 不会从 nodejs 应用程序的公共文件夹中加载静态文件
- laravel-5 - Laravel 应用程序(AWS 服务器)中的关键缓存问题
- javascript - 使用 recorder.js 以低 kbps 录制音频
- python - 按模型中计算的计算字段对记录进行排序
- rust - 如何在循环间隔内同时运行一组函数,而不使用 Tokio 同时运行相同的函数?
- javascript - 如何使用反应钩子实现多个复选框
- html - CSS 字体包括未在浏览器中显示