Android ContentProvider学习

ContentProvider介绍:

Android ContentProvider是数据对外的接口,我们只需通过使用ContentProvider访问数据而不需要关心数据具体的存储及访问过程,这样既提高了数据的访问效率,同时也保护了数据。Activity类中有一个继承自ContentWapper的getContentResolver()无参数方法,该方法返回一个ContentResolver对象,通过调用其query、insert、update、delete方法访问数据。这几个方法的第一个参数均为URI型,用来标识资源。

总结:
1、ContentProvider为存储和读取数据提供了统一的接口
2、使用ContentProvider,应用程序可以实现数据共享
3、android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)

Uri介绍:

1、每一个ContentProvider都拥有一个公共的Uri,这个Uri用于表示这个ContentProvider提供的数据
2、Android所提供的ContentProvider都存放在andriod.provider这个包里面

Android的ContentProvider URI有固定的形式:content://contract/people

前缀:固定为content : //
认证:contract 资源的唯一标识符
路径:people 具体的资源类型

在Android中广泛应用URI,而不是URL。URL标识资源的物理位置,相当于文件的路径;而URI则是标识资源的逻辑位置,并不提供资源的具体位置。比如说电话薄中的数据,如果用URL来标识的话,可能会是一个很复杂的文件结构,而且一旦文件的存储路径改变,URL也必须得改动。但是若是URI,则可以用诸如content://contract/people这样容易记录的逻辑地址来标识,而且并不需要关心文件的具体位置,即使文件位置改动也不需要做变化,当然这都是对于用户来说,后台程序中URI到具体位置的映射还是需要程序员来改动的。

ContentProvider提供的函数:

1、query() 查询
2、insert() 插入
3、update() 更新
4、delete() 删除
5、getType() 得到数据类型
6、onCreate() 创建时的回调函数

实现ContentProvider的过程:

1、定义一个COTENT_URI常量
2、定义一个类,继承ContentProvider
3、实现query(),delete(),update(),insert(),onCreate(),getType()方法
4、在AndroidMainfest.xml中申明

下面以两个实例(一个是ContentProvider所在的应用,另一个是使用ContentProvider的应用),说明如何使用ContentProvider

ContentProvider所在的应用

1、定义一个类,里面定义一些常量

package com.yyl.android; 
  
import android.net.Uri; 
import android.provider.BaseColumns; 
  
public class MyUsers { 
  
    public static final String AUTHORITY = "com.yyl.android.MyContentProvider"; 
  
    // BaseColumn类中已经包含了_id字段 
    public static final class User implements BaseColumns { 
        // 定义Uri 
        public static final Uri CONTENT_URI = Uri.parse("content://"
                + AUTHORITY); 
        // 定义数据表列 
        public static final String USER_NAME = "USER_NAME"; 
    } 
  
}


 

2、定义一个继承ContentProvider的子类,实现其方法

package com.yyl.android; 
  
import android.content.ContentProvider; 
import android.content.ContentUris; 
import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.database.sqlite.SQLiteQueryBuilder; 
import android.net.Uri; 
  
/** 
 * MyContentProvider继承ContentProvider类,实现其insert,update,delete,getType,onCreate等方法 
 */
public class MyContentProvider extends ContentProvider { 
  
    // 定义一个SQLiteDatabase变量 
    private SQLiteDatabase sqlDB; 
    // 定义一个DatabaseHelper变量 
    private DatabaseHelper dbHelper; 
    // 数据库名 
    private static final String DATABASE_NAME = "Users.db"; 
    // 数据库版本 
    private static final int DATABASE_VERSION = 1; 
    // 表名 
    private static final String TABLE_NAME = "User"; 
    // 标签 
    private static final String TAG = "MyContentProvider"; 
  
    /** 
     * 定义一个内部类 
     *  
     * 这个内部类继承SQLiteOpenHelper类,重写其方法 
     */
    public static class DatabaseHelper extends SQLiteOpenHelper { 
  
        // 构造方法 
        public DatabaseHelper(Context context) { 
            // 父类构造方法 
            super(context, DATABASE_NAME, null, DATABASE_VERSION); 
        } 
  
        // 当第一次创建数据库的时候调用该方法,可以为数据库增加一些表,和初始化一些数据 
        @Override
        public void onCreate(SQLiteDatabase db) { 
            // 在数据库里生成一张表 
            db.execSQL("Create table "
                    + TABLE_NAME 
                    + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);"); 
        } 
  
        // 当更新数据库版本的时候,调用该方法。可以删除,修改表的一些信息 
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
            onCreate(db); 
  
        } 
  
    } 
  
    // 这是一个回调函数,当生成所在类的对象时,这个方法被调用,创建一个数据库 
    @Override
    public boolean onCreate() { 
        dbHelper = new DatabaseHelper(getContext()); 
        return (dbHelper == null) ? false : true; 
    } 
  
    // 查询 
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, 
            String[] selectionArgs, String sortOrder) { 
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 
        SQLiteDatabase db = dbHelper.getReadableDatabase(); 
        qb.setTables(TABLE_NAME); 
        Cursor c = qb.query(db, projection, selection, null, null, null, 
                sortOrder); 
        c.setNotificationUri(getContext().getContentResolver(), uri); 
        return c; 
    } 
  
    // 取得类型 
    @Override
    public String getType(Uri uri) { 
        return null; 
    } 
  
    // 插入数据 
    @Override
    public Uri insert(Uri uri, ContentValues contentvalues) { 
        sqlDB = dbHelper.getWritableDatabase(); 
        long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues); 
        if (rowId > 0) { 
            Uri rowUri = ContentUris.appendId( 
                    MyUsers.User.CONTENT_URI.buildUpon(), rowId).build(); 
            getContext().getContentResolver().notifyChange(rowUri, null); 
            return rowUri; 
        } 
        throw new SQLException("Failed to insert row into" + uri); 
    } 
  
    // 删除数据 
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) { 
        return 0; 
    } 
  
    // 更新数据 
    @Override
    public int update(Uri uri, ContentValues values, String selection, 
            String[] selectionArgs) { 
        return 0; 
    } 
  
}


 

3、定义一个默认加载的Activity,里面对ContentProvider进行数据加载

package com.yyl; 
  
import com.yyl.android.MyUsers; 
import android.app.Activity; 
import android.content.ContentValues; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.Bundle; 
import android.widget.Toast; 
  
public class MyContentDemo extends Activity { 
  
    @Override
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        insertRecord("MyUser"); 
        insertRecord("YangYuLin"); 
        displayRecords(); 
    } 
  
    private void insertRecord(String userName) { 
        ContentValues values = new ContentValues(); 
        values.put(MyUsers.User.USER_NAME, userName); 
        getContentResolver().insert(MyUsers.User.CONTENT_URI, values); 
    } 
  
    private void displayRecords() { 
        String columns[] = new String[] { MyUsers.User._ID, 
                MyUsers.User.USER_NAME }; 
        Uri myUri = MyUsers.User.CONTENT_URI; 
        Cursor cur = managedQuery(myUri, columns, null, null, null); 
        if (cur.moveToFirst()) { 
            String id = null; 
            String userName = null; 
            do { 
                id = cur.getString(cur.getColumnIndex(MyUsers.User._ID)); 
                userName = cur.getString(cur 
                        .getColumnIndex(MyUsers.User.USER_NAME)); 
                Toast.makeText(this, id + " " + userName, Toast.LENGTH_LONG) 
                        .show(); 
            } while (cur.moveToNext()); 
        } 
    } 
}


 

4、在AndroidMainfest.xml里注册

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yyl" android:versionCode="1" android:versionName="1.0"> 
    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
        <provider android:name=".android.MyContentProvider"
            android:authorities="com.yyl.android.MyContentProvider" /> 
        <activity android:name=".MyContentDemo" android:label="@string/app_name"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
  
    </application> 
    <uses-sdk android:minSdkVersion="7" /> 
</manifest>


 

做另一个App.使用上面ContentProvider提供的数据

package yyl.client; 
  
import android.app.Activity; 
import android.content.ContentResolver; 
import android.content.ContentValues; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.Bundle; 
import android.text.Editable; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
  
public class CPClientActitity extends Activity { 
  
    public static final String AUTHORITY = "com.yyl.android.MyContentProvider"; 
    private Button insertButton = null; 
    // 访问ContentProvider的Uri 
    Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY); 
  
    @Override
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
  
        // 得到ContentProvider对于表的所有数据,以游标格式保存 
        Cursor c = managedQuery(CONTENT_URI, 
                new String[] { "_id", "USER_NAME" }, null, null, null); 
  
        // 循环打印ContentProvider的数据 
        if (c.moveToFirst()) { 
            String _id = null; 
            String user_name = null; 
  
            do { 
                // 得到_id列,USER_NAME列 
                _id = c.getString(c.getColumnIndex("_id")); 
                user_name = c.getString(c.getColumnIndex("USER_NAME")); 
  
                System.out.println("_id = " + _id + ", user_name = "
                        + user_name); 
  
            } while (c.moveToNext()); 
        } 
  
        // 根据Id得到控件对象 
        insertButton = (Button) findViewById(R.id.Insert); 
        // 给按钮绑定事件监听器 
        insertButton.setOnClickListener(new View.OnClickListener() { 
  
            @Override
            public void onClick(View v) { 
  
                // 得到EditText输入的数据 
                String username = ((EditText) findViewById(R.id.userName)) 
                        .getText().toString(); 
                // 生成一个ContentResolver对象 
                ContentResolver cr = getContentResolver(); 
                // 生成一个ContentValues对象 
                ContentValues values = new ContentValues(); 
                // 将EditText输入的值,保存到ContentValues对象中 
                values.put("USER_NAME", username); 
                // 插入数据 
                cr.insert(CONTENT_URI, values); 
            } 
        }); 
    } 
}


 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值