跨程序内容提供器ContentProvider

MainActivity.java

package test.example.com.datasavetest;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;


public class MainActivity extends Activity{

    private Button addData,queryData,updateData,deleteData,replaceData;

    private MyDatabaseHelper dbHelper;
    private SQLiteDatabase db;
    private String newId;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
    }

    private void init() {
        addData = (Button) findViewById(R.id.add_data);
        queryData = (Button) findViewById(R.id.query_data);
        updateData = (Button) findViewById(R.id.update_data);
        deleteData = (Button) findViewById(R.id.delete_data);

        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //添加数据
                //先调用了Uri.parse()方法将一个内容URI 解析成Uri 对象
                Uri uri = Uri.parse("content://test.example.com.datasavetest.provider/book");
                //把要添加的数据都存放到ContentValues 对象中
                ContentValues values = new ContentValues();
                values.put("name","A Clash of Kings");
                values.put("author","George Martin");
                values.put("pages",1040);
                values.put("price",22.85);
                //着调用ContentResolver 的insert()方法执行添加操作
                //insert()方法会返回一个Uri 对象,这个对象中包含了新增数据的id
                Uri newUri = getContentResolver().insert(uri,values);
                //通过getPathSegments()方法将这个id取出
                newId = newUri.getPathSegments().get(1);
            }
        });

        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //查询数据
                //调用了Uri.parse()方法将一个内容URI 解析成Uri 对象
                Uri uri = Uri.parse("content://test.example.com.datasavetest.provider/book");
                Cursor cursor = getContentResolver().query(uri, null, null, null, null);
                if (cursor != null)
                {
                    while (cursor.moveToNext())
                    {
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        String author = cursor.getString(cursor.getColumnIndex("author"));
                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        double price = cursor.getDouble(cursor.getColumnIndex("price"));
                        Log.d("test","----------------------------");
                        Log.d("test", "book name is " + name);
                        Log.d("test", "book author is " + author);
                        Log.d("test", "book pages is " + pages);
                        Log.d("test", "book price is " + price);
                    }
                    cursor.close();
                }
            }
        });

        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //更新数据
                Uri uri = Uri.parse("content://test.example.com.datasavetest.provider/book/" +newId);
                ContentValues values = new ContentValues();
                values.put("name","A Storm of Swords");
                values.put("pages",1216);
                values.put("price",24.05);
                getContentResolver().update(uri,values,null,null);
            }
        });

        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //删除数据
                Uri uri = Uri.parse("content://test.example.com.datasavetest.provider/book/"+newId);
                getContentResolver().delete(uri,null,null);
            }
        });
    }
}

MyDatabaseHelper

package test.example.com.datasavetest;

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

/**
 * Created by fengq on 2015/8/25 0025.
 */
public class MyDatabaseHelper extends SQLiteOpenHelper {

    /**
    public static final String CREATE_BOOK = "create table book (" +
            "id integer primary key autoincrement," +   //integer表示整形,primary key表示主键,autoincrement表示自增长
            "author text," + //text表示文本类型
            "price real," + //real表示浮点型
            "pages integer," +
            "name text)";
    */

    public static final String CREATE_BOOK = "create table Book ("
            + "id integer primary key autoincrement, "
            + "author text, "
            + "price real, "
            + "pages integer, "
            + "name text"
            + "category_id integer)";

    //Category表,用于记录书籍的分类
    public static final String CREATE_CATEGORY = "create table Category (" +
            "id integer primary key autoincrement," +
            "category_name text," +
            "category_code integer)";

    private Context mContext;

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        /**
         * 当程序中没有BookStore.db时会创建数据库并调用onCreate函数
         */
        //通过db.execSQL(SQLCommand)来执行没有返回值的SQL语言
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext,"Create succeeded", Toast.LENGTH_SHORT).show();
        Log.d("test","Create succeeded");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        /**
        //如果数据库中存在这两张表就将这两张表删除,再调用onCreate方法去重新创建
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        Toast.makeText(mContext,"Delete succeeded", Toast.LENGTH_SHORT).show();
        onCreate(db);
         */
        switch (oldVersion)
        {
            //如果用户当前数据库的版本号是1,就只会创建一张Category表
            case 1:
                db.execSQL(CREATE_CATEGORY);

            //如果当前数据库的版本号是2,就会执行alter命令来为Book表新增一个category_id列
            case 2:
                db.execSQL("alter table Book add column category_id integer");
            default:
                /**
                 * switch中的每一个case的最后都是没有使用break的,
                 * 保证在跨版本升级的时候,每一次的数据库修改都能被全部执行到
                 * */
        }
    }
}

main_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/add_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add To Book" />
    <Button
        android:id="@+id/query_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Query From Book" />
    <Button
        android:id="@+id/update_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Update Book" />
    <Button
        android:id="@+id/delete_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Delete From Book" />

</LinearLayout>

DatabaseProvider.java

package test.example.com.datasavetest;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

/**
 * Created by fengq on 2015/8/28 0028.
 */
public class DatabaseProvider extends ContentProvider {

    //访问Book中的所有数据
    public static final int BOOK_DIR = 0;
    //访问Book中的单条数据
    public static final int BOOK_ITEM = 1;
    //访问Category中的所有数据
    public static final int CATEGORY_DIR = 2;
    //访问Category中的单条数据
    public static final int CATEGORY_ITEM = 3;

    public static final String AUTHORITY = "test.example.com.datasavetest.provider";
    public static UriMatcher uriMatcher;
    private MyDatabaseHelper dbHelper;

    //在静态代码块中对UriMatcher进行初始化操作
    static
    {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY,"book",BOOK_DIR);
        uriMatcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);
        uriMatcher.addURI(AUTHORITY,"category",CATEGORY_DIR);
        uriMatcher.addURI(AUTHORITY,"category/#",CATEGORY_ITEM);
    }

    @Override
    public boolean onCreate() {
        //创建MyDatabaseHelper的实例
        dbHelper = new MyDatabaseHelper(getContext(),"BookStore.db",null,2);
        //返回true表示内容提供器初始化成功,这时数据库就完成了创建或升级操作
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        //查询数据
        //获取SQLiteDatabase的实例
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        //根据传入的Uri参数判断出用户想要访问哪张表
        switch (uriMatcher.match(uri))
        {
            case BOOK_DIR:
                //调用SQLiteDatabase的query()进行查询,并返回Cursor对象
                cursor = db.query("Book",projection,selection,selectionArgs,null,null,sortOrder);
                break;
            case BOOK_ITEM:
                /**
                 * 访问单条数据时,调用getPathSegments()方法
                 * 将内容URI权限之后的部分以"/"符号进行分割,并把分割后的结果放入到一个字符串列表中,
                 * 这个列表的第0个位置存放的是路径
                 * 第1个位置存放的是id
                 * 得到id之后,通过selection和selectionArgs参数进行约束,实现了查询单条数据的功能
                 * */
                String bookId = uri.getPathSegments().get(1);
                cursor = db.query("Book",projection,"id = ?",new String[]{bookId},null,null,sortOrder);
                break;
            case CATEGORY_DIR:
                cursor = db.query("Book",projection,selection,selectionArgs,null,null,sortOrder);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                cursor = db.query("Category",projection,"id = ?",new String[]{categoryId},null,null,sortOrder);
                break;
            default:
                break;
        }
        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri))
        {
            case BOOK_DIR:
                return "vnd.android.cursor.dir/vnd.test.example.com.datasavetest.provider.book";
            case BOOK_ITEM:
                return "vnd.android.cursor.item/vnd.test.example.com.datasavetest.provider.book";
            case CATEGORY_DIR:
                return "vnd.android.cursor.dir/vnd.test.example.com.datasavetest.provider.category";
            case CATEGORY_ITEM:
                return "vnd.android.cursor.item/vnd.test.example.com.datasavetest.provider.category";
        }
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        //添加数据
        //获取SQLiteDatabase实例
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Uri uriReturn = null;
        //根据Uri参数判断用户想往哪张表添加数据
        switch (uriMatcher.match(uri))
        {
            case BOOK_DIR:
            case BOOK_ITEM:
                /**
                 * insert()方法要求返回一个能够表示这条新增数据的URI,
                 * 调用Uri.parse()方法将一个内容URI解析成Uri对象
                 * 这个内容URI是以新增数据的id结尾
                 * */
                long newBookId = db.insert("Book",null,values);
                uriReturn = Uri.parse("content://"+AUTHORITY+"/book/"+newBookId);
                break;
            case CATEGORY_DIR:
            case CATEGORY_ITEM:
                long newCategoryId = db.insert("Category",null,values);
                uriReturn = Uri.parse("content://"+AUTHORITY+"/category/"+newCategoryId);
                break;
            default:
                break;
        }
        return uriReturn;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        //删除数据
        //先获取到SQLiteDatabase 的实例
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int deleteRows = 0;
        //根据传入的Uri 参数判断出用户想要删除哪张表里的数据
        switch (uriMatcher.match(uri))
        {
            case BOOK_DIR:
                deleteRows = db.delete("Book",selection,selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                deleteRows = db.delete("Book","id = ?",new String[]{bookId});
                break;
            case CATEGORY_DIR:
                deleteRows = db.delete("Category",selection,selectionArgs);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                deleteRows = db.delete("Category","id = ?",new String[]{ categoryId});
                break;
            default:
                break;
        }
        //被删除的行数将作为返回值返回
        return deleteRows;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        //更新数据
        //获取SQLiteDatabase的实例
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int updateRows = 0;
        //根据传入的Uri 参数判断出用户想要更新哪张表里的数据
        switch (uriMatcher.match(uri))
        {
            case BOOK_DIR:
                updateRows = db.update("Book",values,selection,selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                updateRows = db.update("Book",values,"id = ?",new String[]{ bookId});
                break;
            case CATEGORY_DIR:
                updateRows = db.update("Category",values,selection,selectionArgs);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                updateRows = db.update("Category",values,"id = ?",new String[]{ categoryId});
                break;
            default:
                break;
        }
        //受影响的行数将作为返回值返回
        return updateRows;
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="test.example.com.datasavetest" >
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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>

        <!--
        在android:name属性中指定了该类的全名,
        在android:authorities属性中指定了该内容提供器的权限
        -->
        <provider
            android:authorities="test.example.com.datasavetest.provider"
            android:name="test.example.com.datasavetest.DatabaseProvider">

        </provider>
    </application>

</manifest>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值