Android 之 ContentProvider (二) 示例代码

转载请注明出处:www.leoyanblog.com

本文出自 LeoYan 的博客

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 LeoYan 即可关注。

示例说明

ContentProviderDemo_01

  在创建ContentProvider前,首先要实现底层的数据源,数据源包括数据库、文件系统或网络等,然后继承ContentProvider类中实现基本数据操作的接口函数。调用者不能直接调用ContentProvider的接口函数,需要通过ContentResolver对象,通过URI间接调用ContentProvider。

注:示例中所选的数据源是 SQLite。

Demo 结构

  Demo结构如下:

ContentProviderDemo_02

ContentProviderDemo_03

关键代码

  People.Java (TestContentProvider 和 TestContentResolver 都有)

public class People {
    public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir";
    public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item";
    public static final String MIME_ITEM = "vnd.leo.people";

    public static final String MIME_TYPE_SINGLE = MIME_ITEM_PREFIX + "/" + MIME_ITEM;
    public static final String MIME_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/" + MIME_ITEM;

    public static final String AUTHORITY = "com.leo.peopleprovider";
    public static final String PATH_SINGLE = "people/#";
    public static final String PATH_MULTIPLE = "people";
    public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE;
    public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING);

    public static final String KEY_ID = "_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_AGE = "age";
    public static final String KEY_HEIGHT = "height";
} 

  DBOpenHelper.java (TestContentProvider 中)

public class DBOpenHelper extends SQLiteOpenHelper {

    public static final String DB_NAME = "people.db";
    public static final String DB_TABLE = "peopleinfo";
    public static final int DB_VERSION = 1;

    private static final String DB_CREATE = "create table " +
            DB_TABLE + "(" + People.KEY_ID + " integer primary key autoincrement, " +
            People.KEY_NAME + " text not null, " + People.KEY_AGE + " integer, " +
            People.KEY_HEIGHT + " float);";

    public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DB_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
        onCreate(db);
    }
}

  PeopleProvider.java (TestContentProvider 中)

public class PeopleProvider extends ContentProvider {

    private SQLiteDatabase db;
    private DBOpenHelper dbOpenHelper;

    private static final int MULTIPLE_PEOPLE = 1;
    private static final int SINGLE_PEOPLE = 2;
    private static final UriMatcher uriMatcher;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(People.AUTHORITY, People.PATH_MULTIPLE, MULTIPLE_PEOPLE);
        uriMatcher.addURI(People.AUTHORITY, People.PATH_SINGLE, SINGLE_PEOPLE);
    }

    @Override
    public boolean onCreate() {
        Context context = getContext();
        dbOpenHelper = new DBOpenHelper(context, DBOpenHelper.DB_NAME, null, DBOpenHelper.DB_VERSION);
        db = dbOpenHelper.getWritableDatabase();
        if (db == null) {
            return false;
        } else {
            return true;
        }
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(DBOpenHelper.DB_TABLE);
        switch (uriMatcher.match(uri)) {
            case SINGLE_PEOPLE:
                // 单条数据的处理
                qb.appendWhere(People.KEY_ID + "=" + uri.getPathSegments().get(1));
                break;
            default:
                break;
        }
        Cursor cursor = qb.query(db,
                projection,
                selection,
                selectionArgs,
                null,
                null,
                sortOrder);
        cursor.setNotificationUri(getContext().getContentResolver(), uri);
        return cursor;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case MULTIPLE_PEOPLE:
                // 多条数据的处理
                return People.MIME_TYPE_MULTIPLE;
            case SINGLE_PEOPLE:
                // 单条数据的处理
                return People.MIME_TYPE_SINGLE;
            default:
                throw new IllegalArgumentException("Unkown uro:" + uri);
        }
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long id = db.insert(DBOpenHelper.DB_TABLE, null, values);
        if (id > 0) {
            Uri newUri = ContentUris.withAppendedId(People.CONTENT_URI, id);
            getContext().getContentResolver().notifyChange(newUri, null);
            return newUri;
        }
        throw new SQLException("failed to insert row into " + uri);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case MULTIPLE_PEOPLE:
                // 多条数据的处理
                count = db.delete(DBOpenHelper.DB_TABLE, selection, selectionArgs);
                break;
            case SINGLE_PEOPLE:
                // 单条数据的处理
                String segment = uri.getPathSegments().get(1);
                count = db.delete(DBOpenHelper.DB_TABLE, People.KEY_ID + "=" + segment, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unsupported URI:" + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        int count;
        switch (uriMatcher.match(uri)) {
            case MULTIPLE_PEOPLE:
                // 多条数据的处理
                count = db.update(DBOpenHelper.DB_TABLE, values, selection, selectionArgs);
                break;
            case SINGLE_PEOPLE:
                // 单条数据的处理
                String segment = uri.getPathSegments().get(1);
                count = db.update(DBOpenHelper.DB_TABLE, values, People.KEY_ID + "=" + segment, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknow URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

}

  AndroidManifest.xml (TestContentProvider 中)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.leo.testcontentprovider" >
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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="com.leo.peopleprovider"
            android:name=".PeopleProvider"
            android:exported="true"/>
    </application>
</manifest>

  MainActivity.java (TestContentResolver 中)

public class MainActivity extends AppCompatActivity {

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        resolver = this.getContentResolver();
        initView();
        initEvent();
    }

    private void initView() {
        ...
    }

    private void initEvent() {
        addBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ContentValues values = new ContentValues();
                values.put(People.KEY_NAME, nameEt.getText().toString());
                values.put(People.KEY_AGE, Integer.parseInt(ageEt.getText().toString()));
                values.put(People.KEY_HEIGHT, Float.parseFloat(heightEt.getText().toString()));
                Uri newUri = resolver.insert(People.CONTENT_URI, values);
                labelTv.setText("添加成功,URI:" + newUri);
            }
        });

        queryBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEt.getText().toString());
                Cursor cursor = resolver.query(uri,
                        new String[]{People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT},
                        null, null, null);
                if (cursor == null) {
                    labelTv.setText("数据库中没有数据");
                    return;
                }
                labelTv.setText("数据库:" + String.valueOf(cursor.getCount()) + "条记录");
                String msg = "";
                if (cursor.moveToFirst()) {
                    do {
                        msg += "ID: " + cursor.getString(cursor.getColumnIndex(People.KEY_ID)) + ",";
                        msg += "姓名: " + cursor.getString(cursor.getColumnIndex(People.KEY_NAME)) + ",";
                        msg += "年龄: " + cursor.getInt(cursor.getColumnIndex(People.KEY_AGE)) + ",";
                        msg += "身高: " + cursor.getFloat(cursor.getColumnIndex(People.KEY_HEIGHT)) + "\n";
                    } while (cursor.moveToNext());
                }
                displayTv.setText(msg);
            }
        });

        queryAllBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Cursor cursor = resolver.query(People.CONTENT_URI,
                        new String[]{People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT},
                        null, null, null);
                if (cursor == null) {
                    labelTv.setText("数据库中没有数据");
                    return;
                }
                labelTv.setText("数据库:" + String.valueOf(cursor.getCount()) + "条记录");
                String msg = "";
                if (cursor.moveToFirst()) {
                    do {
                        msg += "ID: " + cursor.getString(cursor.getColumnIndex(People.KEY_ID)) + ",";
                        msg += "姓名: " + cursor.getString(cursor.getColumnIndex(People.KEY_NAME)) + ",";
                        msg += "年龄: " + cursor.getInt(cursor.getColumnIndex(People.KEY_AGE)) + ",";
                        msg += "身高: " + cursor.getFloat(cursor.getColumnIndex(People.KEY_HEIGHT)) + "\n";
                    } while (cursor.moveToNext());
                }
                displayTv.setText(msg);
            }
        });

        deleteBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEt.getText().toString());
                int count = resolver.delete(uri, null, null);
                String msg = count + " 条数据被删除";
                labelTv.setText(msg);
            }
        });

        deleteAllBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resolver.delete(People.CONTENT_URI, null, null);
                String msg = "数据全部删除";
                labelTv.setText(msg);
            }
        });

        updateBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ContentValues values = new ContentValues();
                values.put(People.KEY_NAME, nameEt.getText().toString());
                values.put(People.KEY_AGE, Integer.parseInt(ageEt.getText().toString()));
                values.put(People.KEY_HEIGHT, Float.parseFloat(heightEt.getText().toString()));
                Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEt.getText().toString());
                int result = resolver.update(uri, values, null, null);
                String msg = "更新ID为" + idEt.getText().toString() + "的数据" + (result > 0 ? "成功" : "失败");
                labelTv.setText(msg);
            }
        });
    }
}

Demo 下载

  Demo 下载地址:http://download.csdn.net/download/leoyan_blog/9783601

关注我的微信公众号,会有优质技术文章推送。

微信扫一扫下方二维码即可关注:
公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值