情境
要怎麼寫一個電話簿?
首先要先了解幾個課題,
如何動態新增內建ListView + 資料庫SQLiteOpenHelper存取[記事本]
如何使用打電話功能(Call)
程式碼說明
首先我們必須取得手機裡面的電話簿(廢話= =)
接著把這些電話號碼放進一個ListView裡面。
一開始先定義XML, 放入一個ListView
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="example.givemepass.providercontactdemo.MainActivity">
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/listview" />
</RelativeLayout>
主程式碼
public class MainActivity extends AppCompatActivity {
private static final String NAME = "name";
private static final String NUMBER = "number";
private List<Map<String, String>> contactsArrayList;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
}
private void initView(){
listView = (ListView) findViewById(R.id.list);
SimpleAdapter adapter = new SimpleAdapter(this,
contactsArrayList,
android.R.layout.simple_list_item_1,
new String[] { NAME,NUMBER },
new int[] { android.R.id.text1,android.R.id.text2 });
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String number = contactsArrayList.get(position).get(NUMBER);
new AlertDialog.Builder(MainActivity.this)
.setTitle(number)
.setItems(new String[]{"Call"}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
Intent call = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number));
startActivity(call);
break;
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
}
});
}
private void initData(){
getPhoneBookData();
}
public void getPhoneBookData(){
contactsArrayList = new ArrayList<>();
Cursor contacts_name = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
null,
null,
null,
null);
while (contacts_name.moveToNext()) {
Map<String, String> map = new HashMap<>();
String phoneNumber = "";
long id = contacts_name.getLong(
contacts_name.getColumnIndex(ContactsContract.Contacts._ID));
Cursor contacts_number = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ "=" + Long.toString(id),
null,
null);
while (contacts_number.moveToNext()) {
phoneNumber = contacts_number
.getString(contacts_number.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
}
contacts_number.close();
String name = contacts_name.getString(contacts_name
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
map.put(NAME, name);
map.put(NUMBER, phoneNumber);
contactsArrayList.add(map);
}
}
}
我們ListView想要放入人名以及電話號碼,
本來我們可以利用這樣的方法取得人名以及電話,
Cursor cursor = getContentResolver().query(
Contacts.People.CONTENT_URI,
new String[]{Contacts.People.NAME,Contacts.People.NUMBER},
null,
null,
null);
但是Android2.0以後, 就把這個方法deprecated了。
所以我們採取新的方法,
查詢手機裡面電話簿人名,
Cursor contacts_name = getContentResolver()
.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
它會回傳一個Cursor, 就可以利用下面的方法取出人名
String name = contacts_name
.getString(
contacts_name.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
可是他的電話號碼卻是放在另外一個地方,
因此我們必須重新查詢一次,
Cursor contacts_number = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
null,
null,
null);
可是這兩個Table怎麼連起來呢? 很簡單, 它裡面有一個欄位叫作_id,
通常習慣上我們都會在每個Table裡面放入一個primary key,
這樣才會符合正規化,然後利用這個key將兩個Table關聯起來。
因此我們寫了一個方法, 把這個兩個Table關聯起來,
public void getPhoneBookData(){
contacts_name = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
null,
null,
null,
null);
while (contacts_name.moveToNext()) {
contactsMap = new HashMap<String, String>();
String phoneNumber = "";
long id = contacts_name.getLong(
contacts_name.getColumnIndex(ContactsContract.Contacts._ID));
contacts_number = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ "=" + Long.toString(id),
null,
null);
while (contacts_number.moveToNext()) {
phoneNumber = contacts_number
.getString(contacts_number.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
}
contacts_number.close();
String name = contacts_name.getString(contacts_name
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contactsMap.put(NAME, name);
contactsMap.put(NUMBER, phoneNumber);
contactsArrayList.add(contactsMap);
}
}
這樣一來, 我們就可以直接把存好的ArrayList丟進SimpleAdapter裡面,
SimpleAdapter adapter = new SimpleAdapter(this,
contactsArrayList,
android.R.layout.simple_list_item_2,
new String[] { NAME,NUMBER },
new int[] { android.R.id.text1,android.R.id.text2 });
listView.setAdapter(adapter);
而當我們按下某一個Item的時候, 會跳出AlertDialog讓我們選擇要不要打電話。
listView.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String name = contactsArrayList.get(position).get(NAME);
final String number = contactsArrayList.get(position).get(NUMBER);
new AlertDialog.Builder(ProviderContactDemoActivity.this)
.setTitle(number)
.setItems(new String[]{"Call"}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which){
case 0:
Intent call = new Intent(
Intent.ACTION_CALL, Uri.parse("tel:" + number));
startActivity(call);
break;
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.show();
}
});
最後記得加上權限,
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
結果如下圖