标签:sql uri android content provider getcontentresolver
ContentProvider:内容提供者
1、为存储和读取数据提供了统一的接口
2、使用ContentProvider,应用程序可以实现数据共享
3、android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
4、当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。
先来了解一下Uri:
Uri,即通用资源标识符
1、Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示
2、Uri一般由三部分组成:访问资源的命名机制;存放资源的主机名; 资源自身的名称,由路径表示。
Android的Uri由以下三部分组成: "content://"+数据的路径+标示ID(可选)、
如:所有联系人的Uri: content://contacts/people
某个联系人的Uri: content://contacts/people/5 //联系人中id为5的联系人
3、如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.archer.ContentProvider")ContentResolver:
在android中,每个应用程序是可以实现数据共享的,对于每一个应用程序程序都拥有一个ContentProvider实例进行存储,
而ContentResolver则是用于管理所有程序的ContentProvider实例,通过ContentRescolver可以对数据进行添加、删除、修改和查询操作
通过getContentRescolver()获取实例
下面通过创建一个Content Provider,并使用 SQLLite数据库实现数据共享
首先,定义ContentProvider的CONTENT_URI,并且是public static final的Uri类型的类变量
必须为其制定一个唯一的字符串值,一般用类的全名称命名
package com.ContentProviderDemo.Archer;
import android.net.Uri;
import android.provider.BaseColumns;
public class MyUsers {
public static final String AUTHORITY = "com.archer.ContentProvider";
//BaseColumn类中已经包含了 _id 字段
public static final class User implements BaseColumns{
public static final Uri CONTENT_URI =
Uri.parse("content://com.archer.ContentProvider");
//表数据列
public static final String USER_NAME = "USER_NAME";
}
}之后创建一个类继承ContentProvider
package com.ContentProviderDemo.Archer;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
public class MyContentProvider extends ContentProvider{
/**
* 定义一个SQLiteDatabase变量
* Android提供了一个名为SQLiteDatabase的类,它封装了一些操作数据库的API。
* 使用它能实现基本的CRUD(插入、查询、更新、删除)操作,通过getWritableDatabase()和getReadableDatabase()可以获取数据库实例
*/
private SQLiteDatabase sqlDB;
private DatabaseHelper dbHelper;
private static final String DATABASE_NAME = "Users.db"; //数据库名
private static final int DATABASE_VERSION = 1; //数据库版本
//表名
private static final String TABLE_NAME = "User";//表名
/**
* 首先需要创建数据库(定义一个内部类,继承SQLiteOpenHelper类,重写其方法)
* SQliteOpenHelper是一个抽象类,来管理数据库的创建和版本的管理。
* 要使用它必须实现它的onCreate(SQLiteDatabase),onUpgrade(SQLiteDatabase, int, int)方法
* onCreate:当数据库第一次被建立的时候被执行,例如创建表,初始化数据等。
* onUpgrade:当数据库需要被更新的时候执行,例如删除旧表,创建新表。
* @author Administrator
*/
private static class DatabaseHelper extends SQLiteOpenHelper{
/**
* 创建数据库的构造方法
* name 数据库的名字
* factory 查询数据库的游标工厂一般情况下用sdk默认的
* version 数据库的版本一般大于0
*/
public DatabaseHelper(Context context){
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sq1 = "Create table " + TABLE_NAME + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);"; //创建表的sql语句
db.execSQL(sq1); //创建表
}
/**
* 更新数据的时候调用的方法,如新增表、修改数据
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//增加一列
db.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME);
onCreate(db);
}
}
@Override
public int delete(Uri uri, String s, String[] arg2) {
return 0;
}
@Override
public String getType(Uri arg0) {
return null;
}
/**
* 插入数据
* ContentValues类负责存储一些名值对,的名是一个String类型,而值都是基本类型。
*/
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
//以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,就会打开失败
sqlDB = dbHelper.getWritableDatabase();
//插入一条新的纪录,如果插入成功则会返回这条记录的id,如果插入失败会返回-1
long rowId = sqlDB.insert(TABLE_NAME, "", contentValues);
if(rowId > 0){
// ContentUris 类用于获取Uri路径后面的ID部分
//appendId:为该Uri加上ID
Uri rowUri = ContentUris.appendId(MyUsers.User.CONTENT_URI.buildUpon(),
rowId).build();
// getContextResolver().notifyChange():获得一个ContextResolver对象并且更新里面的内容。
getContext().getContentResolver().notifyChange(rowUri, null);
return rowUri;
}
throw new SQLException("Fail to insert row into"+uri);
}
/**
* 这是一个回调函数,当生成所在类的对象时,这个方法被调用,创建一个数据库
*/
@Override
public boolean onCreate() {
dbHelper = new DatabaseHelper(getContext());
return (dbHelper == null) ? false:true;
}
/**
* 查询
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
//SQLiteQueryBuilder 是一个构造SQL查询语句的辅助类。
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
//getReadableDatabase():先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库
SQLiteDatabase db = dbHelper.getReadableDatabase();
qb.setTables(TABLE_NAME);
/**
* Cursor 是每行的集合
* 在Android中 查询数据是通过Cursor 类来实现的。当我们使用 SQLiteDatabase.query()方法时,就会得到Cursor对象,
* Cursor所指向的就是每一条数据
*/
Cursor c = qb.query(db, projection, selection, null, null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
return 0;
}
}在AndroidManifest.xml中进行注册:
<application android:allowBackup="true" android:icon="@drawable/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> <provider android:name=".MyContentProvider" android:authorities="com.archer.ContentProvider"> </provider> <!-- android:authorities属性配置的就是该ContentProvider的名字,是它在Android系统中的名字,我们是通过这个名字去找对应的ContentProvider对象的--> </application>
最后,创建一个新的工程(测试用)
package com.ContentProviderDemo.Archer;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
/**
* 在另一个工程中访问创建的数据库,不用再注册provider,否则会保存
* @author Administrator
*
*/
public class MainActivity extends Activity {
public static final String AUTHORITY = "com.archer.ContentProvider";
private Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
insertRecord("record1");
displayRecords();
}
//插入数据
private void insertRecord(String userName) {
ContentValues values = new ContentValues();
values.put("USER_NAME", userName);
getContentResolver().insert(CONTENT_URI, values);
}
//查询数据
private void displayRecords() {
// 该数组中包含了所有要返回的字段
String columns[] = new String[] { "_id", "USER_NAME" };
Uri myUri = CONTENT_URI;
Cursor cur = getContentResolver().query(myUri, columns, null, null,null);
if (cur.moveToFirst()) {
String id = null;
String userName = null;
do {
id = cur.getString(cur.getColumnIndex("_id"));
userName = cur.getString(cur.getColumnIndex("USER_NAME"));
Log.e("TAG", "id:" + id + ";" + "userName:" + userName);
} while (cur.moveToNext());
}
cur.close(); // 关闭Cursor对象
}
}这样,就是先不同应用程序间的数据共享了
标签:sql uri android content provider getcontentresolver
原文地址:http://4131541.blog.51cto.com/4121541/1638667