Fork me on GitHub

android四大组件之ContentProvider(二)

ContentProvider学习笔记

  上一章节我们编写了自定义的一个StudentProvider,他提供了两种供外界访问数据的方式,content://come.demo.sqlite.studentprovider/t_student和content://come.demo.sqlite.studentprovider/t_student/#,这一章我们将讲解其他应用程序将如何来访问StudentProvider中的数据。

1、ContentResolver类介绍

  我们知道StudentProvider继承了ContentProvider类,并实现了insert(),update(),delete(),query(),getType()等方法,同样的ContentResolver这个类也提供了insert(),update(),delete(),query()方法,当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法

  ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
    public Uri insert(Uri uri, ContentValues values):该方法用于往ContentProvider添加数据。
    public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于从ContentProvider删除数据。
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):该方法用于更新ContentProvider中的数据。
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):该方法用于从ContentProvider中获取数据。

2、实例:对数据库表t_student的增删改查操作

(1)布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <Button 
        android:id="@+id/btnAdd1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="插入数据1"
        />
    
    <Button 
        android:id="@+id/btnAdd2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="插入数据2"
        />
    
    <Button 
        android:id="@+id/btnSearch1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="查询数据1"
        />
    
    <Button 
        android:id="@+id/btnSearch2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="查询数据2"
        />
    
    <Button 
        android:id="@+id/btnUpdate1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="修改数据1"
        />
    
    <Button 
        android:id="@+id/btnUpdate2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="修改数据2"
        />
    
    <Button 
        android:id="@+id/btnDelete1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="删除数据1"
        />
    
    <Button 
        android:id="@+id/btnDelete2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="删除数据2"
        />

</LinearLayout>

(2)MainActivity来实现具体的操作

package com.demo.contentprovider;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
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 android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

/**
 * 使用ContentResolver实现对数据库表t_student的操作
 * @author yinbenyang
 */
public class MainActivity extends Activity {

    private Button btnAdd1, btnAdd2, btnSearch1, btnSearch2, btnUpdate1,
            btnUpdate2, btnDelete1, btnDelete2;

    //匹配content://come.demo.sqlite.studentprovider/t_student路径
    private static final int ONE = 1;
    //匹配content://come.demo.sqlite.studentprovider/t_student/
    private static final int TWO = 2;
    //日志输出
    private static final String TAG = "ContentProvider";
    //定义的一个Uri,这个是StudentProvider提供的一个内容提供者
    private static String CONTENT_URI = "content://come.demo.sqlite.studentprovider/t_student";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnAdd1 = (Button) findViewById(R.id.btnAdd1);
        btnAdd2 = (Button) findViewById(R.id.btnAdd2);
        btnUpdate1 = (Button) findViewById(R.id.btnUpdate1);
        btnUpdate2 = (Button) findViewById(R.id.btnUpdate2);
        btnSearch1 = (Button) findViewById(R.id.btnSearch1);
        btnSearch2 = (Button) findViewById(R.id.btnSearch2);
        btnDelete1 = (Button) findViewById(R.id.btnDelete1);
        btnDelete2 = (Button) findViewById(R.id.btnDelete2);

        btnAdd1.setOnClickListener(listener);
        btnAdd2.setOnClickListener(listener);
        btnUpdate1.setOnClickListener(listener);
        btnUpdate2.setOnClickListener(listener);
        btnSearch1.setOnClickListener(listener);
        btnSearch2.setOnClickListener(listener);
        btnDelete1.setOnClickListener(listener);
        btnDelete2.setOnClickListener(listener);
    }

    private OnClickListener listener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btnAdd1:
                add(ONE);
                break;
            case R.id.btnAdd2:
                add(TWO);
                break;
            case R.id.btnUpdate1:
                update(ONE);
                break;
            case R.id.btnUpdate2:
                update(TWO);
                break;
            case R.id.btnDelete1:
                delete(ONE);
                break;
            case R.id.btnDelete2:
                delete(TWO);
                break;
            case R.id.btnSearch1:
                search(ONE);
                break;
            case R.id.btnSearch2:
                search(TWO);
                break;
            default:
                break;
            }
        }
    };

    // 查询数据
    private void search(int type) {
        ContentResolver resolver = getContentResolver();
        Uri url = null;
        // 指定查询的列名
        String projection[] = new String[] { "sid", "sname", "age" };
        // 查询的条件
        String selection = "";
        // 查询条件的参数值
        String[] selectionArgs = null;
        // 指定是否排序以及使用排序是时的排序规则
        String sortOrder = "";
        // 查询结果为一个Cursor
        Cursor cursor = null;
        switch (type) {
        case ONE:
            // parse方法通过传入一个字符串来构造一个Uri对象
            url = Uri.parse(CONTENT_URI);
            selection = "sid < ?";
            selectionArgs = new String[] { "3" };
            cursor = resolver.query(url, projection, selection, selectionArgs,
                    sortOrder);
            while (cursor.moveToNext()) {
                Log.i(TAG,
                        "sid=" + cursor.getInt(0) + ",sname="
                                + cursor.getString(1) + ",age="
                                + cursor.getShort(2));
                Toast.makeText(
                        this,
                        "sid=" + cursor.getInt(0) + ",sname="
                                + cursor.getString(1) + ",age="
                                + cursor.getShort(2), Toast.LENGTH_SHORT)
                        .show();
            }
            break;
        case TWO:
            // 此时指定查询id为1的学生信息
            url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1);
            selection = null;
            cursor = resolver.query(url, projection, selection, selectionArgs,
                    sortOrder);
            while (cursor.moveToNext()) {
                Log.i(TAG,
                        "sid=" + cursor.getInt(0) + ",sname="
                                + cursor.getString(1) + ",age="
                                + cursor.getShort(2));
                Toast.makeText(
                        this,
                        "sid=" + cursor.getInt(0) + ",sname="
                                + cursor.getString(1) + ",age="
                                + cursor.getShort(2), Toast.LENGTH_SHORT)
                        .show();
            }
            break;
        default:
            break;
        }
    }

    // 删除数据
    private void delete(int type) {
        ContentResolver resolver = getContentResolver();
        Uri url = null;
        String where = "";
        String[] selectionArgs = null;
        switch (type) {
        case ONE:
            url = Uri.parse(CONTENT_URI);
            // 指定删除id为1,2的学生信息
            where = "sid in(?,?)";
            selectionArgs = new String[] { "1", "2" };
            resolver.delete(url, where, selectionArgs);
            break;
        case TWO:
            // 指定删除id为3的学生信息
            url =  ContentUris.withAppendedId(Uri.parse(CONTENT_URI),3);
            Log.i(TAG, "url:" + url);
            where = null;
            resolver.delete(url, where, selectionArgs);
            break;
        default:
            break;
        }
    }

    // 修改数据
    private void update(int type) {
        ContentResolver resolver = getContentResolver();
        ContentValues values = new ContentValues();
        Uri url = null;
        String where = "";
        String[] selectionArgs = null;
        switch (type) {
        case ONE:
            url = Uri.parse(CONTENT_URI);
            values.put("sname", "update1");
            values.put("age", 22);
            where = "sid = ?"; // 指定更新语句的条件(此时若不指定则是更新全部的数据)
            selectionArgs = new String[] { "1" }; // 指定占位符的数值
            Log.i(TAG, resolver.update(url, values, where, selectionArgs) + "");
            break;
        case TWO:
            // 此时的Uri中包含了需要更新数据的id,所以不再需要指定更新语句的条件和参数值
            url =  ContentUris.withAppendedId(Uri.parse(CONTENT_URI),2);
            values.put("sname", "update2");
            values.put("age", 22);
            where = null;
            Log.i(TAG, resolver.update(url, values, where, selectionArgs) + "");
            break;
        default:
            break;
        }
    }

    // 插入数据
    private void add(int type) {
        ContentResolver resolver = getContentResolver();
        ContentValues values = new ContentValues();
        values.put("sname", "zhaobenshan");
        values.put("age", 23);
        Uri url = null;
        switch (type) {
        case ONE:
            url = Uri.parse(CONTENT_URI);
            // insert()方法返回一个Uri对象,这个对象是新插入的数据的Uri
            Log.i(TAG, resolver.insert(url, values).toString());
            break;
        case TWO:
            /**
             * 这个构造一个Uri为:content://com.demo.contentprovider.studentprovider/
             * t_student/1,然后插入,实际上新插入的一条数据的id并不会为1,
             * 因为已经存在为1的数据了,所以这个和上面的写法一样,生成的数据的id为2
             */
            url =  ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1);
            // insert()方法返回一个Uri对象,这个对象是新插入的数据的Uri
            Log.i(TAG, resolver.insert(url, values).toString());
            break;
        default:
            break;
        }
    }
}

页面显示的布局效果:

而后我们还是利用命令去com.demo.sqlite.activity/database/data.db中查看t_student表

(1) 点击插入数据1或者插入数据2,查看数据:

(2)点击查询数据1,可以看到弹出了id为1和2的两条数据,点击查询数据2可以看到只弹出id为1的数据

(3)点击修改数据1将t_student表中sid为1的name改为update1,age改为22,点击修改数据2将sid为2的name改为update2,age改为22.

(4)点击删除数据1将id为1,2的学生信息删除:如图删除后只剩下id为3的学生信息

  点击删除数据2将id为3的学生信息删除,如图,最后t_student表中已经没有学生信息了

后记:t_student表是SqliteDemo应用程序中的表数据,而现在通过ContentProviderDemo程序也可以实现对t_student表的操作,由此可见,我们的ContentProvider实现数据在应用程序间的共享了

posted on 2015-06-03 13:45  骑着乌龟漫步  阅读(490)  评论(0编辑  收藏  举报

导航