ContentReslove
可以通过getContentResolver( )方法获取到该类的实例,ContentReslover中提供了一系列的方法用于对数据进行CRUD操作,其中insert( )方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据。
Uri主要由两部分组成,权限和路径。一般权限写为com.example.app.provider,路径为要查的表名所以标准写法为:
content://com.example.app.provider/table1
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
query()方法 | 对应SQL部分 | 描述 |
---|---|---|
uri | from table_name | 指定查询某个应用下的某一张表 |
projection | select column,column2 | 指定查询的列名 |
selection | where column=value | 指定where的约束条件 |
selectionArgs | - | 为where中的占位符提供具体的值 |
orderBy | order by column1,column2 | 指定查询结果的排序方式 |
if(cursor!=null){
while(cursor.moveToNext()){
String column1 = cur.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
}
//关闭索引
cursor.close();
}
添加数据
ContentValues values = new ContentValues();
values.put("column1","text");
values.put("column2",1);
getContentResolver().insert(uri,values);
修改数据
ContentValues values = new ContentValues();
vallues.put("column1","");
getContentResolver().update(uri,values,"column1 = ? and column2 = ?",new String[]{"text","1"});
删除数据
getContentResolver().delete(uri,"column2 = ?",new String[]{"1"});
读取联系人
添加权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
"*********************主布局文件为Listview************************"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
//ListView的id,便于在java文件下寻找
android:id="@+id/contacts_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
"*********************主方法*********************"
import android.support.v7.app.ActionBarActivity;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
ListView contactsView;
// 添加适配器
ArrayAdapter<String> adapter;
// 定义一个联系人的集合
List<String> contactsList = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contactsView = (ListView) findViewById(R.id.contacts_view);
//适配器的设置
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList);
//安装好适配器
contactsView.setAdapter(adapter);
readContacts();
}
private void readContacts() {
Cursor cursor = null;
try {
//ContactsContract.CommonDataKinds.Phone.CONTENT_URI是一个常量,这个常量就是Uri.parse()方法解析出来的,下面的那两个也是同样的意思
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null,
null);
//遍历要查找的联系人表
while (cursor.moveToNext()) {
String displayName = cursor
.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//将对象加入到集合中
contactsList.add(displayName + "\n" + number);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
//千万记得把Cursor对象关闭
cursor.close();
}
}
}
}
创建自己的内容提供者
uri的写法
content://com.example.app.provider/table1
"包名" "内容提供者标志" "表名"
*:表示匹配任意长度的字符,因此匹配任意表内容的URI为
content://com.example.app.provider/*
#:表示匹配任意长度的数字,一次匹配一个表中任意一行数据内容的uri可以写为
content://com.example.app.provider/table1/#
MIME在android中的规定
1.必须以vnd开头
2.如果内容以URI以路径结尾,则后面跟android.cursor.dir/,如果内容URI以id结尾,则后面接android.cursor.item/
3.最后接上vnd.<authority>.<path>
例如1:对于content://com.example.app.provider/table1
对应MIME:vnd.android.cursor.dir/vnd.com.example.app.provider.table1
例如2:对于content://com.example.app.provider/table1
MIME:vnd.android.cursor.item/vnd.com.example.app.provider.table1
下面要用到的辅助类
package com.example.databaseandroid;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class MyDatabaseeHelper extends SQLiteOpenHelper{
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)";
public static final String CREATE_CATEGORY = "create table category("+
"id integer primary key autoincrement,"
+"category_name text,"
+"category_code integer)";
public MyDatabaseeHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion){
case 1:
db.execSQL(CREATE_CATEGORY);
//添加语句
case 2:
db.execSQL("alter table Book add column category_id integer");
default:
}
}
}
1.创建自己的ContentProvider
总体思路,只需要获取到该应用程序的内容URI,然后借助ContentResolver进行增删改查操作。
"********************主要的布局文件**************************"
package com.example.databaseandroid;
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;
/**
* 继承ContentProvider来创建自己的内容提供器
*/
public class MyProvider extends ContentProvider{
public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
public static final int CATEGORY_DIR = 2;
public static final int CATEGORY_ITEM = 3;
public static final String AUTHORITY = "com.example.databaseandroid.provider";
private MyDatabaseeHelper dbHelper;
private static UriMatcher uriMatcher;
/**
*在静态代码块里对UriMatcher进行了初始化操作,将期望匹配的几种Uri格式添加进去了。
*/
static{
//uriMatcher可以轻松的实现匹配内容URI功能
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//addURI()方法接收三个参数,可以分别把权限、路径和一个自定义的代码传进去。
uriMatcher.addURI(AUTHORITY,"book",BOOK_DIR);
uriMatcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);
uriMatcher.addURI(AUTHORITY,"category",CATEGORY_DIR);
uriMatcher.addURI(AUTHORITY,"category/#",CATEGORY_ITEM);
}
/**
*初始化内容提供其时使用,只有当ContentResolver尝试访问我们程序中的数据时,内容提供者才会被初始化,初始化成功返回true
*/
@Override
public boolean onCreate() {
//创建数据库,获得数据库的实例
dbHelper = new MyDatabaseeHelper(getContext(), "BookStore.db", null, 2);
return true;
}
/**
*从内容提供器查询数据,使用URI参数来确定是哪一张表,projection参数用于指定查询的列,selection和selectionArgs参数用来约束查询的条件,sortOrder指定排序方式,查询结果放在Cursor中。
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
//查询数据
SQLiteDatabase db= dbHelper.getReadableDatabase();
Cursor cursor = null;
//当调用match()方法时,可以传入uri,返回自定义的代码
switch(uriMatcher.match(uri)){
case BOOK_DIR:
cursor = db.query("book", projection, selection, selectionArgs, null, null, sortOrder);
break;
case BOOK_ITEM:
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("category", 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;
}
/**
*根据传入内容的uri来返回相应的MIME类型,这个参数正是调用ContentResolver的增删改查时传递过来的
*/
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databaseandroid.provider.book";
case BOOK_ITEM:
return "vnd.android.currsor.item/vnd.com.example.databaseandroid.provider.book";
case CATEGORY_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databaseandroid.provider.category";
case CATEGORY_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databaseandroid.provider.category";
}
return null;
}
/**
*向内容提供器添加一条数据,使用uri找到要添加的表,待添加的数据保存在values中,添加完成后,返回一个用于表示这条新纪录的uri
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
//添加数据
SQLiteDatabase db = dbHelper.getWritableDatabase();
Uri uriReturn = null;
switch(uriMatcher.match(uri)){
case BOOK_DIR:
case BOOK_ITEM:
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 db = dbHelper.getWritableDatabase();
int deletedRows = 0;
switch(uriMatcher.match(uri)){
case BOOK_DIR:
deletedRows = db.delete("book", selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
deletedRows = db.delete("book", "id = ?", new String[]{bookId});
break;
case CATEGORY_DIR:
deletedRows = db.delete("category", selection, selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
deletedRows = db.delete("category", "id = ?", new String[]{categoryId});
break;
default:
break;
}
return deletedRows;
}
/**
* 使用uri参数来确定更新哪一张表中的数据,新数据保存在values参数中,selection和selectionArgs参数用于约束更新哪一行,受影响的行数将作为返回值返回。
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int updatedRows =0;
switch(uriMatcher.match(uri)){
case BOOK_DIR:
updatedRows = db.update("book", values, selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
updatedRows = db.update("book", values, "id = ?", new String[]{bookId});
break;
case CATEGORY_DIR:
updatedRows = db.update("category", values, selection, selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
updatedRows = db.update("category", values, "id = ?", new String[]{categoryId});
break;
default:
break;
}
return updatedRows;
}
}
"***************必须要在内容提供者的应用中添加权限***************"
//MyProvider为上面所写的类名,前面为包名。
<provider
android:name="com.example.databaseandroid.MyProvider"
android:authorities="com.example.databaseandroid.provider" >
</provider>
在其他应用中访问上一个应用的数据
"************************布局文件************************"
<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/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="Updata Book" />
<Button
android:id="@+id/delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete From book" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
"*********************主要的活动文件***********************"
package com.test.dukang;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
private String newId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(this);
Button queryData = (Button) findViewById(R.id.query_data);
queryData.setOnClickListener(this);
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(this);
Button deleteData = (Button) findViewById(R.id.delete_data);
deleteData.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.add_data:
Uri uri = Uri.parse("content://com.example.databaseandroid.provider/book");
ContentValues values = new ContentValues();
values.put("name", "A Clash of Kings");
values.put("author", "Gerge Martin");
values.put("pages", 1040);
values.put("price", 22.85);
Uri newUri = getContentResolver().insert(uri, values);
newId = newUri.getPathSegments().get(1);
break;
case R.id.query_data:
Uri quri = Uri.parse("content://com.example.databaseandroid.provider/book");
Cursor cursor = getContentResolver().query(quri, 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"));
System.out.println("你好");
Log.d("MainAcivity", name);
Log.d("MainAcivity", author);
Log.d("MainAcivity", ""+pages);
Log.d("MainAcivity", ""+price);
}
cursor.close();
}
break;
case R.id.update_data:
Uri uuri = Uri.parse("content://com.example.databaseandroid.provider/book/" + newId);
ContentValues valuesUpdate = new ContentValues();
valuesUpdate.put("name", "A Storm of Swords");
valuesUpdate.put("pages", 1216);
valuesUpdate.put("price", 24.05);
getContentResolver().update(uuri, valuesUpdate, null, null);
break;
case R.id.delete_data:
Uri uriDelete=Uri.parse("content://com.example.databaseandroid.provider/book/"+newId);
getContentResolver().delete(uriDelete, null, null);
break;
}
}
}