1.为什么需要内容提供者(ContentProvider)
[1].如何创建一个数据库,定义一个类继承SqliteOpenHelper
[2].打开数据库 :(1)adb shell (2)cd data/data (3)ls (4)cd con.eson.db (5)ls (6)cd databases (7)ls (8)sqlite3 数据库名 (9) select * from 表名
[3]创建数据库例子:
第一步:创建 MyOpenHelper类 继承 SQLiteOpenHelper
package
com.eson.db
;
import
android.content.Context
;
import
android.database.sqlite.SQLiteDatabase
;
import
android.database.sqlite.SQLiteOpenHelper
;
public class
MyOpenHelper
extends
SQLiteOpenHelper {
/**
*
* @param
context
* name 数据库的名字
*
* factory 游标工厂
*/
public
MyOpenHelper(Context context) {
super
(context
,
"Account.db"
, null,
1
)
;
}
//表结构的初始化
@Override
public void
onCreate
(SQLiteDatabase db) {
db.execSQL(
"create table info(_id integer primary key autoincrement,name varchar(20),money varchar(20))"
)
;
db.execSQL(
"insert into info(name,money) values(?,?)"
, new
String[]{
"张三"
,
"5000"
})
;
db.execSQL(
"insert into info(name,money) values(?,?)"
, new
String[]{
"李四"
,
"3000"
})
;
}
@Override
public void
onUpgrade
(SQLiteDatabase db
, int
oldVersion
, int
newVersion) {
}
}
第二步:在MainActivity读取数据库
package
com.eson.db
;
import
android.os.Bundle
;
import
android.support.v7.app.AppCompatActivity
;
public class
MainActivity
extends
AppCompatActivity {
@Override
protected void
onCreate
(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState)
;
setContentView(R.layout.
activity_main
)
;
MyOpenHelper myOpenHelper =
new
MyOpenHelper(getApplicationContext())
;
myOpenHelper.getReadableDatabase()
;
}
}
[4]利用Cursor结果集将数据库内容打印在控制台上
MyOpenHelper myOpenHelper =
new
MyOpenHelper(getApplicationContext())
;
SQLiteDatabase database = myOpenHelper.getReadableDatabase()
;
Cursor cursor = database.query(
"info"
, null, null, null, null, null, null
)
;
if
(cursor!=
null
&&cursor.getCount()>
0
){
while
(cursor.moveToNext()){
String name=cursor.getString(
1
)
;
String phone=cursor.getString(
2
)
;
System.
out
.println(
"name:"
+name+
"------"
+
"phone:"
+phone)
;
}
}
[5]用chcp 65001 命令将cmd编码改为utf-8
[6] 用adb shell ,cd data/data/com.eson.db/databases进入到databases里面, 用chmod 777 Account.db将Account.db的权限修改为可读可写可执行。
[7]使用内容提供者,把私有的数据库暴露出来
2.内容提供者原理
[1].内容提供者的作用:
[2].内容提供者将数据封装然后把提供出来,其他应用都可以通过内容解析者(ContentResolver)来访问。
[3].写一个类去继承内容提供者,实现内容提供者的方法。
3.实现内容提供者步骤
[1].定义一个类继承ContentProvider
[2].在清单文件里配置内容提供者
<provider
android
:authorities=
"com.eson.provider"
android :name=".AccountProvider"></provider>
[3]定义一个UriMatcher 定义匹配器并且定义静态代码块,定义匹配规则
//定义一个UriMatcher 定义匹配器
private static final
UriMatcher
sUriMatcher
=
new
UriMatcher(UriMatcher.
NO_MATCH
)
;
//定义静态代码块,定义匹配规则
private static final int
QUERYSUCCESS
=
1
;
static
{
sUriMatcher.addURI( "com.eson.provider" ,"query", QUERYSUCCESS);
}
[4]在onCreate方法初始化
public boolean
onCreate
() {
myOpenHelper
=
new
MyOpenHelper(getContext())
;
return false;
}
[5].实现query方法
public
Cursor
query
(Uri uri
,
String[] projection
,
String selection
,
String[] selectionArgs
,
String sortOrder) {
int
code=
sUriMatcher
.match(uri)
;
if
(code==
QUERYSUCCESS
){
SQLiteDatabase db =
myOpenHelper
.getReadableDatabase()
;
db.query(
"info"
,
projection
,
selection
,
selectionArgs
,null,null,
sortOrder)
;
}
else
{
throw new
IllegalArgumentException(
"您的路径不匹配,请检查路径"
)
;
}
return null;
}
[6]暴露想要暴露的方法(增删改查)
[7]在另外一个应用中查询数据库
Uri uri=Uri. parse(
"content://com.esom.provider/query"
)
;
Cursor cursor = getContentResolver().query(uri
, null, null, null, null
)
;
if
(cursor!=
null
&&cursor.getCount()>
0
){
while
(cursor.moveToNext()){
String name = cursor.getString(
1
)
;
String phone = cursor.getString(
2
)
;
System.
out
.println(
"name:"
+name+
" "
+
"phone:"
+phone)
;
}
}
4.备份短信案例
[1].在content布局里设置按钮
<Button
android
:onClick=
"click"
android
:layout_width=
"wrap_content"
android
:layout_height=
"wrap_content"
android
:text=
"短信备份"
/>
[2].实现按钮的点击事件
//点击按钮 查询短信数据内容 然后进行备份
public void
click
(View v){
try
{
//[1]获取xml序列化实例
XmlSerializer serializer = Xml. newSerializer()
;
//[2]设置序列化参数
File file =
new
File(Environment.getExternalStorageDirectory ().getPath()
,
"smsBackUp.xml"
)
;
FileOutputStream fos =
new
FileOutputStream(file)
;
serializer.setOutput(fos
,
"utf-8"
)
;
//[3]开始写xml文档开头
serializer.startDocument(
"utf-8"
, true
)
;
//[4]开始写根节点
serializer.startTag(
null,
"smss"
)
;
//[5]由于短信数据库 系统也通过内容提供者给暴露出来了了 所以我们只需要通过内容解析者去操作数据库
Uri uri = Uri. parse(
"content://sms/"
)
;
Cursor cursor = getContentResolver().query(uri
, new
String[]{
"address"
,
"date"
,
"body"
}
, null, null, null
)
;
while
(cursor.moveToNext()) {
String address = cursor.getString(
0
)
;
String date = cursor.getString(
1
)
;
String body= cursor.getString(
2
)
;
//[6]写sms节点
serializer.startTag(
null,
"sms"
)
;
//[7]写address节点
serializer.startTag(
null,
"address"
)
;
serializer.text(address)
;
serializer.endTag(
null,
"address"
)
;
//[8]写body节点
serializer.startTag(
null,
"body"
)
;
serializer.text(body)
;
serializer.endTag(
null,
"body"
)
;
//[9]写date节点
serializer.startTag(
null,
"date"
)
;
serializer.text(date)
;
serializer.endTag(
null,
"date"
)
;
serializer.endTag(
null,
"sms"
)
;
}
serializer.endTag(
null,
"smss"
)
;
serializer.endDocument()
;
}
catch
(Exception e) {
e.printStackTrace()
;
}
}
[
3].添加权限
<uses-permission
android
:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android
:name=
"android.permission.READ_SMS"
/>
<uses-permission android :name="android.permission.WRITE_SMS"/>
5.利用内容提供者插入短信
[1]设置按钮布局
<Button
android
:onClick=
"click"
android
:layout_width=
"wrap_content"
android
:layout_height=
"wrap_content"
android
:text=
"插入短信"
/>
[2]设置按钮点击事件
public void
click
(View v){
Uri uri = Uri.parse(
"content://sms"
)
;
ContentValues values =
new
ContentValues()
;
values.put(
"address"
,
"95555"
)
;
values.put(
"body"
,
"您的余额为0.0000元"
)
;
values.put(
"date"
,
System. currentTimeMillis())
;
Uri insert = getContentResolver().insert(uri
,
values)
;
}
[3].添加权限
<uses-permission
android
:name=
"android.permission.READ_SMS"
/>
<uses-permission android :name="android.permission.WRITE_SMS"/>
6.读取联系人案例
[1].在MainActivity中
public class
MainActivity
extends
AppCompatActivity {
@Override
protected void
onCreate
(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState)
;
setContentView(R.layout.
activity_main
)
;
List<Contact> readContacts=ReadContactUtils. readContact(getApplicationContext())
;
for
(Contact contact:readContacts){
System.
out
.println(
"contact"
+contact)
;
}
}
}
[2].创建读取联系人方法
public class
ReadContactUtils {
public static
List<Contact>
readContact
(Context context){
//创建集合对象
ArrayList<Contact> contactsLists =
new
ArrayList<>()
;
//由于联系人的数据库也是通过内容提供者暴露出来的,所以可以造作数据库直接用内容解析者
//先查询raw_contacts表 contact_id列
Uri uri = Uri. parse(
"content://com.android.contacts/raw_contacts"
)
;
Uri dataUri = Uri. parse(
"content://com.android.contacts/data"
)
;
Cursor cursor = context.getContentResolver().query(uri
, new
String[]{
"contact_id"
}
, null, null, null
)
;
while
(cursor.moveToNext()){
String contact_id = cursor.getString(
0
)
;
if
(contact_id !=
null
) {
System.
out
.println(
"contact_id:"
+contact_id)
;
//创建javabean对象
Contact contact=
new
Contact()
;
contact.setId(contact_id)
;
//根据raw_contact_id去查询data表 data1列和mimetype_id列
//小细节 查询的不是data表 查询的是view_data的视图
Cursor dataCursor = context.getContentResolver().query(dataUri
, new
String[]{
"data1"
,
"mimetype"
}
,
"raw_contact_id=?"
, new
String[]{contact_id}
, null
)
;
while
(dataCursor.moveToNext()){
String data1 = dataCursor.getString(
0
)
;
String mimetype = dataCursor.getString(
1
)
;
if
(
"vnd.android.cursor.item/name"
.equals(mimetype)){
System.
out
.println(
"姓名"
+data1)
;
contact.setName(data1)
;
}
else if
(
"vnd.android.cursor.item/phone_v2"
.equals(mimetype)){
System.
out
.println(
"电话号码:"
+data1)
;
contact.setPhone(data1)
;
}
else if
(
"vnd.android.cursor.item/email_v2"
.equals(mimetype)){
System.
out
.println(
"邮箱:"
+data1)
;
contact.setEmail(data1)
;
}
}
//把javabean对象加入到结合中
contactsLists.add(contact)
;
}
}
return
contactsLists
;
}
}
[3]javabean对象
public class
Contact {
private
String
id
;
private
String
email
;
private
String
name
;
private
String
phone
;
public
String
getEmail
() {
return
email
;
}
public void
setEmail
(String email) {
this
.
email
= email
;
}
public
String
getId
() {
return
id
;
}
public void
setId
(String id) {
this
.
id
= id
;
}
public
String
getName
() {
return
name
;
}
public void
setName
(String name) {
this
.
name
= name
;
}
public
String
getPhone
() {
return
phone
;
}
public void
setPhone
(String phone) {
this
.
phone
= phone
;
}
@Override
public
String
toString
() {
return
"Contact{"
+
"id='"
+
id
+
'
\'
'
+
", name='"
+
name
+
'
\'
'
+
", phone='"
+
phone
+
'
\'
'
+
'}'
;
}
}
[4].添加权限
<uses-permission
android
:name=
"android.permission.READ_CONTACTS"
/>