Reputation: 568
I am using geofire to populate my recyclerview working fine onkeyEnter but when the onKeyExited call my application is crashes please help me here is my code.
private void Geofireinit() {
started = true;
GeoQuery geoQuery = fire.queryAtLocation(new GeoLocation(20.887715, 77.757623), 50);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
Log.e("id", key);
Location to = new Location("to");
to.setLatitude(location.latitude);
to.setLongitude(location.longitude);
if (!fetchedUserIds) {
userIdsToLocations.put(key, to);
} else {
userIdsToLocations.put(key, to);
addUserListener(key);
}
}
@Override
public void onKeyExited(String key) {
Log.d("TAG", "onKeyExited: ");
if (userIdsWithListeners.contains(key)) {
int position = getUserPosition(key);
arrayList.remove(position);
adapter.notifyItemRemoved(position);
}
}
@Override
public void onKeyMoved(String key, GeoLocation location) {
}
@Override
public void onGeoQueryReady() {
initialListSize = userIdsToLocations.size();
if (initialListSize == 0) {
fetchedUserIds = true;
}
iterationCount = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
userIdsToLocations.keySet().forEach(this::addUserListener);
}
}
private void addUserListener(String key) {
databaseReference = FirebaseDatabase.getInstance().getReference().child("buses").child(key);
databaseReference.addValueEventListener(userValueListener);
userIdsWithListeners.add(key);
}
@Override
public void onGeoQueryError(DatabaseError error) {
}
});
geoQueries.add(geoQuery);
}
private void setuplist() {
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new Adapter(this, arrayList);
recyclerView.setAdapter(adapter);
}
private void setupFirebase() {
databaseReference = FirebaseDatabase.getInstance().getReference().child(("tracker"));
fire = new GeoFire(databaseReference);
getrecyclerview();
}
private void getrecyclerview() {
userValueListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Mylist mylist = dataSnapshot.getValue(Mylist.class);
mylist.setTextView(dataSnapshot.child("text").getValue().toString());
if (arrayList.contains(mylist)) {
update(mylist);
} else {
newdata(mylist);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
}
private void newdata(Mylist mylist) { // for new data inserted
iterationCount++;
arrayList.add(0, mylist);
if (!fetchedUserIds && iterationCount == initialListSize) {
fetchedUserIds = true;
adapter.setUsers(arrayList);
} else if (fetchedUserIds) {
adapter.notifyItemInserted(getIndexOfNewUser(mylist));
}
}
private void update(Mylist mylist) {
int position = getUserPosition(mylist.getTextView());
arrayList.set(position, mylist);
adapter.notifyItemChanged(position);
}
private int getUserPosition(String id) {
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).getTextView().equals(id)) {
Log.d("LOG_TAG", "getIndexOfNewUser: " + i);
return i;
}
}
return -1;
}
private int getIndexOfNewUser(Mylist u) {
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).getTextView().equals(u.getTextView())) {
Log.d("index", "getIndexOfNewUser: " + i);
return i;
}
}
throw new RuntimeException();
}
private void removeListeners() {
for (GeoQuery geoQuery : geoQueries) {
geoQuery.removeAllListeners();
}
for (String userId : userIdsWithListeners) {
databaseReference =
FirebaseDatabase.getInstance().getReference().child("buses").child(userId);
databaseReference.removeEventListener(userValueListener);
}
}
My Adpter code
public class Adapter extends RecyclerView.Adapter<Adapter.Myholder> {
ArrayList<Mylist> arrayList;
Context context;
public Adapter(Context context, ArrayList<Mylist> arrayList)
{
this.context=context;
this.arrayList=arrayList;
}
@NonNull
@Override
public Myholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.samplecard,parent,false);
return new Myholder(view);
}
@Override
public void onBindViewHolder(@NonNull Myholder holder, int position) {
final Mylist mylist=arrayList.get(position);
holder.textView.setText(mylist.getTextView());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(context,MapsActivity.class);
intent.putExtra("id",mylist.getTextView());
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return arrayList.size();
}
public void setUsers(List<Mylist> list) {
arrayList = (ArrayList<Mylist>) list;
notifyDataSetChanged();
}
public class Myholder extends RecyclerView.ViewHolder {
TextView textView;
public Myholder(@NonNull View itemView) {
super(itemView);
textView=itemView.findViewById(R.id.mytext);
}
}
public Mylist getUser(int position) {
if (position > arrayList.size() - 1) {
return new Mylist();
} else {
return arrayList.get(position);
}
}}
whenever the onKeyExited is called i want to remove that data from recyclerview but the application crashed when i reopen the application its runs successfully.
2020-06-11 14:46:21.752 16559-16559/com.pranay.test2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pranay.test2, PID: 16559
java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
at java.util.ArrayList.remove(ArrayList.java:506)
at com.pranay.test2.MainActivity$4.onKeyExited(MainActivity.java:208)
at com.firebase.geofire.EventListenerBridge.onDataExited(EventListenerBridge.java:52)
at com.firebase.geofire.GeoQuery$4.run(GeoQuery.java:162)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:232)
at android.app.ActivityThread.main(ActivityThread.java:7172)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:576)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
Upvotes: 0
Views: 198
Reputation: 924
Method getUserPosition(String id)
can return -1, but it is impossible for array to have -1 position. So you suppose to check here:
public void onKeyExited(String key) {
Log.d("TAG", "onKeyExited: ");
if (userIdsWithListeners.contains(key)) {
int position = getUserPosition(key);
if (position!=-1){
arrayList.remove(position);
adapter.notifyItemRemoved(position);
}
}
}
Upvotes: 1