ContentProvider例子

 MyHelper.java
public class MyHelper 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 MyHelper(Context context)
	{
		super(context, DB_NAME, null, DB_VERSION);
		// TODO Auto-generated constructor stub
	}

	@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 oldVersion, int newVersion)
	{
		db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
		onCreate(db);
	}

}

 

MyProvider.java
public class MyProvider extends ContentProvider
{
	MyHelper myHelper;
	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(MyHelper.AUTHORITY, "item", MyHelper.ITEM);
		sMatcher.addURI(MyHelper.AUTHORITY, "item/#", MyHelper.ITEM_ID);
	}

	/*
	 * 每当ContentProvider启动时都会回调onCreate()方法。此方法主要执行一些ContentProvider初始化
	 * 的工作,返回true表示初始化成功,返回false则初始化失败。
	 */
	@Override
	public boolean onCreate()
	{
		myHelper = new MyHelper(this.getContext());
		return true;
	}

	// getType()是用来返回数据的MIME类型的方法。使用sMatcher对URI进行匹配,并返回相应的MIME类型字符串
	@Override
	public String getType(Uri uri)
	{
		switch (sMatcher.match(uri))
		{
			case MyHelper.ITEM:
				return MyHelper.CONTENT_TYPE;
			case MyHelper.ITEM_ID:
				return MyHelper.CONTENT_ITEM_TYPE;
			default:
				throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	/*
	 * 插入数据,返回新插入数据的URI,只接受数据集的URI,即指向表的URI
	 */
	@Override
	public Uri insert(Uri uri, ContentValues values)
	{
		SQLiteDatabase sdb = myHelper.getWritableDatabase();
		long rowId;
		if (sMatcher.match(uri) != MyHelper.ITEM)
		{
			throw new IllegalArgumentException("Unknow URI " + uri);
		}
		rowId = sdb.insert(MyHelper.TABLE_NAME, MyHelper.SID, values);
		if (rowId > 0)
		{
			Uri noteUri = ContentUris.withAppendedId(MyHelper.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 = myHelper.getWritableDatabase();
		int count;
		switch (sMatcher.match(uri))
		{
			case MyHelper.ITEM:
				count = sdb.delete(MyHelper.DB_NAME, selection, selectionArgs);
				break;
			case MyHelper.ITEM_ID:
				String id = uri.getPathSegments().get(1);
				count = sdb.delete(MyHelper.DB_NAME, MyHelper.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 = myHelper.getReadableDatabase();
		Cursor c;
		switch (sMatcher.match(uri))
		{
			case MyHelper.ITEM:
				c = sdb.query(MyHelper.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
				break;
			case MyHelper.ITEM_ID:
				String id = uri.getPathSegments().get(1);
				c = sdb.query(MyHelper.TABLE_NAME, projection, MyHelper.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 = myHelper.getWritableDatabase();
		int count;
		switch (sMatcher.match(uri))
		{
			case MyHelper.ITEM:
				count = sdb.update(MyHelper.TABLE_NAME, values, selection, selectionArgs);
				break;
			case MyHelper.ITEM_ID:
				String id = uri.getPathSegments().get(1);
				count = sdb.update(MyHelper.DB_NAME, values, MyHelper.SID + "=" + id
						+ (!TextUtils.isEmpty(selection) ? " AND (" + selection + ")" : ""), selectionArgs);
				break;
			default:
				throw new IllegalArgumentException("Unknown URI " + uri);
		}
		this.getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

}

TestContentProvider.java
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 = { MyHelper.SNAME, MyHelper.SID };
		Cursor c = resolver.query(MyHelper.CONTENT_URI, null, null, null, MyHelper.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(MyHelper.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(MyHelper.SNAME, name);
						values.put(MyHelper.SID, sid);
						resolver.insert(MyHelper.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.ic_launcher)
						.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);
		}
	}
}

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/butt_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <EditText
        android:id="@+id/edit_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </EditText>


    <EditText
        android:id="@+id/edit_sid"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <ListView
        android:id="@+id/show_stud"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="14" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".TestContentProvider" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:authorities="com.shutao.testsqlite2.provider.studentdata"
            android:name=".MyProvider" />
    </application>

</manifest>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值