通讯录就是一个ListView,我们需要通过数据库和ContentProvider来活动通讯录的数据,当然,我们应该提供选中后编辑的功能。
很简单的一个通讯略Demo,所以,直接上代码,需要的看一下就知道。不解释。
文件1: MyContacs
主活动页面。
package com.yarin.android.MyContacts; import android.app.ListActivity; import android.content.ComponentName; import android.content.ContentUris; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ContextMenu.ContextMenuInfo; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleCursorAdapter; public class MyContacts extends ListActivity{ private static final int AddContact_ID = Menu.FIRST; //private static final int EditContact_ID = Menu.FIRST+1; private static final int DELEContact_ID = Menu.FIRST+2; private static final int EXITContact_ID = Menu.FIRST+3; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); Intent intent = getIntent(); if (intent.getData() == null) { intent.setData(ContactsProvider.CONTENT_URI); } getListView().setOnCreateContextMenuListener(this); Cursor cursor = managedQuery(getIntent().getData(), ContactColumn.PROJECTION, null, null,null); //注册每个列表表示形式 :姓名 + 移动电话 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, new String[] {ContactColumn.NAME, ContactColumn.MOBILENUM }, new int[] { android.R.id.text1, android.R.id.text2 }); setListAdapter(adapter); } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); //添加联系人 menu.add(0, AddContact_ID, 0, R.string.add_user) .setShortcut('3', 'a') .setIcon(R.drawable.add); Intent intent = new Intent(null, getIntent().getData()); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, new ComponentName(this, MyContacts.class), null, intent, 0, null); //退出程序 menu.add(0, EXITContact_ID, 0, R.string.exit) .setShortcut('4', 'd') .setIcon(R.drawable.exit); return true; } //处理菜单操作 public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case AddContact_ID: //添加联系人 startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData())); return true; case EXITContact_ID: //退出程序 this.finish(); return true; } return super.onOptionsItemSelected(item); } public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); final boolean haveItems = getListAdapter().getCount() > 0; if (haveItems) { Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId()); Intent[] specifics = new Intent[2]; specifics[0] = new Intent(Intent.ACTION_EDIT, uri); specifics[1] = new Intent(Intent.ACTION_VIEW, uri); MenuItem[] items = new MenuItem[2]; //添加满足条件的菜单 Intent intent = new Intent(null, uri); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0, items); if (items[0] != null) { //编辑联系人 items[0].setShortcut('1', 'e').setIcon(R.drawable.edituser).setTitle(R.string.editor_user); } if (items[1] != null) { //查看联系人 items[1].setShortcut('2', 'f').setTitle(R.string.view_user).setIcon(R.drawable.viewuser); } } else { menu.removeGroup(Menu.CATEGORY_ALTERNATIVE); } return true; } //动态菜单处理 //点击的默认操作也可以在这里处理 protected void onListItemClick(ListView l, View v, int position, long id) { Uri uri = ContentUris.withAppendedId(getIntent().getData(), id); String action = getIntent().getAction(); if ( Intent.ACTION_EDIT.equals(action) ) { //编辑联系人 startActivity(new Intent(Intent.ACTION_EDIT, uri)); } else { //查看联系人 startActivity(new Intent(Intent.ACTION_VIEW, uri)); } } //长按触发的菜单 public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { AdapterView.AdapterContextMenuInfo info; try { info = (AdapterView.AdapterContextMenuInfo) menuInfo; } catch (ClassCastException e) { return; } //得到长按的数据项 Cursor cursor = (Cursor) getListAdapter().getItem(info.position); if (cursor == null) { return; } menu.setHeaderTitle(cursor.getString(1)); //添加删除菜单 menu.add(0, DELEContact_ID, 0, R.string.delete_user); } @Override public boolean onContextItemSelected(MenuItem item){ AdapterView.AdapterContextMenuInfo info; try{ info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); }catch (ClassCastException e){ return false; } switch (item.getItemId()){ case DELEContact_ID:{ //删除一条记录 Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id); getContentResolver().delete(noteUri, null, null); return true; } } return false; } }
文件2 DBHelper
数据库相关操作。
package com.yarin.android.MyContacts; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DBHelper extends SQLiteOpenHelper { public static final String DATABASE_NAME = "mycontacts.db";//数据库名 public static final int DATABASE_VERSION = 2; //版本 public static final String CONTACTS_TABLE = "contacts"; //表名 //创建表 private static final String DATABASE_CREATE = "CREATE TABLE " + CONTACTS_TABLE +" (" + ContactColumn._ID+" integer primary key autoincrement," + ContactColumn.NAME+" text," + ContactColumn.MOBILENUM+" text," + ContactColumn.HOMENUM+" text," + ContactColumn.ADDRESS+" text," + ContactColumn.EMAIL+" text," + ContactColumn.BLOG+" text);"; public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + CONTACTS_TABLE); onCreate(db); } }
文件3 ContentsProvider
内容提供
package com.yarin.android.MyContacts; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; public class ContactsProvider extends ContentProvider{ private DBHelper dbHelper; private SQLiteDatabase contactsDB; public static final String AUTHORITY = "com.yarin.android.provider.ContactsProvider"; public static final String CONTACTS_TABLE = "contacts"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"+CONTACTS_TABLE); /*=====================================================*/ //下面是自定义的类型 public static final int CONTACTS = 1; public static final int CONTACT_ID = 2; private static final UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY,"contacts",CONTACTS); //单独列 uriMatcher.addURI(AUTHORITY,"contacts/#",CONTACT_ID); } /*=====================================================*/ @Override public boolean onCreate() { dbHelper = new DBHelper(getContext()); //执行创建数据库 contactsDB = dbHelper.getWritableDatabase(); return (contactsDB == null) ? false : true; } // 删除指定数据列 @Override public int delete(Uri uri, String where, String[] selectionArgs) { int count; switch (uriMatcher.match(uri)) { case CONTACTS: count = contactsDB.delete(CONTACTS_TABLE, where, selectionArgs); break; case CONTACT_ID: String contactID = uri.getPathSegments().get(1); count = contactsDB.delete(CONTACTS_TABLE, ContactColumn._ID + "=" + contactID + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), selectionArgs); break; default: throw new IllegalArgumentException("Unsupported URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } // URI类型转换 public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case CONTACTS: return "vnd.android.cursor.dir/vnd.yarin.android.mycontacts"; case CONTACT_ID: return "vnd.android.cursor.item/vnd.yarin.android.mycontacts"; default: throw new IllegalArgumentException("Unsupported URI: " + uri); } } // 插入数据 public Uri insert(Uri uri, ContentValues initialValues) { if (uriMatcher.match(uri) != CONTACTS) { throw new IllegalArgumentException("Unknown URI " + uri); } ContentValues values; if (initialValues != null) { values = new ContentValues(initialValues); } else { values = new ContentValues(); } // 设置默认值 if (values.containsKey(ContactColumn.NAME) == false) { values.put(ContactColumn.NAME, ""); } if (values.containsKey(ContactColumn.MOBILENUM) == false) { values.put(ContactColumn.MOBILENUM, ""); } if (values.containsKey(ContactColumn.HOMENUM) == false) { values.put(ContactColumn.HOMENUM, ""); } if (values.containsKey(ContactColumn.ADDRESS) == false) { values.put(ContactColumn.ADDRESS, ""); } if (values.containsKey(ContactColumn.EMAIL) == false) { values.put(ContactColumn.EMAIL, ""); } if (values.containsKey(ContactColumn.BLOG) == false) { values.put(ContactColumn.BLOG, ""); } long rowId = contactsDB.insert(CONTACTS_TABLE, null, values); if (rowId > 0) { Uri noteUri = ContentUris.withAppendedId(CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new SQLException("Failed to insert row into " + uri); } // 查询数据 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(CONTACTS_TABLE); switch (uriMatcher.match(uri)) { case CONTACT_ID: qb.appendWhere(ContactColumn._ID + "=" + uri.getPathSegments().get(1)); break; default: break; } String orderBy; if (TextUtils.isEmpty(sortOrder)) { orderBy = ContactColumn._ID; } else { orderBy = sortOrder; } Cursor c = qb.query(contactsDB, projection, selection, selectionArgs, null, null, orderBy); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } // 更新数据库 public int update(Uri uri, ContentValues values, String where, String[] selectionArgs) { int count; switch (uriMatcher.match(uri)) { case CONTACTS: count = contactsDB.update(CONTACTS_TABLE, values, where, selectionArgs); break; case CONTACT_ID: String contactID = uri.getPathSegments().get(1); count = contactsDB.update(CONTACTS_TABLE, values, ContactColumn._ID + "=" + contactID + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), selectionArgs); break; default: throw new IllegalArgumentException("Unsupported URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } }文件4 ContactView
package com.yarin.android.MyContacts; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView; public class ContactView extends Activity { private TextView mTextViewName; private TextView mTextViewMobile; private TextView mTextViewHome; private TextView mTextViewAddress; private TextView mTextViewEmail; private TextView mTextViewBlog; private Cursor mCursor; private Uri mUri; private static final int REVERT_ID = Menu.FIRST; private static final int DELETE_ID = Menu.FIRST + 1; private static final int EDITOR_ID = Menu.FIRST + 2; private static final int CALL_ID = Menu.FIRST + 3; private static final int SENDSMS_ID = Menu.FIRST + 4; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mUri = getIntent().getData(); this.setContentView(R.layout.viewuser); mTextViewName = (TextView) findViewById(R.id.TextView_Name); mTextViewMobile = (TextView) findViewById(R.id.TextView_Mobile); mTextViewHome = (TextView) findViewById(R.id.TextView_Home); mTextViewAddress = (TextView) findViewById(R.id.TextView_Address); mTextViewEmail = (TextView) findViewById(R.id.TextView_Email); mTextViewBlog = (TextView) findViewById(R.id.TextView_Blog); // 获得并保存原始联系人信息 mCursor = managedQuery(mUri, ContactColumn.PROJECTION, null, null, null); mCursor.moveToFirst(); } protected void onResume() { super.onResume(); if (mCursor != null) { // 读取并显示联系人信息 mCursor.moveToFirst(); mTextViewName.setText(mCursor.getString(ContactColumn.NAME_COLUMN)); mTextViewMobile.setText(mCursor.getString(ContactColumn.MOBILENUM_COLUMN)); mTextViewHome.setText(mCursor.getString(ContactColumn.HOMENUM_COLUMN)); mTextViewAddress.setText(mCursor.getString(ContactColumn.ADDRESS_COLUMN)); mTextViewEmail.setText(mCursor.getString(ContactColumn.EMAIL_COLUMN)); mTextViewBlog.setText(mCursor.getString(ContactColumn.BLOG_COLUMN)); } else { setTitle("错误信息"); } } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); //添加菜单 menu.add(0, REVERT_ID, 0, R.string.revert).setShortcut('0', 'r').setIcon(R.drawable.listuser); menu.add(0, DELETE_ID, 0, R.string.delete_user).setShortcut('0', 'd').setIcon(R.drawable.remove); menu.add(0, EDITOR_ID, 0, R.string.editor_user).setShortcut('0', 'd').setIcon(R.drawable.edituser); menu.add(0, CALL_ID, 0, R.string.call_user).setShortcut('0', 'd').setIcon(R.drawable.calluser) .setTitle(this.getResources().getString(R.string.call_user)); menu.add(0, SENDSMS_ID, 0, R.string.sendsms_user).setShortcut('0', 'd').setIcon(R.drawable.sendsms) .setTitle(this.getResources().getString(R.string.sendsms_user)); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { //删除 case DELETE_ID: deleteContact(); finish(); break; //返回列表 case REVERT_ID: setResult(RESULT_CANCELED); finish(); break; case EDITOR_ID: //编辑联系人 startActivity(new Intent(Intent.ACTION_EDIT, mUri)); break; case CALL_ID: //呼叫联系人 Intent call = new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+mTextViewMobile.getText())); startActivity(call); break; case SENDSMS_ID: //发短信给联系人 Intent sms = new Intent(Intent.ACTION_SENDTO,Uri.parse("smsto:"+mTextViewMobile.getText())); startActivity(sms); break; } return super.onOptionsItemSelected(item); } // 删除联系人信息 private void deleteContact() { if (mCursor != null) { mCursor.close(); mCursor = null; getContentResolver().delete(mUri, null, null); setResult(RESULT_CANCELED); } } }文件5 ContactColumn
数据表定义
package com.yarin.android.MyContacts; import android.provider.BaseColumns; //定义数据 public class ContactColumn implements BaseColumns{ public ContactColumn(){} //列名 public static final String NAME = "name"; //姓名 public static final String MOBILENUM = "mobileNumber";//移动电话 public static final String HOMENUM = "homeNumber"; //家庭电话 public static final String ADDRESS = "address"; //地址 public static final String EMAIL = "email"; //邮箱 public static final String BLOG = "blog"; //博客 //列 索引值 public static final int _ID_COLUMN = 0; public static final int NAME_COLUMN = 1; public static final int MOBILENUM_COLUMN = 2; public static final int HOMENUM_COLUMN = 3; public static final int ADDRESS_COLUMN = 4; public static final int EMAIL_COLUMN = 5; public static final int BLOG_COLUMN = 6; //查询结果 public static final String[] PROJECTION ={ _ID, NAME, MOBILENUM, HOMENUM, ADDRESS, EMAIL, BLOG, }; }文件6
编辑状态下的页面
package com.yarin.android.MyContacts; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class ContactEditor extends Activity{ private static final int STATE_EDIT = 0; private static final int STATE_INSERT = 1; private static final int REVERT_ID = Menu.FIRST; private static final int DISCARD_ID = Menu.FIRST + 1; private static final int DELETE_ID = Menu.FIRST + 2; private Cursor mCursor; private int mState; private Uri mUri; private EditText nameText; private EditText mobileText; private EditText homeText; private EditText addressText; private EditText emailText; private EditText blogText; private Button okButton; private Button cancelButton; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent intent = getIntent(); final String action = intent.getAction(); //根据action的不同进行不同的操作 //编辑联系人 if (Intent.ACTION_EDIT.equals(action)) { mState = STATE_EDIT; mUri = intent.getData(); } else if (Intent.ACTION_INSERT.equals(action)) { //添加新联系人 mState = STATE_INSERT; mUri = getContentResolver().insert(intent.getData(), null); if (mUri == null) { finish(); return; } setResult(RESULT_OK, (new Intent()).setAction(mUri.toString())); } else { finish(); return; } setContentView(R.layout.editorcontacts); nameText = (EditText) findViewById(R.id.EditText01); mobileText = (EditText) findViewById(R.id.EditText02); homeText = (EditText) findViewById(R.id.EditText03); addressText = (EditText) findViewById(R.id.EditText04); emailText = (EditText) findViewById(R.id.EditText05); blogText = (EditText) findViewById(R.id.EditText06); okButton = (Button)findViewById(R.id.Button01); cancelButton = (Button)findViewById(R.id.Button02); okButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { String text = nameText.getText().toString(); if(text.length()==0) { //如果没有输入东西,则不添加记录 setResult(RESULT_CANCELED); deleteContact(); finish(); } else { //添加一条数据 updateContact(); } } }); cancelButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { if(mState == STATE_INSERT) { //不添加记录 setResult(RESULT_CANCELED); deleteContact(); finish(); } else { //恢复到编辑前的状态 backupContact(); } } }); // 获得并保存原始联系人信息 mCursor = managedQuery(mUri, ContactColumn.PROJECTION, null, null, null); mCursor.moveToFirst(); } protected void onResume() { super.onResume(); if (mCursor != null) { // 读取并显示联系人信息 mCursor.moveToFirst(); if (mState == STATE_EDIT) { setTitle(getText(R.string.editor_user)); } else if (mState == STATE_INSERT) { setTitle(getText(R.string.add_user)); } String name = mCursor.getString(ContactColumn.NAME_COLUMN); String moblie = mCursor.getString(ContactColumn.MOBILENUM_COLUMN); String home = mCursor.getString(ContactColumn.HOMENUM_COLUMN); String address = mCursor.getString(ContactColumn.ADDRESS_COLUMN); String email = mCursor.getString(ContactColumn.EMAIL_COLUMN); String blog = mCursor.getString(ContactColumn.BLOG_COLUMN); nameText.setText(name); mobileText.setText(moblie); homeText.setText(home); addressText.setText(address); emailText.setText(email); blogText.setText(blog); } else { setTitle("错误信息"); } } protected void onPause() { super.onPause(); if (mCursor != null) { String text = nameText.getText().toString(); if (text.length() == 0) { setResult(RESULT_CANCELED); deleteContact(); // 更新信息 } else { ContentValues values = new ContentValues(); values.put(ContactColumn.NAME, nameText.getText().toString()); values.put(ContactColumn.MOBILENUM, mobileText.getText().toString()); values.put(ContactColumn.HOMENUM, homeText.getText().toString()); values.put(ContactColumn.ADDRESS, addressText.getText().toString()); values.put(ContactColumn.EMAIL, emailText.getText().toString()); values.put(ContactColumn.BLOG, blogText.getText().toString()); getContentResolver().update(mUri, values, null, null); } } } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); if (mState == STATE_EDIT) { menu.add(0, REVERT_ID, 0, R.string.revert) .setShortcut('0', 'r') .setIcon(R.drawable.listuser); menu.add(0, DELETE_ID, 0, R.string.delete_user) .setShortcut('0', 'f') .setIcon(R.drawable.remove); } else { menu.add(0, DISCARD_ID, 0, R.string.revert) .setShortcut('0', 'd') .setIcon(R.drawable.listuser); } return true; } //菜单处理 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case DELETE_ID: deleteContact(); finish(); break; case DISCARD_ID: cancelContact(); break; case REVERT_ID: backupContact(); break; } return super.onOptionsItemSelected(item); } //删除联系人信息 private void deleteContact() { if (mCursor != null) { mCursor.close(); mCursor = null; getContentResolver().delete(mUri, null, null); nameText.setText(""); } } //丢弃信息 private void cancelContact() { if (mCursor != null) { deleteContact(); } setResult(RESULT_CANCELED); finish(); } //更新 变更的信息 private void updateContact() { if (mCursor != null) { mCursor.close(); mCursor = null; ContentValues values = new ContentValues(); values.put(ContactColumn.NAME, nameText.getText().toString()); values.put(ContactColumn.MOBILENUM, mobileText.getText().toString()); values.put(ContactColumn.HOMENUM, homeText.getText().toString()); values.put(ContactColumn.ADDRESS, addressText.getText().toString()); values.put(ContactColumn.EMAIL, emailText.getText().toString()); values.put(ContactColumn.BLOG, blogText.getText().toString()); getContentResolver().update(mUri, values, null, null); } setResult(RESULT_CANCELED); finish(); } //取消用,回退到最初的信息 private void backupContact() { if (mCursor != null) { mCursor.close(); mCursor = null; ContentValues values = new ContentValues(); values.put(ContactColumn.NAME, nameText.getText().toString()); values.put(ContactColumn.MOBILENUM, mobileText.getText().toString()); values.put(ContactColumn.HOMENUM, homeText.getText().toString()); values.put(ContactColumn.ADDRESS, addressText.getText().toString()); values.put(ContactColumn.EMAIL, emailText.getText().toString()); values.put(ContactColumn.BLOG, blogText.getText().toString()); getContentResolver().update(mUri, values, null, null); } setResult(RESULT_CANCELED); finish(); } }