ContentProvider内容提供者

来源:互联网 发布:codol过一会就数据异常 编辑:程序博客网 时间:2024/06/05 21:01
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
packagecom.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(?,?)", newString[]{"张三","5000"});
       
db.execSQL( "insert into info(name,money) values(?,?)", newString[]{"李四","3000"});

   
}

   
@Override
   
public void onUpgrade(SQLiteDatabase db, int oldVersion, intnewVersion) {

    }

}
    
第二步:在MainActivity读取数据库
packagecom.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 =newMyOpenHelper(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 finalUriMatchersUriMatcher=newUriMatcher(UriMatcher.NO_MATCH);
//定义静态代码块,定义匹配规则

private static final intQUERYSUCCESS=1;

static
{

    sUriMatcher.addURI("com.eson.provider","query",QUERYSUCCESS);}
   [4]在onCreate方法初始化
public booleanonCreate() {

   
myOpenHelper = new MyOpenHelper(getContext()) ;

    return false;
}
 
[5].实现query方法
publicCursorquery(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 voidclick(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, newString[]{"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-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android :name="android.permission.READ_SMS"/>
<uses-permissionandroid: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 voidclick(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-permissionandroid:name="android.permission.READ_SMS"/>
<uses-permissionandroid:name="android.permission.WRITE_SMS"/>

6.读取联系人案例
  [1].在MainActivity中

public classMainActivityextendsAppCompatActivity {

   
@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 classReadContactUtils {
   
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, newString[]{"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=newContact();
               
contact.setId(contact_id);

               
//根据raw_contact_id去查询data表   data1列和mimetype_id列
                //小细节 查询的不是data表 查询的是view_data的视图
               
Cursor dataCursor = context.getContentResolver().query(dataUri, newString[]{"data1","mimetype"},"raw_contact_id=?", newString[]{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 classContact {
   
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-permissionandroid:name="android.permission.READ_CONTACTS"/>


1 0
原创粉丝点击