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所属目录下的数据库资源。这就是一个简单的用来理解概念的实战实例。


Android ContentProvider一个不恰当的简例实战却能说明道理,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。