Android程序的主要4部分:
1、Activiyt
2、Broadcast Intent Receiver
3、Service
4、Content Provider
一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。
下面列举一些常用的接口:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
52、ContentResolver
外界程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用ContentResolver实例。其提供的接口与ContentProvider提供的接口对应:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
【实例】
提供ContentProvider的程序:TestSQLite_2_ContentProvider
对其进行访问访问的程序:TestContentProvider_useStudentData
下面进行分析:
【1】要为当前应用程序的私有数据定义URI,就需要专门定义个继承自ContentProvider的类,然后实现各个不同的操作所调用的方法。
首先在该应用程序的某个类中定义所有与数据库操作有关的静态字段,以便打包成jar文件供其他应用程序调用(本例中引用打包好的jar包后会有“找不到类”的错误,故直接将该类,连同包名一同复制到另一个程序中,如)
此例子没有新定义一个专门的类来存放这些字段,而是在继承了SQLiteOpenHelper的类StudentData中定义:
package com.shutao.testsqlite2;
public class StudentData extends SQLiteOpenHelper {
/*
* 分别定义了数据库和表的名称、表中各个字段的名称、数据库的版本号
*/
public final static String DB_NAME = "student";
public final static String TABLE_NAME = "hero";
public final static String SNAME = "name";
public final static String SID = "_id";
public final static int DB_VERSION = 1;
/*
* AUTHORITY:定义了标识ContentProvider的字符串 ;
* ITEM和ITEM_ID分别用于UriMatcher(资源标识符匹配器)中对路径item和item/id的匹配号码
* CONTENT_TYPE和CONTENT_ITEM_TYPE定义了数据的MIME类型。需要注意的是: 单一数据的MIME 类型字符串应该以
* vnd.android.cursor.item/开头,数据集的MIME类型字符串应该以vnd.android.cursor.dir开头
* CONTENT_URI定义的是查询当前表数据的content://样式URI
*/
public static final String AUTHORITY = "com.shutao.testsqlite2.provider.studentdata";
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.shutao.testsqlite2.studentdata";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.shutao.testsqlite2.studentdata";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/item");
public StudentData(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(" + SID
+ " VARCHAR PRIMARY KEY," + SNAME + " VARCHAR NOT NULL);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
}
【2】接下来定义一个继承自ContentProvider的类:MyProvider.java,来实现对数据进行操作的各个方法。这里将用到StudentData来辅助得到SQLiteDatabase对象:
package com.shutao.testsqlite2;
public class MyProvider extends ContentProvider {
StudentData sd;
private static final UriMatcher sMatcher;
static {
// 传入匹配码如果大于0表示匹配根路径或传入-1,即常量UriMatcher.NO_MATCH表示不匹配根路径
// addURI()方法是用来增加其他URI匹配路径的:
// 第一个参数代表传入标识ContentProvider的AUTHORITY字符串
// 第二个参数是要匹配的路径,#代表任意数字,另外还可以用*来匹配任意文本
// 第三个参数必须传入一个大于零的匹配码,用于match()方法对相匹配的URI返回相对应的匹配码
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI(StudentData.AUTHORITY, "item", StudentData.ITEM);
sMatcher.addURI(StudentData.AUTHORITY, "item/#", StudentData.ITEM_ID);
}
/*
* 每当ContentProvider启动时都会回调onCreate()方法。此方法主要执行一些ContentProvider初始化
* 的工作,返回true表示初始化成功,返回false则初始化失败。
*/
@Override
public boolean onCreate() {
sd = new StudentData(this.getContext());
return true;
}
// getType()是用来返回数据的MIME类型的方法。使用sMatcher对URI进行匹配,并返回相应的MIME类型字符串
@Override
public String getType(Uri uri) {
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
return StudentData.CONTENT_TYPE;
case StudentData.ITEM_ID:
return StudentData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
/*
* 插入数据,返回新插入数据的URI,只接受数据集的URI,即指向表的URI
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase sdb = sd.getWritableDatabase();
long rowId;
if (sMatcher.match(uri) != StudentData.ITEM) {
throw new IllegalArgumentException("Unknow URI " + uri);
}
rowId = sdb.insert(StudentData.TABLE_NAME, StudentData.SID, values);
if (rowId > 0) {
Uri noteUri = ContentUris.withAppendedId(StudentData.CONTENT_URI,
rowId);
this.getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
/*
* 用于数据的删除,返回的是所影响数据的数目,首先利用数据库辅助对象获取一个SQLiteDatabase对象
* 然后根据传入Uri用sMatcher进行匹配,对单个数据或数据集进行删除或修改。notifyChange()方法
* 用来通知注册在次URI上的观察者(observer)数据发生了改变。
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.delete(StudentData.DB_NAME, selection, selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.delete(StudentData.DB_NAME, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
/*
* 查询数据,将数据装入一个Cursor对象并返回
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase sdb = sd.getReadableDatabase();
Cursor c;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
c = sdb.query(StudentData.TABLE_NAME, projection, selection,
selectionArgs, null, null, sortOrder);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
c = sdb.query(StudentData.TABLE_NAME, projection, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs, null, null, sortOrder);
break;
default:
Log.i("sMatcher.match(uri)", String.valueOf(sMatcher.match(uri)));
throw new IllegalArgumentException("Query with unknown URI: " + uri);
}
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// 更新,与删除类方法类似
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.update(StudentData.TABLE_NAME, values, selection,
selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.update(StudentData.DB_NAME, values, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
【3】完成以上方法以后,还要AndroidManifest.xml中对这个ContentProvider声明:
<provider
android:name="MyProvider"
android:authorities="com.shutao.testsqlite2.provider.studentdata"/>
<!-- 其中 android:name必须跟定义的ContentProvider的类名一样
android:authorities则指定了content://样式的URI中标识这个ContentProvider的字符串-->
【4】接下来在另一个程序中使用ContentResolver来操作数据:
package com.shutao.contentprovider;
public class TestContentProvider extends Activity {
private EditText stu_name;
private EditText stu_sid;
Button commit;
ListView studList;
ContentResolver resolver;
// 由于在AlertDialog中用到,所以定义为全局变量。
String sid = "";
private final int DIALOG_IN_USED = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stu_name = (EditText) this.findViewById(R.id.edit_name);
stu_sid = (EditText) this.findViewById(R.id.edit_sid);
commit = (Button) this.findViewById(R.id.butt_add);
studList = (ListView) this.findViewById(R.id.show_stud);
//【重要】得到ContentResolver()
resolver = this.getContentResolver();
String[] projection = { StudentData.SNAME, StudentData.SID };
Cursor c = resolver.query(StudentData.CONTENT_URI, null, null, null,
StudentData.SID);
CursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, c, projection, new int[] {
android.R.id.text1, android.R.id.text2 });
studList.setAdapter(adapter);
commit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!(stu_name.getText().length() > 0)) {
Toast.makeText(TestContentProvider.this,
"Please input the student's name!",
Toast.LENGTH_LONG).show();
} else if (!(stu_sid.getText().length() > 0)) {
Toast
.makeText(TestContentProvider.this,
"Please input the student's ID!",
Toast.LENGTH_LONG).show();
} else {
String name = stu_name.getText().toString();
sid = stu_sid.getText().toString();
Uri quri = Uri.parse(StudentData.CONTENT_URI + "/" + sid);
Cursor c = resolver.query(quri, null, null, null, null);
if (c.moveToFirst()) {
// 采用Toast方式提醒
/*
* Toast.makeText(TestContentProvider.this,
* "Fail to add!This ID is already in used!",
* Toast.LENGTH_LONG).show();
*/
// 采用AlertDialog方式提醒
TestContentProvider.this.showDialog(DIALOG_IN_USED);
} else {
ContentValues values = new ContentValues();
values.put(StudentData.SNAME, name);
values.put(StudentData.SID, sid);
resolver.insert(StudentData.CONTENT_URI, values);
}
}
}
});
}
//如果插入的Id已经存在则用提示框进行提示
@Override
protected Dialog onCreateDialog(int id, Bundle args) {
// // TODO Auto-generated method stub
// return super.onCreateDialog(id, args);
switch (id) {
case DIALOG_IN_USED:
return new AlertDialog.Builder(this).setTitle("Fail to add!")
.setIcon(R.drawable.fail).setMessage(
"This ID:" + sid + " is already in used!")
.setPositiveButton("确定",
// 特别注意:必须为:new DialogInterface.OnClickListener()
// 不能为new
// OnClickListener(),否则会跟View.OnClickListener冲突。
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
}
}).create();
default:
return super.onCreateDialog(id, args);
}
}
}
53、ContentProvider与ContentResolver中用到的Uri
【注】:在ContentProvider与ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据,如:
1、content://contacts/people/:这个Uri指定的就是全部联系人的数据。
2、content://contacts/people/1:这个Uri指定的就是ID为1的联系人的数据。
Uri一般由3部分组成:
1、"content://"
2、要获得数据的一个字符串片段
3、最后就是ID,如果没有ID则返回全部数据。
但因为URI通常比较长,容易出错,所以在Android当中定义了一些辅助类,并定义了一些常量来代替这些这些字符串的使用,如:
Contacts.People.CONTENT_URI:联系人的URI.
1、Activiyt
2、Broadcast Intent Receiver
3、Service
4、Content Provider
一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。
下面列举一些常用的接口:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
52、ContentResolver
外界程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用ContentResolver实例。其提供的接口与ContentProvider提供的接口对应:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
【实例】
提供ContentProvider的程序:TestSQLite_2_ContentProvider
对其进行访问访问的程序:TestContentProvider_useStudentData
下面进行分析:
【1】要为当前应用程序的私有数据定义URI,就需要专门定义个继承自ContentProvider的类,然后实现各个不同的操作所调用的方法。
首先在该应用程序的某个类中定义所有与数据库操作有关的静态字段,以便打包成jar文件供其他应用程序调用(本例中引用打包好的jar包后会有“找不到类”的错误,故直接将该类,连同包名一同复制到另一个程序中,如)
此例子没有新定义一个专门的类来存放这些字段,而是在继承了SQLiteOpenHelper的类StudentData中定义:
package com.shutao.testsqlite2;
public class StudentData extends SQLiteOpenHelper {
/*
* 分别定义了数据库和表的名称、表中各个字段的名称、数据库的版本号
*/
public final static String DB_NAME = "student";
public final static String TABLE_NAME = "hero";
public final static String SNAME = "name";
public final static String SID = "_id";
public final static int DB_VERSION = 1;
/*
* AUTHORITY:定义了标识ContentProvider的字符串 ;
* ITEM和ITEM_ID分别用于UriMatcher(资源标识符匹配器)中对路径item和item/id的匹配号码
* CONTENT_TYPE和CONTENT_ITEM_TYPE定义了数据的MIME类型。需要注意的是: 单一数据的MIME 类型字符串应该以
* vnd.android.cursor.item/开头,数据集的MIME类型字符串应该以vnd.android.cursor.dir开头
* CONTENT_URI定义的是查询当前表数据的content://样式URI
*/
public static final String AUTHORITY = "com.shutao.testsqlite2.provider.studentdata";
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.shutao.testsqlite2.studentdata";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.shutao.testsqlite2.studentdata";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/item");
public StudentData(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(" + SID
+ " VARCHAR PRIMARY KEY," + SNAME + " VARCHAR NOT NULL);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
}
【2】接下来定义一个继承自ContentProvider的类:MyProvider.java,来实现对数据进行操作的各个方法。这里将用到StudentData来辅助得到SQLiteDatabase对象:
package com.shutao.testsqlite2;
public class MyProvider extends ContentProvider {
StudentData sd;
private static final UriMatcher sMatcher;
static {
// 传入匹配码如果大于0表示匹配根路径或传入-1,即常量UriMatcher.NO_MATCH表示不匹配根路径
// addURI()方法是用来增加其他URI匹配路径的:
// 第一个参数代表传入标识ContentProvider的AUTHORITY字符串
// 第二个参数是要匹配的路径,#代表任意数字,另外还可以用*来匹配任意文本
// 第三个参数必须传入一个大于零的匹配码,用于match()方法对相匹配的URI返回相对应的匹配码
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI(StudentData.AUTHORITY, "item", StudentData.ITEM);
sMatcher.addURI(StudentData.AUTHORITY, "item/#", StudentData.ITEM_ID);
}
/*
* 每当ContentProvider启动时都会回调onCreate()方法。此方法主要执行一些ContentProvider初始化
* 的工作,返回true表示初始化成功,返回false则初始化失败。
*/
@Override
public boolean onCreate() {
sd = new StudentData(this.getContext());
return true;
}
// getType()是用来返回数据的MIME类型的方法。使用sMatcher对URI进行匹配,并返回相应的MIME类型字符串
@Override
public String getType(Uri uri) {
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
return StudentData.CONTENT_TYPE;
case StudentData.ITEM_ID:
return StudentData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
/*
* 插入数据,返回新插入数据的URI,只接受数据集的URI,即指向表的URI
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase sdb = sd.getWritableDatabase();
long rowId;
if (sMatcher.match(uri) != StudentData.ITEM) {
throw new IllegalArgumentException("Unknow URI " + uri);
}
rowId = sdb.insert(StudentData.TABLE_NAME, StudentData.SID, values);
if (rowId > 0) {
Uri noteUri = ContentUris.withAppendedId(StudentData.CONTENT_URI,
rowId);
this.getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
/*
* 用于数据的删除,返回的是所影响数据的数目,首先利用数据库辅助对象获取一个SQLiteDatabase对象
* 然后根据传入Uri用sMatcher进行匹配,对单个数据或数据集进行删除或修改。notifyChange()方法
* 用来通知注册在次URI上的观察者(observer)数据发生了改变。
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.delete(StudentData.DB_NAME, selection, selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.delete(StudentData.DB_NAME, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
/*
* 查询数据,将数据装入一个Cursor对象并返回
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase sdb = sd.getReadableDatabase();
Cursor c;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
c = sdb.query(StudentData.TABLE_NAME, projection, selection,
selectionArgs, null, null, sortOrder);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
c = sdb.query(StudentData.TABLE_NAME, projection, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs, null, null, sortOrder);
break;
default:
Log.i("sMatcher.match(uri)", String.valueOf(sMatcher.match(uri)));
throw new IllegalArgumentException("Query with unknown URI: " + uri);
}
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// 更新,与删除类方法类似
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.update(StudentData.TABLE_NAME, values, selection,
selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.update(StudentData.DB_NAME, values, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
【3】完成以上方法以后,还要AndroidManifest.xml中对这个ContentProvider声明:
<provider
android:name="MyProvider"
android:authorities="com.shutao.testsqlite2.provider.studentdata"/>
<!-- 其中 android:name必须跟定义的ContentProvider的类名一样
android:authorities则指定了content://样式的URI中标识这个ContentProvider的字符串-->
【4】接下来在另一个程序中使用ContentResolver来操作数据:
package com.shutao.contentprovider;
public class TestContentProvider extends Activity {
private EditText stu_name;
private EditText stu_sid;
Button commit;
ListView studList;
ContentResolver resolver;
// 由于在AlertDialog中用到,所以定义为全局变量。
String sid = "";
private final int DIALOG_IN_USED = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stu_name = (EditText) this.findViewById(R.id.edit_name);
stu_sid = (EditText) this.findViewById(R.id.edit_sid);
commit = (Button) this.findViewById(R.id.butt_add);
studList = (ListView) this.findViewById(R.id.show_stud);
//【重要】得到ContentResolver()
resolver = this.getContentResolver();
String[] projection = { StudentData.SNAME, StudentData.SID };
Cursor c = resolver.query(StudentData.CONTENT_URI, null, null, null,
StudentData.SID);
CursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, c, projection, new int[] {
android.R.id.text1, android.R.id.text2 });
studList.setAdapter(adapter);
commit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!(stu_name.getText().length() > 0)) {
Toast.makeText(TestContentProvider.this,
"Please input the student's name!",
Toast.LENGTH_LONG).show();
} else if (!(stu_sid.getText().length() > 0)) {
Toast
.makeText(TestContentProvider.this,
"Please input the student's ID!",
Toast.LENGTH_LONG).show();
} else {
String name = stu_name.getText().toString();
sid = stu_sid.getText().toString();
Uri quri = Uri.parse(StudentData.CONTENT_URI + "/" + sid);
Cursor c = resolver.query(quri, null, null, null, null);
if (c.moveToFirst()) {
// 采用Toast方式提醒
/*
* Toast.makeText(TestContentProvider.this,
* "Fail to add!This ID is already in used!",
* Toast.LENGTH_LONG).show();
*/
// 采用AlertDialog方式提醒
TestContentProvider.this.showDialog(DIALOG_IN_USED);
} else {
ContentValues values = new ContentValues();
values.put(StudentData.SNAME, name);
values.put(StudentData.SID, sid);
resolver.insert(StudentData.CONTENT_URI, values);
}
}
}
});
}
//如果插入的Id已经存在则用提示框进行提示
@Override
protected Dialog onCreateDialog(int id, Bundle args) {
// // TODO Auto-generated method stub
// return super.onCreateDialog(id, args);
switch (id) {
case DIALOG_IN_USED:
return new AlertDialog.Builder(this).setTitle("Fail to add!")
.setIcon(R.drawable.fail).setMessage(
"This ID:" + sid + " is already in used!")
.setPositiveButton("确定",
// 特别注意:必须为:new DialogInterface.OnClickListener()
// 不能为new
// OnClickListener(),否则会跟View.OnClickListener冲突。
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
}
}).create();
default:
return super.onCreateDialog(id, args);
}
}
}
53、ContentProvider与ContentResolver中用到的Uri
【注】:在ContentProvider与ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据,如:
1、content://contacts/people/:这个Uri指定的就是全部联系人的数据。
2、content://contacts/people/1:这个Uri指定的就是ID为1的联系人的数据。
Uri一般由3部分组成:
1、"content://"
2、要获得数据的一个字符串片段
3、最后就是ID,如果没有ID则返回全部数据。
但因为URI通常比较长,容易出错,所以在Android当中定义了一些辅助类,并定义了一些常量来代替这些这些字符串的使用,如:
Contacts.People.CONTENT_URI:联系人的URI.
发表评论
-
startActivityForResult 简介
2011-03-29 15:55 1284依次打开Activity A1--A2--A3--A4 这时 ... -
startActivityForResult
2011-03-29 15:49 1146startActivityForResult 方法-- ... -
史上最全的Android的Tab与TabHost讲解
2011-03-28 11:22 1591Tab与TabHost 这就是Tab,而盛放Tab的 ... -
Android对话框
2011-03-25 11:21 1125Android 对话框(Dialog)大全 ... -
PreferenceActivity详解
2011-03-25 11:15 1442为了引入这个概率 首先从需求说起 即:现有某Activity专 ... -
TCP/UDP/HTTP
2011-03-25 11:09 1125先来一个讲TCP、UDP和HTTP ... -
9png
2011-03-25 11:08 1914今天学习了用9png图来优化横屏竖屏的UI,使用sdk自带的工 ... -
Notification
2011-03-25 11:07 939Android系统的状态栏(Status Bar)中有一个创新 ... -
一些技巧
2011-03-25 11:03 7861:查看是否有存储卡插入 String status=Envi ... -
布局像素单位
2011-03-25 11:03 826Android的layout文件中有时候可能会指定具体的单位, ... -
使用ActivityGroup来切换Activity和Layout
2011-03-25 11:02 1135在一个主界面中做Activity切换一般都会用TabActiv ... -
activitygroup
2011-03-25 11:01 1730说说tabhost和activitygroup 最近 ... -
线程
2011-03-25 11:01 1014今天在论坛上看到一些关于线程的帖子,我觉得与我理解的有些差异, ... -
类级框架
2011-03-25 11:00 744类集框架:Collection,Map,Iterator,En ... -
Intent打电话
2011-03-25 11:00 1217intent英文意思是意图,pending表示即将发生或来临的 ... -
Intent Uri
2011-03-25 10:59 1068进入联系人页面 1.Intent intent = new I ... -
Service
2011-03-25 10:59 939一、Service的概念 Service是Android程序中 ... -
Broadcast Receiver
2011-03-25 10:56 1948一、Broadcast Receiver简介 Android中 ... -
ContentProvider-1查询
2011-03-25 10:55 1237今天看了android的官方文档中ContentProvide ... -
ContentProvider-2modify data:insert,update,delete
2011-03-25 10:54 1200今天补充关于modify data ...
相关推荐
博客《ContentProvider数据库共享之——MIME类型与getType()》对应源码,博客地址:http://blog.csdn.net/harvic880925/article/details/44620851
ContentProvider的结构包括URI、MIME类型和Cursor,这些元素共同构成了数据操作的基础。 二、ContentProvider的主要功能 1. 数据共享:ContentProvider允许一个应用将内部数据开放给其他应用,实现了跨应用的数据...
2. MIME类型:每个ContentProvider需要定义一个或多个MIME类型来描述其提供的数据类型。例如,联系人的MIME类型通常为`vnd.android.cursor.dir/contact`和`vnd.android.cursor.item/contact`。 3. UriMatcher:为了...
MIME类型则描述了ContentProvider提供的数据类型,对于`getType()`方法至关重要。 9. **实例分析** 博文链接中提到的"sunzone.iteye.com/blog/1884167"可能详细介绍了如何根据上述步骤创建一个自定义的...
3. MIME类型:MIME类型用于标识Uri对应的数据类型,如vnd.android.cursor.dir/person用于表示一类Person数据,vnd.android.cursor.item/person表示单个Person数据。 4. CRUD操作:ContentProvider提供了insert、...
1. **了解系统Provider**:Android系统内置了一些ContentProvider,如联系人、日历等,了解它们的URI和MIME类型,这对于使用它们至关重要。 2. **获取ContentResolver**:在任何Activity、Service或者...
2. MIME类型:定义了ContentProvider提供的数据类型,如text/plain、image/jpeg等,用于描述返回的数据格式。 3. Provider类:继承自android.content.ContentProvider,需要实现其抽象方法,如query()、insert()、...
* Type(数据类型):显式指定 Intent 的数据类型(MIME)。 3. Intent 的使用 * 使用 Intent 可以启动 Activity,例如:Intent i = new Intent(Intent.ACTION_SHUTDOWN); sendBroadcast(i); 实现关机。 * 使用 ...
ContentProvider的核心在于它的 Uri(统一资源标识符)和 MIME 类型。Uri 是一个字符串,用来唯一标识要访问的数据,它由授权名、类型名以及可能的ID组成。MIME 类型则用来指定数据的类型,如文本、图片等,这样系统...
`getType`方法根据传入的URI返回一个MIME类型,用来标识URI所代表的数据类型,这对于理解请求的意图非常重要。 在ContentProvider中,数据的访问通常通过URI来控制。URI的格式一般为`content://authority/path/...
2. MIME类型:ContentProvider返回的数据类型通常用MIME类型来定义,例如vnd.android.cursor.dir/联系人用于表示一组联系人数据,vnd.android.cursor.item/联系人用于表示单个联系人数据。 二、ContentProvider的...
- `getType()`:返回指定URI对应的数据类型,常用于定义MIME类型。 5. **注册ContentProvider**:在AndroidManifest.xml文件中,声明你的ContentProvider。你需要指定它的`authorities`,这通常是你的应用包名加上...
6. `getType()`: 返回指定Uri所代表的数据的MIME类型,这对于处理多媒体数据非常有用。 在实际应用中,你需要在AndroidManifest.xml中注册ContentProvider,指定它的权限和对应的Uri模式。例如: ```xml android...
- `getType()`方法返回对应Uri的数据类型,对于MIME类型的支持。 3. **URI匹配与解析** - URI是ContentProvider的核心,它标识了数据的唯一路径。通常由两部分组成:authority和path。 - 通过`UriMatcher`类来...
5. **getType()**: 获取对应Uri的数据类型,通常用于定义MIME类型,对某些操作(如分享)是必需的。 在`ch04_TestProvider`这个示例中,我们可以看到以下步骤: 1. **创建数据库**: 首先,你需要创建一个SQLite...
`getType` 方法用于返回指定 URI 的 MIME 类型。例如,如果要获取所有 person 记录,则 URI 可能是 `"content://com.xawx.providers.personprovider/person"`,相应的 MIME 类型为 `"vnd.android.cursor.dir/person...
- `MIME类型`用于描述数据的类型,如文本、图片等,通过`getType()`方法返回。 2. **注册ContentProvider** 在AndroidManifest.xml文件中,使用`<provider>`标签注册ContentProvider,设置`android:name`为自定义...
ContentProvider可以通过MIME类型来区分不同种类的数据。 在实际开发中,使用ContentProvider的主要步骤如下: 1. **创建ContentProvider子类**:根据需求实现ContentProvider的基本功能,处理数据操作。 2. **...
5. `getType(Uri uri)`: 此方法返回对应uri的数据类型,通常用于多媒体类型的ContentProvider,返回MIME类型。 在进行ContentProvider的实践时,首先你需要创建一个继承自`android.content.ContentProvider`的类,...
MIME类型是ContentProvider用来表示返回数据类型的规范。对于ContentProvider,它告诉请求者数据的类型,例如是单个记录还是记录集合。对于单条记录,MIME类型如`vnd.android.cursor.item/vnd.your-company.content-...