ContentProvider demo

本文介绍了一个基于Android平台的简单应用程序,演示了如何使用ContentProvider进行数据库的增删查改操作。包括创建数据库、定义数据表结构、实现CRUD功能等核心步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、DataBaseTest/app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="example.com.databasetest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            android:authorities="example.com.databasetest"
            android:name=".TeacherContentProvider"
            android:grantUriPermissions="true"/>
    </application>

</manifest>

2、布局文件:DataBaseTest/app/src/main/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="example.com.databasetest.MainActivity">

    <Button
        android:text="insert"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="13dp"
        android:id="@+id/insert"
        android:onClick="iinsertTeacher"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true" />

    <Button
        android:text="querys"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/query"
        android:layout_alignParentStart="true"
        android:id="@+id/querys"
        android:onClick="querysTeacher" />

    <Button
        android:text="query"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/query"
        android:onClick="queryTeacher"
        android:layout_below="@+id/insert"
        android:layout_alignParentStart="true" />

    <Button
        android:text="update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/update"
        android:layout_below="@+id/querys"
        android:layout_alignParentStart="true"
        android:onClick="updateTeacher" />

    <Button
        android:text="delete"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/delete"
        android:onClick="deleteTeacher"
        android:layout_below="@+id/update"
        android:layout_alignParentStart="true" />
</RelativeLayout>

3、显示页面:DataBaseTest/app/src/main/java/example/com/databasetest/MainActivity.java

package example.com.databasetest;

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.util.Log;
import android.view.View;

import java.util.Date;

public class MainActivity extends Activity {

    Uri uri = Uri.parse("content://example.com.databasetest/teacher");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void iinsertTeacher(View v) {
        ContentResolver cr = getContentResolver();
        ContentValues cv = new ContentValues();
        cv.put("title", "jiaoshou");
        cv.put("name", "jiaoshi");
        cv.put("sex", true);
        Log.e("myy","iinsertTeacher(View v)");
        Uri uri2 = cr.insert(uri, cv);
        System.out.println(uri2.toString());
    }

    public void querysTeacher(View v) {
        ContentResolver cr = getContentResolver();
        // 查找id1的数据
        Cursor c = cr.query(uri, null, null, null, null);
        System.out.println(c.getCount());
        c.close();
    }

    public void queryTeacher(View v) {
        ContentResolver cr = getContentResolver();
        // 查找id1的数据
        Cursor c = cr.query(uri, null, "_ID=?", new String[]{"1"}, null);
        //这里必须要调用 c.moveToFirst将游标移动到第一条数据,不然会出现index -1 requested , with a size of 1错误;cr.query返回的是一个结果集。
        if (c.moveToFirst() == false) {
            return;
        }
        int name = c.getColumnIndex("name");
        System.out.println(c.getString(name));
        c.close();
    }

    public void updateTeacher(View v) {
        ContentResolver cr = getContentResolver();
        ContentValues cv = new ContentValues();
        cv.put("name", "huangbiao");
        cv.put("date_added", (new Date()).toString());
        int uri2 = cr.update(uri, cv, "_ID=?", new String[]{"3"});
        System.out.println("updated" + ":" + uri2);
    }

    public void deleteTeacher(View v) {
        ContentResolver cr = getContentResolver();
        cr.delete(uri, "_ID=?", new String[]{"2"});
    }
}

4、创建常量:DataBaseTest/app/src/main/java/example/com/databasetest/ContentData.java

package example.com.databasetest;

import android.content.UriMatcher;
import android.net.Uri;
import android.provider.BaseColumns;

/**
 * Created by myy on 18-7-2.
 */

public class ContentData {

    public static final String AUTHORITY = "example.com.databasetest";
    public static final String DATABASE_NAME = "teacher.db";
    //创建 数据库的时候,都必须加上版本信息;并且必须大于4
    public static final int DATABASE_VERSION = 4;
    public static final String USERS_TABLE_NAME = "teacher";

    public static final class UserTableData implements BaseColumns {
        public static final String TABLE_NAME = "teacher";
        //Uri,外部程序需要访问就是通过这个Uri访问的,这个Uri必须的唯一的。
        public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY + "/teacher");
        // 数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/example.com.teachers";
        // 单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头
        public static final String CONTENT_TYPE_ITME = "vnd.android.cursor.item/example.com.teacher";
        /* 自定义匹配码 */
        public static final int TEACHERS = 1;
        /* 自定义匹配码 */
        public static final int TEACHER = 2;

        public static final String TITLE = "title";
        public static final String NAME = "name";
        public static final String DATE_ADDED = "date_added";
        public static final String SEX = "SEX";
        public static final String DEFAULT_SORT_ORDER = "_id desc";

        public static final UriMatcher uriMatcher;
        static {
            // 常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
            uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
            // 如果match()方法匹配content://hb.android.teacherProvider/teachern路径,返回匹配码为TEACHERS
            uriMatcher.addURI(ContentData.AUTHORITY, "teacher", TEACHERS);
            // 如果match()方法匹配content://hb.android.teacherProvider/teacher/230,路径,返回匹配码为TEACHER
            uriMatcher.addURI(ContentData.AUTHORITY, "teacher/#", TEACHER);
        }
    }
}

5、创建数据库:DataBaseTest/app/src/main/java/example/com/databasetest/DBOpenHelper.java

package example.com.databasetest;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;


/**
 * Created by myy on 18-7-2.
 */

public class DBOpenHelper extends SQLiteOpenHelper {

    // SQLiteOepnHelper的子类当中,必须有该构造函数,用来创建一个数据库;
    public DBOpenHelper(Context context, String name, CursorFactory factory,
                        int version) {
        // 必须通过super调用父类当中的构造函数
        super(context, name, factory, version);
        // TODO Auto-generated constructor stub
    }

    // public DBOpenHelper(Context context, String name) {
    // this(context, name, VERSION);
    // }

    public DBOpenHelper(Context context, String name, int version) {
        this(context, name, null, version);
    }

    /**
     * 只有当数据库执行创建 的时候,才会执行这个方法。如果更改表名,也不会创建,只有当创建数据库的时候,才会创建改表名之后 的数据表
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.e("myy","DBOpenHelper--->Create database" );
        db.execSQL("CREATE TABLE IF NOT EXISTS " + ContentData.UserTableData.TABLE_NAME
                + "(" + ContentData.UserTableData._ID
                + " INTEGER PRIMARY KEY autoincrement,"
                + ContentData.UserTableData.NAME + " varchar(20),"
                + ContentData.UserTableData.TITLE + " varchar(20),"
                + ContentData.UserTableData.DATE_ADDED + " long,"
                + ContentData.UserTableData.SEX + " boolean)" + ";");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}

6、重写privoder:DataBaseTest/app/src/main/java/example/com/databasetest/TeacherContentProvider.java

package example.com.databasetest;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import static example.com.databasetest.ContentData.UserTableData.TEACHER;
import static example.com.databasetest.ContentData.UserTableData.TEACHERS;
import static example.com.databasetest.ContentData.UserTableData.CONTENT_TYPE;
import static example.com.databasetest.ContentData.UserTableData.CONTENT_TYPE_ITME;


/**
 * Created by myy on 18-7-2.
 */

public class TeacherContentProvider extends ContentProvider {
    private DBOpenHelper dbOpenHelper = null;
    // UriMatcher类用来匹配Uri,使用match()方法匹配路径时返回匹配码
    private static final UriMatcher uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);

    /**
     * 是一个回调函数,在ContentProvider创建的时候,就会运行,第二个参数为指定数据库名称,如果不指定,就会找不到数据库;
     * 如果数据库存在的情况下是不会再创建一个数据库的。(当然首次调用 在这里也不会生成数据库必须调用SQLiteDatabasegetWritableDatabase,getReadableDatabase两个方法中的一个才会创建数据库)
     */
    @Override
    public boolean onCreate() {
        Log.e("myy","TeacherContentProvider--->Create database" );
        //这里会调用 DBOpenHelper的构造函数创建一个数据库;
        dbOpenHelper = new DBOpenHelper(this.getContext(), ContentData.DATABASE_NAME, ContentData.DATABASE_VERSION);
        return true;
    }
    /**
     * 当执行这个方法的时候,如果没有数据库,他会创建,同时也会创建表,但是如果没有表,下面在执行insert的时候就会出错
     * 这里的插入数据也完全可以用sql语句书写,然后调用 db.execSQL(sql)执行。
     */
    @Override
    public Uri insert(Uri uri, ContentValues values){
        Log.e("myy","TeacherContentProvider---insert(),uriMatcher.match(uri):" + uriMatcher.match(uri) );
        //获得一个可写的数据库引用,如果数据库不存在,则根据onCreate的方法里创建;
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        long id = 0;

        switch (uriMatcher.match(uri)) {
            case TEACHERS:
                id = db.insert("teacher", null, values);    // 返回的是记录的行号,主键为int,实际上就是主键值
                return ContentUris.withAppendedId(uri, id);
            case TEACHER:
                id = db.insert("teacher", null, values);
                String path = uri.toString();
                return Uri.parse(path.substring(0, path.lastIndexOf("/"))+id); // 替换掉id
            default:
                Log.e("myy","TeacherContentProvider---insert(),throw new IllegalArgumentException(\"Unknown URI \" + uri)"  );
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case TEACHERS:
                count = db.delete("teacher", selection, selectionArgs);
                break;
            case TEACHER:
                // 下面的方法用于从URI中解析出id,对这样的路径content://hb.android.teacherProvider/teacher/10
                // 进行解析,返回值为10
                long personid = ContentUris.parseId(uri);
                String where = "_ID=" + personid;    // 删除指定id的记录
                where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";    // 把其它条件附加上
                count = db.delete("teacher", where, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        db.close();
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case TEACHERS:
                count = db.update("teacher", values, selection, selectionArgs);
                break;
            case TEACHER:
                // 下面的方法用于从URI中解析出id,对这样的路径content://com.ljq.provider.personprovider/person/10
                // 进行解析,返回值为10
                long personid = ContentUris.parseId(uri);
                String where = "_ID=" + personid;// 获取指定id的记录
                where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它条件附加上
                count = db.update("teacher", values, where, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        db.close();
        return count;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case TEACHERS:
                return CONTENT_TYPE;
            case TEACHER:
                return CONTENT_TYPE_ITME;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        switch (uriMatcher.match(uri)) {
            case TEACHERS:
                return db.query("teacher", projection, selection, selectionArgs, null, null, sortOrder);
            case TEACHER:
                // 进行解析,返回值为10
                long personid = ContentUris.parseId(uri);
                String where = "_ID=" + personid;// 获取指定id的记录
                where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它条件附加上
                return db.query("teacher", projection, where, selectionArgs, null, null, sortOrder);
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }
}
还未调通,待debug。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值