ContentProvider内容提供者

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].内容提供者的作用:
ContentProvider内容提供者_第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" />


你可能感兴趣的:(ContentProvider内容提供者)