Contacts in listview

307 views Asked by At
  1. I am making an app in which i need to read contacts and send text message.I am able to read the contacts but i am unable to show the contacts name and no in list View.

  2. when i try to set C_number my app crashes.

  3. And i want to send the sms to selected contacts.

Any help to cater my problems thanks.

This is single_listview_item.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">
    <CheckBox
        android:id="@+id/chk_box"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"/>

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/chk_box"
        android:textStyle="bold"/>
    <TextView
        android:id="@+id/number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/name"
        android:layout_toRightOf="@id/chk_box"
        android:textStyle="italic"
        android:textSize="12sp"/>
        </LinearLayout>
    </ScrollView>
</RelativeLayout>

This is the main activity where i read all the contacts and i am trying to set them to list view . I have searched a lot but i am unable to find the correct solution. Any to get me going .

This is Mainactivity.java

    package chypher.listviewexample;

import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Switch;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends ActionBarActivity implements CompoundButton.OnCheckedChangeListener {
    ListView lv;
    ArrayList<Planet> planetlist;
    contactadapter cadapter;
    Button okbtn;
    public String name;
    public String phoneNumber;
   public List<String> numb= new ArrayList<String>();;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lv=(ListView)findViewById(R.id.listview);

        fetchContacts();

        //fetchContacts();


    }

    private void fetchContacts() {
       // int phoneNumber ;

 int i=0;
        Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
        String _ID = ContactsContract.Contacts._ID;
        String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
        String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;

        Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
        String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;



      List<String>output = new ArrayList<String>();
        List<String>outputnum=new ArrayList<String>();

        ContentResolver contentResolver = getContentResolver();

        Cursor cursor = contentResolver.query(CONTENT_URI, null,null, null, null);
        // Loop for every contact in the phone
        if (cursor.getCount() > 0) {

            while (cursor.moveToNext()) {

                String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));
               name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));

               // System.out.println("checking from phonename variable"+fromphonename);
                int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex( HAS_PHONE_NUMBER )));

                if (hasPhoneNumber > 0) {

                    output.add(name);

                    // Query and loop for every phone number of the contact
                    Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?", new String[] { contact_id }, null);

                    while (phoneCursor.moveToNext()) {
                        phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
                        outputnum.add( phoneNumber);

                       // System.out.println("cursor phoneno:"+phoneNumber);
                    System.out.println("i value:"+i);
                        i++;
                        displayPlanetList(name,phoneNumber);
                    }

                    phoneCursor.close();
                }




            }
            System.out.println("read from phone:"+output.size());
            System.out.println("read from num:"+outputnum.size());

        }

    }

    private void displayPlanetList(String nam,String nm) {


        planetlist =new ArrayList<Planet>();

        planetlist.add(new Planet(nam,nm));



        cadapter=new contactadapter(planetlist,this);

        lv.setAdapter(cadapter);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        switch (item.getItemId()) {
            case R.id.action_next:
                System.out.println("selected are :" + numb);
                break;
        }

       return true;

    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int pos=lv.getPositionForView(buttonView);
        if(pos!=ListView.INVALID_POSITION){
            Planet p=planetlist.get(pos);
            p.setSelected(isChecked);

            Toast.makeText(this,"Clicked on planet:" +p.getName()+" : state :"+isChecked,Toast.LENGTH_SHORT).show();

            numb.add(p.getNumber());



        }
    }
}

This is my contact adapter class .

  package chypher.listviewexample;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;

import java.util.List;

/**
 * Created by Saqlain Haider on 6/13/2015.
 */
class Planet{
    String name;
    String number;
    boolean selected=false;
    public Planet(String name,String number){
        super();
        this.name=name;
        this.number=number;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class contactadapter extends ArrayAdapter<Planet> {
    private List<Planet>planetList;
    private Context context;
    public contactadapter(List<Planet> planetList, Context context) {
        super(context, R.layout.single_listview_item,planetList);
        this.planetList=planetList;
        this.context=context;
    }
    private static class planetholder{
        public TextView cName,Cnumber;
        public CheckBox checkBox;
    }
    @Override
    public View getView(int position,View convertView,ViewGroup parent){

        View v=convertView;
        planetholder holder=new planetholder();
        if(convertView==null){
            LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v=inflater.inflate(R.layout.single_listview_item,null);
            holder.cName=(TextView)v.findViewById(R.id.name);
            holder.Cnumber=(TextView)v.findViewById(R.id.number);
            holder.checkBox=(CheckBox)v.findViewById(R.id.chk_box);
            holder.checkBox.setOnCheckedChangeListener((MainActivity)context);


        }
        else
        {
            holder=(planetholder)v.getTag();
        }
        Planet p=planetList.get(position);
        holder.cName.setText(p.getName());
        holder.Cnumber.setText(p.getNumber());
        holder.checkBox.setChecked(p.isSelected());
        holder.checkBox.setTag(p);
        return v;
    }
}

This is simple main.xml containing listview

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>

</LinearLayout>

error log:

06-14 00:01:59.972  10362-10362/chypher.listviewexample E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
        at chypher.listviewexample.contactadapter.getView(contactadapter.java:82)
        at android.widget.AbsListView.obtainView(AbsListView.java:2063)
        at android.widget.ListView.makeAndAddView(ListView.java:1792)
        at android.widget.ListView.fillDown(ListView.java:676)
        at android.widget.ListView.fillGap(ListView.java:640)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4901)
        at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:2923)
        at android.widget.AbsListView.startScrollIfNeeded(AbsListView.java:2868)
        at android.widget.AbsListView.onInterceptTouchEvent(AbsListView.java:3738)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1639)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1754)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1754)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1754)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1754)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1754)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1754)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1928)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1387)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2388)
        at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1876)
        at android.view.View.dispatchPointerEvent(View.java:5733)
        at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3104)
        at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2666)
        at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:900)
        at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2675)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4666)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
        at dalvik.system.NativeStart.main(Native Method)

updated error log:

    06-14 01:24:17.271  14698-14698/chypher.listviewexample W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x40e4c258)
06-14 01:24:17.305  14698-14698/chypher.listviewexample E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at android.widget.AdapterView.getPositionForView(AdapterView.java:594)
            at chypher.listviewexample.MainActivity.onCheckedChanged(MainActivity.java:153)
            at android.widget.CompoundButton.setChecked(CompoundButton.java:125)
            at chypher.listviewexample.contactadapter.getView(contactadapter.java:84)
            at android.widget.AbsListView.obtainView(AbsListView.java:2063)
            at android.widget.ListView.makeAndAddView(ListView.java:1792)
            at android.widget.ListView.fillUp(ListView.java:709)
            at android.widget.ListView.fillGap(ListView.java:649)
            at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4901)
            at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4074)
            at android.os.Handler.handleCallback(Handler.java:605)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4666)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
            at dalvik.system.NativeStart.main(Native Method)
1

There are 1 answers

3
Lukas Knuth On

The problem is, that you're never setting your planetholder (which should really be written in camel-case) as the tag of the item-view.

This is okay for the first items, since they'll need to be inflated anyways. As soon as you start scrolling and the inflated views are re-used, you run into this block:

} else {
  holder=(planetholder)v.getTag();
}

Since the tag is never set on v, v.getTag() will return null. In Java, you can cast null to anything (see this discussion), which causes holder to be null.

Now, when you call holder.cName, you're trying to access a property on a null-reference, which causes the NullPointerException.

The fix is to change this:

holder.checkBox.setTag(p);

to this:

v.setTag(holder);