当前位置: 代码迷 >> Android >> Android ContentProvider一个不恰当的简例实战却能说明情理
  详细解决方案

Android ContentProvider一个不恰当的简例实战却能说明情理

热度:25   发布时间:2016-04-28 06:42:38.0
Android ContentProvider一个不恰当的简例实战却能说明道理

周末了,闲来无事看了网上几篇大神的博客,写的不错,适合入门,遂自己建了一个工程按照自己想法捣腾了一阵子,就有了下边代码的诞生。特别感谢这几篇博文,有了牛人博文在也用买书了,全是干货,麻麻、爸比再也不用担心我的学习了!

致谢:Android四大组件介绍 里面对方法参数的汉语注释简直就是雪中送炭,同事我把你的汉语注释部分copy到了我的方法上(方便日后查阅,哈哈)。

ContentProvider是Android在不同应用程序之间实现数据共享的一种机制。一个应用如果需要让别的程序可以操作自己的数据,即可采用这种机制。并且此种方式忽略了底层的数据存储实现,ContentProvider提供了一种统一的通过Uri实现数据操作的方式。其步骤为:1. 在当前应用程序中定义一个ContentProvider。2. 在当前应用程序的AndroidManifest.xml中注册此ContentProvider。3. 其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据。ContentResolver提供了诸如insert(), delete(), query()和update()之类的方法。用于实现对ContentProvider中数据的存取操作。

Uri是一个通用资源标志符,将其分为A,B,C,D 4个部分:1、无法改变的标准前缀,包括;"content://"、"tel://"等。当前缀是"content://"时,说明通过一个Content Provider控制这些数据。2、URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的   类名。例如;"content://com.jesse.myprovider"。3、路径,可以近似的理解为需要操作的数据库中表的名字,如:"content://yb.android.jesse.myprovider/name"中的name。4、如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部。

ContentProvider这种存储方式相比SQLite和SharedPreferences,其复杂性太明显了,但是在处处可见“云端服务”的今天(不是“莞式服务”(哈哈))数据交互需求使得ContentProvider越来也特么重要了。

上代码:功能:contentprovidertest这个apk提供通过ContentProvider创建数据源(类似云端),contentresolvertest这个apk用来取数据显示。重点之重点已经红色高亮了。

contentprovidertest apk代码:

MainActivity.java

package com.example.contentprovidertest;import android.os.Bundle;import android.app.Activity;public class MainActivity extends Activity {	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				MyContentProvider contentProvider = new MyContentProvider();	}}

MyContentProvider.java

package com.example.contentprovidertest;import android.content.ContentProvider;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;public class MyContentProvider extends ContentProvider {	private static final String DBASE_TABLE_NAME = "tel_number_tab";	private static final String DBASE_FILE_NAME = "StudyContentProvider.db";		/**	 * 初始化操作	 */	public boolean onCreate() {		// TODO Auto-generated method stub	    SQLiteDatabase mDataBase = this.getContext().openOrCreateDatabase(DBASE_FILE_NAME, Context.MODE_PRIVATE, null);		mDataBase.execSQL("CREATE TABLE " +DBASE_TABLE_NAME+ " (_id INTEGER PRIMARY KEY AUTOINCREMENT, tel_num TEXT NOT NULL)");		//模拟数据方法调运		insertDbaseData(mDataBase);		mDataBase.close();		return true;	}	/**     * 从内容提供者中删除数据(允许其他应用删除你应用的数据时重写)     * @param uri     * @param selection 条件语句     * @param selectionArgs 参数     * @return     */	public int delete(Uri uri, String selection, String[] selectionArgs) {		// TODO Auto-generated method stub		return 0;	}	/**     * 用于返回当前Uri所代表数据的MIME类型     * 如果操作的数据为集合类型(多条数据),那么返回的类型字符串应该为vnd.android.cursor.dir/开头     * 例如要得到所有person记录的Uri为content://com.bravestarr.provider.personprovider/person,  	 * 那么返回的MIME类型字符串应该为"vnd.android.cursor.dir/person"     * 如果操作的数据为单一数据,那么返回的类型字符串应该为vnd.android.cursor.item/开头     * 例如要得到id为10的person记录的Uri为content://com.bravestarr.provider.personprovider/person/10,         * 那么返回的MIME类型字符串应该为"vnd.android.cursor.item/person"     * @param uri     */	public String getType(Uri uri) {		// TODO Auto-generated method stub		return null;	}	/**     * 插入数据到内容提供者(允许其他应用向你的应用中插入数据时重写)     * @param uri     * @param initialValues 插入的数据     * @return     */	public Uri insert(Uri uri, ContentValues values) {		// TODO Auto-generated method stub		return null;	}	/**     * 返回数据给调用者(允许其他应用从你的应用中获取数据时重写)     * @param uri     * @param projection 列名     * @param selection 条件语句     * @param selectionArgs 参数     * @param sortOrder 排序     * @return     */	public Cursor query(Uri uri, String[] projection, String selection,			String[] selectionArgs, String sortOrder) {		// TODO Auto-generated method stub		SQLiteDatabase mDataBase = this.getContext().openOrCreateDatabase(DBASE_FILE_NAME, Context.MODE_PRIVATE, null);		Cursor cursor = mDataBase.query(DBASE_TABLE_NAME, null, null, null, null, null, null);		return cursor;	}	 /**     * 更新内容提供者已存在的数据(允许其他应用更新你应用的数据时重写)     * @param uri     * @param values 更新的数据     * @param selection 条件语句     * @param selectionArgs 参数     * @return     */	public int update(Uri uri, ContentValues values, String selection,			String[] selectionArgs) {		// TODO Auto-generated method stub		return 0;	}	//--------------------------------------------------------------------------------	//Jesse逻辑模拟产生电话号码数据库数据方法	private void insertDbaseData(SQLiteDatabase db)	{		for (int index=0; index<5; index++)		{			ContentValues values =new ContentValues();			values.put("tel_num", "156999999" + index + (index+1));			db.insert(DBASE_TABLE_NAME, "_id", values);		}	}}

AndroidMainifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.contentprovidertest"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="17"        android:targetSdkVersion="18" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.example.contentprovidertest.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>                <provider android:name=".MyContentProvider"             		android:exported="true"              		android:authorities="com.example.MyContentProvider"/>            </application></manifest>

contentresolvertest apk代码:

MainActivity.java

package com.jesse.contentresolvertest;import android.net.Uri;import android.os.Bundle;import android.widget.TextView;import android.app.Activity;import android.content.ContentResolver;import android.content.Context;import android.database.Cursor;public class MainActivity extends Activity {	private Context mContext;	private TextView mTextView;	private String mTelNum = "";	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				mContext = MainActivity.this;		mTextView = (TextView) this.findViewById(R.id.tel);        ContentResolver resolver = mContext.getContentResolver();        Uri uri = Uri.parse("content://com.example.MyContentProvider");        Cursor cursor = resolver.query(uri, null, null, null, null);        cursor.moveToFirst();        for(int i=0; i<cursor.getCount(); i++){        	int index = cursor.getColumnIndexOrThrow("tel_num");            String src = cursor.getString(index);            mTelNum = mTelNum + src + "\n";            cursor.moveToNext();        }                cursor.close();                mTextView.setText(mTelNum);	}}

说明:contentprovidertest apk运行后产生数据库和对外声明的URL,contentresolvertest apk通过URL访问不是自己apk所属目录下的数据库资源。这就是一个简单的用来理解概念的实战实例。


  相关解决方案