该例实现了浏览联系人、添加联系人、删除联系人、编辑联系人、查看联系人,当找到一个联系人后,可以呼叫或者发送消息给该联系人。
下例体现了UI设计、数据库的综合操作、动态菜单的使用以及各种权限的注册。
public class ContactColumn implements BaseColumns{//定义数据,要设计数据库,首先要确定数据都是什么内容,为了方便管理、维护和共享首先将数据中要使用的数据全部定义到
ContactColumn类
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,
};
}
public class DBHelper extends SQLiteOpenHelper{//android.database.sqlite.SQLiteOpenHelper类是一个专门用于数据库创建和版本管理的辅助类。
此处创建了一个DBHelper类来维护和更新数据库
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);
}
}
public class ContactsProvider extends ContentProvider{//ContentProvider类提供了多个应用间数据共享的方式,比如:联系人信息可以被多个应用程序访问。
ContentProvider是一个实现了一组用于提供其他应用程序存在数据的标准方法类。
所以此处创建此类用来对数据库的操作,如:查询、修改、添加、删除
private static final String TAG= "ContactsProvider";
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);//单独列
}
public boolean onCreate(){
dbHelper = new DBHelper(getContext());
//执行创建数据库
contactsDB = dbHelper.getWritableDatabase();
return (contactsDB == null) ? false : true;
}
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;
}
public String getType(Uri uri){// URI类型转换。我们定义了一个新的类型,因此得到URI时,就可以通过此方法转换成我们需要的类型。
其中CONTACTS表示多行数据,CONTACT_ID表示单行数据。注意这些类型需要在AndroidManifest.xml中声明权限。
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);
Log.e(TAG + "insert", "initialValues is not null");
}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, "");
}
Log.e(TAG + "insert", values.toString());
long rowId = contactsDB.insert(CONTACTS_TABLE, null, values);
if (rowId > 0){
Uri noteUri = ContentUris.withAppendedId(CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(noteUri, null);
Log.e(TAG + "insert", noteUri.toString());
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){// 对数据库的操作,查询数据
Log.e(TAG + ":query", " in Query");
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){// 更新数据库