Android - 如何检查您的联系人是否已在您的应用程序上注册?
Android - How to check if your contacts has registered on your app?
我正在尝试创建一个 ChatApp。所以,我想知道我的联系人列表中是否有人在我的应用程序中注册过。
如上图,有3个按键。 El7SIqgHmWTsZCl6gVaXidKGsok1
这是我和其他 2 个是我的朋友,我也有他们的 phoneNumber
。所以,我想在我的应用程序中将这 2 个显示为我的朋友。但是它没有显示任何用户。
这是我试过的代码。
public class UsersFragment extends Fragment {
RecyclerView recyclerView;
ContactsAdapter adapter;
List<Users> contactsList, userList;
DatabaseReference reference;
String userId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_users, container, false);
recyclerView = view.findViewById(R.id.userRecyclerView);
recyclerView.setHasFixedSize(false);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
reference = FirebaseDatabase.getInstance().getReference().child("Users");
contactsList = new ArrayList<>();
userList = new ArrayList<>();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
userId = user.getUid();
return view;
}
private void getContactList() {
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
;
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Users contacts = new Users(name, phone, "", "");
contactsList.add(contacts);
if (contactsList.contains(contacts)) {
cursor.moveToNext();
}
getActualUsers(contacts);
}
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getContactList();
}
private void getActualUsers(final Users contacts) {
Query query = reference.orderByChild("number").equalTo(contacts.getPhoneNumber());
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Users users = dataSnapshot.getValue(Users.class);
userList.add(users);
}
Log.d("contact", String.valueOf(userList.size()));
adapter = new ContactsAdapter(getContext(), userList);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
}
我的模型Class
public class 用户 {
String username, phoneNumber, userId, profilephotoURL;
public Users(){}
public Users(String username, String phoneNumber, String userId, String profilephotoURL) {
this.username = username;
this.phoneNumber = phoneNumber;
this.userId = userId;
this.profilephotoURL = profilephotoURL;
}
public String getUsername() {
return username;
}
public String getPhoneNumber() {
return phoneNumber;
}
public String getUserId() {
return userId;
}
public String getProfilephotoURL() {
return profilephotoURL;
}
}
我的适配器Class
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {
Context mContext;
List<Users> mList;
public UsersAdapter(Context mContext, List<Users> mList) {
this.mContext = mContext;
this.mList = mList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.display_contacts, null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
final Users users = mList.get(position);
holder.name.setText(users.getUsername());
holder.number.setText(users.getPhoneNumber());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, ChatActivity.class);
intent.putExtra("name", users.getUsername());
intent.putExtra("userid", users.getPhoneNumber());
intent.putExtra("id", users.getUserId());
mContext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView name, number;
public ViewHolder(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.contactName);
number = itemView.findViewById(R.id.contactNumber);
}
}
}
有任何帮助或建议吗?
不确定这是否是您问题的解决方案,但可能是,而且评论太长无法解释:
让我以压缩的方式编写您的代码并附上一些注释:
// start a loop over every local contacts on the phone
while (cursor.moveToNext()) {
// create a local variable for this contact (the class name should be Contact. Singular.)
Contacts contacts = new Contacts(name, phone, "");
// get a contact with the same phone number from firebase.
// the sorting is executed for every iteration of the loop -> bad performance.
// -> I recommend to order the reference outside of the loop.
Query query = reference.orderByChild("number").equalTo(contacts.getNumber());
// now you add the ValueEventListener
// if onDataChanged is called, you iterate over all children of the new snapshot
// you create again a local Contacts object
// then there is this strange comparison of name and phone...don't know what that accomplishes, but ok
// now comes the part that might cause the wrong behaviour:
userList.add(contacts1);
adapter = new ContactsAdapter(getContext(), userList);
recyclerView.setAdapter(adapter);
}
因此最后 3 行似乎容易出错:
userList.add(contacts1);
adapter = new ContactsAdapter(getContext(), userList);
recyclerView.setAdapter(adapter);
总的来说,它们并没有太大问题,但请记住,您基本上仍处于 getContactList()
中开始的第一个循环中
这意味着您为循环中的每个联系人创建一个全新的适配器,并将这个新适配器分配给 recyclerView。
假设您的 phone 上有 100 个联系人。这导致创建 100 个适配器并设置到 recyclerView。
我建议对您的代码进行 2 处重大更改:
覆盖 onViewCreated
并将 getContactList();
放在那里。方法 onCreateView
应该只关注基本视图 inflation 并且可以初始化简单的视图变量。 用数据填充 视图应该在 onViewCreated
之后完成。
明确区分“为View准备数据”和“将准备好的数据放入View”。换句话说:首先创建你的最终 userList
并且仅当此列表完成后,创建适配器并将其设置为 recyclerView。
如果您想进一步改进,请查看 ViewModels 的概念。简而言之:ViewModel 正在准备其 View 想要显示的所有数据(包括过滤、转换等)。 View(在本例中是您的 Fragment)尽可能“愚蠢”-> 它一直等到 ViewModel 将数据传递给它,并且只做显示该数据。
LiveData 对于这种方法非常有用,它将使您的代码更加清晰,更易于理解和维护:)
祝你项目顺利!
我不会给你任何代码,而是给你一个关于如何实现你的目标的架构提示。根据您问题中提供的详细信息,我假设您的客户是通过 OTP 注册的。当他们登录时,您可以根据他们的 phone 号码存储他们的 UID。看看 how to save user details.
这是您的 firebase 存储注册用户的样子
registeredUsers : {
"23492hsdfs08fv9x9" : "0X20-342234...",
"34928304283438d8f" : "0X02-123123..."
}
现在,当您访问当前用户联系人列表时,循环遍历 firebase 中的 usrs 列表,以查看联系人列表中的哪些 phone 个号码也在 firebase 中。
您可以只使用 phone 号码列表而不添加 Firebase UID,但我建议您像上面那样做,以防您需要将联系电话映射到它的 UID,然后您可以从中获取该用户的详细信息UID也是。
希望我已经给了你如何相处的提示。
所以,我能够确定问题所在,现在我有了解决方案。所以,我发布它以防有人需要它。
这是用户片段的全部更改代码
public class UsersFragment extends Fragment {
RecyclerView recyclerView;
UsersAdapter adapter;
List<String> contactsList;
DatabaseReference reference;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_users, container, false);
recyclerView = view.findViewById(R.id.userRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
contactsList = new ArrayList<>();
return view;
}
private void getContactList() {
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
while (cursor.moveToNext()) {
String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (contactsList.contains(phone)) {
cursor.moveToNext();
} else {
contactsList.add(phone);
}
}
getActualUser();
Log.d("contact: ", String.valueOf(contactsList.size()));
}
private void getActualUser() {
reference = FirebaseDatabase.getInstance().getReference().child("Users");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
List<Users> actualuserList = new ArrayList<>();
actualuserList.clear();
if (snapshot.exists()) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Users user = dataSnapshot.getValue(Users.class);
for (String number : contactsList){
if (user.getPhoneNumber().equals(number)){
actualuserList.add(user);
}
}
}
Log.d("actual: ", String.valueOf(actualuserList.size()));
adapter = new UsersAdapter(getContext(), actualuserList);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getContactList();
}
}
我正在尝试创建一个 ChatApp。所以,我想知道我的联系人列表中是否有人在我的应用程序中注册过。
如上图,有3个按键。 El7SIqgHmWTsZCl6gVaXidKGsok1
这是我和其他 2 个是我的朋友,我也有他们的 phoneNumber
。所以,我想在我的应用程序中将这 2 个显示为我的朋友。但是它没有显示任何用户。
这是我试过的代码。
public class UsersFragment extends Fragment {
RecyclerView recyclerView;
ContactsAdapter adapter;
List<Users> contactsList, userList;
DatabaseReference reference;
String userId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_users, container, false);
recyclerView = view.findViewById(R.id.userRecyclerView);
recyclerView.setHasFixedSize(false);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
reference = FirebaseDatabase.getInstance().getReference().child("Users");
contactsList = new ArrayList<>();
userList = new ArrayList<>();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
userId = user.getUid();
return view;
}
private void getContactList() {
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
;
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Users contacts = new Users(name, phone, "", "");
contactsList.add(contacts);
if (contactsList.contains(contacts)) {
cursor.moveToNext();
}
getActualUsers(contacts);
}
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getContactList();
}
private void getActualUsers(final Users contacts) {
Query query = reference.orderByChild("number").equalTo(contacts.getPhoneNumber());
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Users users = dataSnapshot.getValue(Users.class);
userList.add(users);
}
Log.d("contact", String.valueOf(userList.size()));
adapter = new ContactsAdapter(getContext(), userList);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
}
我的模型Class
public class 用户 {
String username, phoneNumber, userId, profilephotoURL;
public Users(){}
public Users(String username, String phoneNumber, String userId, String profilephotoURL) {
this.username = username;
this.phoneNumber = phoneNumber;
this.userId = userId;
this.profilephotoURL = profilephotoURL;
}
public String getUsername() {
return username;
}
public String getPhoneNumber() {
return phoneNumber;
}
public String getUserId() {
return userId;
}
public String getProfilephotoURL() {
return profilephotoURL;
}
}
我的适配器Class
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {
Context mContext;
List<Users> mList;
public UsersAdapter(Context mContext, List<Users> mList) {
this.mContext = mContext;
this.mList = mList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.display_contacts, null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
final Users users = mList.get(position);
holder.name.setText(users.getUsername());
holder.number.setText(users.getPhoneNumber());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, ChatActivity.class);
intent.putExtra("name", users.getUsername());
intent.putExtra("userid", users.getPhoneNumber());
intent.putExtra("id", users.getUserId());
mContext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView name, number;
public ViewHolder(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.contactName);
number = itemView.findViewById(R.id.contactNumber);
}
}
}
有任何帮助或建议吗?
不确定这是否是您问题的解决方案,但可能是,而且评论太长无法解释:
让我以压缩的方式编写您的代码并附上一些注释:
// start a loop over every local contacts on the phone
while (cursor.moveToNext()) {
// create a local variable for this contact (the class name should be Contact. Singular.)
Contacts contacts = new Contacts(name, phone, "");
// get a contact with the same phone number from firebase.
// the sorting is executed for every iteration of the loop -> bad performance.
// -> I recommend to order the reference outside of the loop.
Query query = reference.orderByChild("number").equalTo(contacts.getNumber());
// now you add the ValueEventListener
// if onDataChanged is called, you iterate over all children of the new snapshot
// you create again a local Contacts object
// then there is this strange comparison of name and phone...don't know what that accomplishes, but ok
// now comes the part that might cause the wrong behaviour:
userList.add(contacts1);
adapter = new ContactsAdapter(getContext(), userList);
recyclerView.setAdapter(adapter);
}
因此最后 3 行似乎容易出错:
userList.add(contacts1);
adapter = new ContactsAdapter(getContext(), userList);
recyclerView.setAdapter(adapter);
总的来说,它们并没有太大问题,但请记住,您基本上仍处于 getContactList()
中开始的第一个循环中
这意味着您为循环中的每个联系人创建一个全新的适配器,并将这个新适配器分配给 recyclerView。
假设您的 phone 上有 100 个联系人。这导致创建 100 个适配器并设置到 recyclerView。
我建议对您的代码进行 2 处重大更改:
覆盖
onViewCreated
并将getContactList();
放在那里。方法onCreateView
应该只关注基本视图 inflation 并且可以初始化简单的视图变量。 用数据填充 视图应该在onViewCreated
之后完成。明确区分“为View准备数据”和“将准备好的数据放入View”。换句话说:首先创建你的最终
userList
并且仅当此列表完成后,创建适配器并将其设置为 recyclerView。
如果您想进一步改进,请查看 ViewModels 的概念。简而言之:ViewModel 正在准备其 View 想要显示的所有数据(包括过滤、转换等)。 View(在本例中是您的 Fragment)尽可能“愚蠢”-> 它一直等到 ViewModel 将数据传递给它,并且只做显示该数据。
LiveData 对于这种方法非常有用,它将使您的代码更加清晰,更易于理解和维护:)
祝你项目顺利!
我不会给你任何代码,而是给你一个关于如何实现你的目标的架构提示。根据您问题中提供的详细信息,我假设您的客户是通过 OTP 注册的。当他们登录时,您可以根据他们的 phone 号码存储他们的 UID。看看 how to save user details.
这是您的 firebase 存储注册用户的样子
registeredUsers : {
"23492hsdfs08fv9x9" : "0X20-342234...",
"34928304283438d8f" : "0X02-123123..."
}
现在,当您访问当前用户联系人列表时,循环遍历 firebase 中的 usrs 列表,以查看联系人列表中的哪些 phone 个号码也在 firebase 中。
您可以只使用 phone 号码列表而不添加 Firebase UID,但我建议您像上面那样做,以防您需要将联系电话映射到它的 UID,然后您可以从中获取该用户的详细信息UID也是。
希望我已经给了你如何相处的提示。
所以,我能够确定问题所在,现在我有了解决方案。所以,我发布它以防有人需要它。
这是用户片段的全部更改代码
public class UsersFragment extends Fragment {
RecyclerView recyclerView;
UsersAdapter adapter;
List<String> contactsList;
DatabaseReference reference;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_users, container, false);
recyclerView = view.findViewById(R.id.userRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
contactsList = new ArrayList<>();
return view;
}
private void getContactList() {
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
while (cursor.moveToNext()) {
String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (contactsList.contains(phone)) {
cursor.moveToNext();
} else {
contactsList.add(phone);
}
}
getActualUser();
Log.d("contact: ", String.valueOf(contactsList.size()));
}
private void getActualUser() {
reference = FirebaseDatabase.getInstance().getReference().child("Users");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
List<Users> actualuserList = new ArrayList<>();
actualuserList.clear();
if (snapshot.exists()) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Users user = dataSnapshot.getValue(Users.class);
for (String number : contactsList){
if (user.getPhoneNumber().equals(number)){
actualuserList.add(user);
}
}
}
Log.d("actual: ", String.valueOf(actualuserList.size()));
adapter = new UsersAdapter(getContext(), actualuserList);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getContactList();
}
}