如何从手机中获取所有联系人并在列表视图中显示按钮点击android?

时间:2017-01-31 16:27:38

标签: android listview

我想从手机中获取所有联系人,只需在android ListView中显示,而不在数据库中存储,目的是当用户点击按钮"同步所有联系人"然后应该获取所有联系人并显示在ListView中。这是主要的活动类我也创建了带有变量contacts_namephone_no以及CustomAdapter

的getter-setter类
public class MainActivity extends AppCompatActivity {

ListView listView;
Button sync;



ArrayList<newlist> listitem;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    listitem = new ArrayList<newlist>();
    listView = (ListView) findViewById(R.id.listViewID);
    registerForContextMenu(listView);

    sync= (Button) findViewById(R.id.syncID);
    sync.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

              //what method will be used here for sync contacts and display in listview
           }
       });
   }
}

请任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

尝试使用此库,您可以轻松获得所有联系人。

https://github.com/EverythingMe/easy-content-providers

对于ListView,您需要编写自定义适配器,您还可以在互联网上找到很多示例。这只是一个样本。

public class CustomListViewAdapter extends ArrayAdapter<Person> {

private final LayoutInflater inflater;
private final Context context;
private ViewHolder holder;
private final ArrayList<Person> persons;

public CustomListViewAdapter(Context context, ArrayList<Person> persons) {
    super(context,0, persons);
    this.context = context;
    this.persons = persons;
    inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
    return persons.size();
}

@Override
public Person getItem(int position) {
    return persons.get(position);
}

@Override
public long getItemId(int position) {
    return persons.get(position).hashCode();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {

        convertView = inflater.inflate(R.layout.list_view_item, null);

        holder = new ViewHolder();
        holder.personImage = (ImageView) convertView.findViewById(R.id.person_image);
        holder.personNameLabel = (TextView) convertView.findViewById(R.id.person_name_label);
        holder.personAddressLabel = (TextView) convertView.findViewById(R.id.person_address_label);
        convertView.setTag(holder);

    }
    else{
        //Get viewholder we already created
        holder = (ViewHolder)convertView.getTag();
    }

    Person person = persons.get(position);
    if(person != null){
        holder.personImage.setImageResource(person.getPhotoId());
        holder.personNameLabel.setText(person.getName());
        holder.personAddressLabel.setText(person.getAddress());

    }
    return convertView;
}

//View Holder Pattern for better performance
private static class ViewHolder {
    TextView personNameLabel;
    TextView personAddressLabel;
    ImageView personImage;

}
} 

onCreate 中阅读图书馆的文档,并尝试弄清楚如何获取联系人。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // GET CONTACTS DATA
    initialize();
}

private void initialize() {
    persons = new ArrayList<Person>();
    listView = (ListView) findViewById(R.id.person_list_view);
    listViewAdapter = new CustomListViewAdapter(MainActivity.this,persons);
    listView.setAdapter(listViewAdapter);
}

答案 1 :(得分:1)

<强>权限

首先,在清单中设置权限:

<uses-permission android:name="android.permission.READ_CONTACTS"/>

注意:从Marshmallow开始,权限模型已更改。如果您的targetSdkVersion&gt; = 23且您在Marshmallow(或更高版本)设备上运行,则可能需要启用运行时权限才能获得 READ_CONTACTS 权限。您还可以在此处阅读有关运行时权限更改的更多信息。

构建SimpleCursorAdapter

SimpleCursorAdapter是一个适配器,它将ListView绑定到Cursor数据集,该数据集将结果集显示为列表中的行。我们可以在接收游标之前通过构造如下来创建适配器:

public class SampleActivity extends AppCompatActivity {
    // ... existing code ...
    private SimpleCursorAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       // ...
       setupCursorAdapter();
    }

    // Create simple cursor adapter to connect the cursor dataset we load with a ListView
    private void setupCursorAdapter() {
        // Column data from cursor to bind views from
        String[] uiBindFrom = { ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.PHOTO_URI };
        // View IDs which will have the respective column data inserted
        int[] uiBindTo = { R.id.tvName, R.id.ivImage };
        // Create the simple cursor adapter to use for our list
        // specifying the template to inflate (item_contact),
        adapter = new SimpleCursorAdapter(
                  this, R.layout.item_contact,
                  null, uiBindFrom, uiBindTo,
                  0);
    }
}

请注意,如果要使用更复杂的自定义布局,则应构建自定义CursorAdapter以替换上面显示的SimpleCursorAdapter。

连接ListView

一旦我们定义了游标适配器,我们就可以在名为R.id.lvContacts的活动中添加一个ListView,它将包含从内容提供者加载的联系人列表。一旦我们在布局XML中定义了ListView,我们就可以将列表绑定到我们的适配器:

public class SampleActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       // ...
       setupCursorAdapter();
       // Find list and bind to adapter
       ListView lvContacts = (ListView) findViewById(R.id.lvContacts);
       lvContacts.setAdapter(adapter);
    }
}

现在,一旦我们从Contacts ContentProvider加载Cursor,我们就可以将数据集插入适配器,列表将自动填充。

使用CursorLoader查询ContentProvider

每当我们想要从已注册的ContactProvider加载数据时,我们都希望异步执行查询以避免阻止UI。执行此查询的最简单方法是使用CursorLoader,它在后台针对ContentProvider运行异步查询,并将结果返回给我们的Activity。

要向我们的联系人提供程序执行请求,我们需要定义加载程序将用于创建请求并处理结果的回调。这些回调的类型为LoaderCallbacks,可以定义如下:

public class SampleActivity extends AppCompatActivity {
   // ... existing code

    // Defines the asynchronous callback for the contacts data loader
    private LoaderManager.LoaderCallbacks<Cursor> contactsLoader =
        new LoaderManager.LoaderCallbacks<Cursor>() {
        // Create and return the actual cursor loader for the contacts data
        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            // Define the columns to retrieve
            String[] projectionFields = new String[] { ContactsContract.Contacts._ID,
                       ContactsContract.Contacts.DISPLAY_NAME,
                       ContactsContract.Contacts.PHOTO_URI };
            // Construct the loader
            CursorLoader cursorLoader = new CursorLoader(SampleActivity.this,
                    ContactsContract.Contacts.CONTENT_URI, // URI
                    projectionFields, // projection fields
                    null, // the selection criteria
                    null, // the selection args
                    null // the sort order
            );
            // Return the loader for use
            return cursorLoader;
        }

        // When the system finishes retrieving the Cursor through the CursorLoader,
        // a call to the onLoadFinished() method takes place.
        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
            // The swapCursor() method assigns the new Cursor to the adapter
            adapter.swapCursor(cursor);  
        }

        // This method is triggered when the loader is being reset
        // and the loader data is no longer available. Called if the data
        // in the provider changes and the Cursor becomes stale.
        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
            // Clear the Cursor we were using with another call to the swapCursor()
            adapter.swapCursor(null);
        }
    };
}

现在,当结果返回到定义的回调时,适配器将绑定到游标。通过指定加载程序回调,我们现在可以设置加载程序并执行对内容提供程序的异步请求:

public class SampleActivity extends AppCompatActivity {
    // ... existing code
    // Defines the id of the loader for later reference
    public static final int CONTACT_LOADER_ID = 78; // From docs: A unique identifier for this loader. Can be whatever you want.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Bind adapter to list
        setupCursorAdapter();
        // Initialize the loader with a special ID and the defined callbacks from above
        getSupportLoaderManager().initLoader(CONTACT_LOADER_ID,
            new Bundle(), contactsLoader);
    }
}

现在我们已经完成了使用CursorLoader查询ContactProvider并将生成的Cursor加载到CursorAdapter中将联系人加载到列表中的过程。我们现在应该看到我们联系人姓名的列表。

您可以参考此link

答案 2 :(得分:1)

使用以下方法从手机数据库中提取联系人(根据您的要求更新方法,目前只提取联系人号码)。

    List<Integer> fetchContacts() {
        final String[] projection = new String[]{
                ContactsContract.CommonDataKinds.Phone.NUMBER,
        };

        final Cursor phone = context.getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                projection, null, null, null);

        List<Integer> contacts = new ArrayList<>();
        while(phone.moveToNext()){
            contacts.add(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER););
        }
        phone.close();
        return contacts;
    }

之后,您可以将此联系人列表传递给适配器,并在适配器上调用notifyDataSetChanged()以反映列表视图中的更改。

此外,您需要为清单文件中的联系人权限声明uses-permission,如此

<uses-permission android:name="android.permission.READ_CONTACTS"/>