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>