I want to retrieve contact data from Firebase Realtime Database and show them in a ListView in Android studio. Problem is my code is getting an Error of null pointer exception. I ran the debugger before this exception it was running fine but suddenly I got this error.
I might also add that after retrieving data from firebase I kept them in an ArrayList. when I ran the debugger the ArrayList was showing its size according to the database but when it got to the adapter class it became null. The ListView that I have created to show contacts is empty. It does not show any data even after notifying the adapter that the data have changed.
Can anyone help me with this?
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sosandvideo, PID: 24758
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sosandvideo/com.example.sosandvideo.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:389)
at android.widget.ListView.setAdapter(ListView.java:581)
at com.example.sosandvideo.MainActivity.onCreate(MainActivity.java:43)
at android.app.Activity.performCreate(Activity.java:7994)
at android.app.Activity.performCreate(Activity.java:7978)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
This is my MainActivity.class
package com.example.sosandvideo;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
;
import com.example.sosandvideo.Contacts.Contact;
import com.example.sosandvideo.Contacts.ContactAdapter;
import com.example.sosandvideo.Contacts.DBhelper;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final int RESULT_PICK_CONTACT =1;
ListView listview;
List<Contact> list;
ContactAdapter contactAdapter;
private Button add;
DBhelper db=new DBhelper();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
// phone = findViewById (R.id.contactTv);
add = findViewById (R.id.addButton);
listview=(ListView)findViewById(R.id.listView);
list = db.getAllContacts();
contactAdapter=new ContactAdapter(this,list);
listview.setAdapter(contactAdapter);
add.setOnClickListener (new View.OnClickListener () {
@Override
public void onClick(View v) {
Intent in = new Intent (Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult (in, RESULT_PICK_CONTACT);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RESULT_PICK_CONTACT:
contactPicked(data);
break;
}
} else {
Toast.makeText(this, "Failed To pick contact", Toast.LENGTH_SHORT).show();
}
}
@SuppressLint("Range")
private void contactPicked(Intent data) {
Cursor cursor = null;
try {
String phoneNo = null;
int id;
String name;
Uri uri = data.getData ();
cursor = getContentResolver ().query (uri, null, null,null,null);
cursor.moveToFirst ();
id= cursor.getColumnIndex (ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
String phoneid= cursor.getString (id);
String phoneNum= cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
db.addContact(new Contact(phoneid,phoneNum,name));
list = db.getAllContacts();
contactAdapter.refresh(list);
} catch (Exception e) {
e.printStackTrace ();
}
}
}
This is My DBhelper.class
package com.example.sosandvideo.Contacts;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class DBhelper {
FirebaseDatabase database=FirebaseDatabase.getInstance();
DatabaseReference reference= database.getReference("contacts");
ArrayList<Contact> list;
public void addContact(Contact contact)
{
// added contact details to database
reference.child(contact.getId()).setValue(contact);
}
public void deleteContact(Contact contact)
{
reference.child(contact.getId()).removeValue();
}
public List<Contact> getAllContacts()
{
reference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) {
Contact contact=snapshot.getValue(Contact.class);
list.add(contact);
//reference.setValue(list);
}
@Override
public void onChildChanged(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) {
}
@Override
public void onChildRemoved(@NonNull @NotNull DataSnapshot snapshot) {
}
@Override
public void onChildMoved(@NonNull @NotNull DataSnapshot snapshot, @Nullable @org.jetbrains.annotations.Nullable String previousChildName) {
}
@Override
public void onCancelled(@NonNull @NotNull DatabaseError error) {
}
});
return list;
}
}
This is my Adapter class
package com.example.sosandvideo.Contacts;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.example.sosandvideo.R;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.List;
public class ContactAdapter extends ArrayAdapter<Contact> {
List<Contact> list;
Context context;
public ContactAdapter( @NonNull Context context ,List<Contact> list)
{
super(context,R.layout.item,list);
this.context=context;
this.list=list;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
DBhelper db=new DBhelper();
Contact c = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item, parent, false);
}
LinearLayout linearLayout = (LinearLayout) convertView.findViewById(R.id.linear);
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
TextView tvPhone = (TextView) convertView.findViewById(R.id.tvPhone);
// Populate the data into the template
// view using the data object
tvName.setText(c.getName());
tvPhone.setText(c.getPhoneNum());
linearLayout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
// generate an MaterialAlertDialog Box
new MaterialAlertDialogBuilder(context)
.setTitle("Remove Contact")
.setMessage("Are you sure want to remove this contact?")
.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// delete the specified contact from the database
db.deleteContact(c);
// remove the item from the list
list.remove(c);
// notify the listview that dataset has been changed
notifyDataSetChanged();
Toast.makeText(context, "Contact removed!", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.show();
return false;
}
});
// Return the completed view to render on screen
return convertView;
}
// this method will update the ListView
public void refresh(List<Contact> c_list) {
list.clear();
list.addAll(c_list);
notifyDataSetChanged();
}
}