四大组件之ContentProvider

四大组件之ContentProvider

ContentProvider简介

ContentProvider的主要作用是实现不同的应用程序之间的数据的共享,而且还保证了数据的安全性。 ContentProvider是android提供的实现程序之间数据共享的一套机制。

ContentProvider的使用

1.创建ContentProvider

  • 首先我们要为应用程序准备数据,我们在数据库里面添加100条数据

        public class MySQLiteOpenHelper extends SQLiteOpenHelper {
    
        public MySQLiteOpenHelper(Context context) {
            super(context, "mydb.db", null, 1);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
            //创建一张表
            db.execSQL("create table student( _id integer primary key autoincrement,name text,age text,score text)");
            //向表中插入100条记录
            for(int i=0;i<100;i++){
                db.execSQL("insert into student(name,age,score)values('zhangsan"+i+"','"+(20+i)+"','"+(60+i)+"')");
            }
        }
        //更新时调用
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub
    
        }
    
    } 
    
  • 添加完数据之后,开始创建自己的ContentProvider。我们需要建一个类,继承 ContentProvider 类,然后复写里面的方法

    public class MyContentProder extends ContentProvider {
        //创建一个UriMatcher对象
        private static final UriMatcher urimatcher =new UriMatcher(UriMatcher.NO_MATCH);
        private static final int INSERT=1;
        private static final int DELETE=2;
        private static final int UPDATE=3;
        private static final int QUERY=4;
        private MySQLiteOpenHelper helper;
        static{
            //添加uri
            urimatcher.addURI("com.example.provider", "insert", INSERT);
            urimatcher.addURI("com.example.provider", "delete", DELETE);
            urimatcher.addURI("com.example.provider", "update", UPDATE);
            urimatcher.addURI("com.example.provider", "query", QUERY);
        }
        @Override
        public boolean onCreate() {
            helper = new MySQLiteOpenHelper(getContext());
            return false;
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
            // TODO Auto-generated method stub
            //匹配uri
            if(urimatcher.match(uri)==QUERY){
                SQLiteDatabase db = helper.getWritableDatabase();
                Cursor cursor = db.query("student", projection, selection, selectionArgs, null, null, sortOrder);
    
                return cursor;
            }
            return null;
        }
    
        @Override
        public String getType(Uri uri) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            // TODO Auto-generated method stub
            if(urimatcher.match(uri)==INSERT){
                SQLiteDatabase db = helper.getWritableDatabase();
                long insert2 = db.insert("student", null, values);
                db.close();
                return Uri.parse("content://com.example.provider"+insert2);
            }
            return null;
        }
    
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            // TODO Auto-generated method stub
            if(urimatcher.match(uri)==DELETE){
                SQLiteDatabase db = helper.getWritableDatabase();
                int delete2 = db.delete("student", selection, selectionArgs);
                return delete2;
            }
            return 0;
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                String[] selectionArgs) {
            // TODO Auto-generated method stub
            if(urimatcher.match(uri)==UPDATE){
                SQLiteDatabase db = helper.getWritableDatabase();
                int update2 = db.update("student", values, selection, selectionArgs);
                return update2;
            }
            return 0;
        }
    
    }
    
  • 和其他的几大大组件组件一样ContentProvider也需要在Manifest.xml里面注册,注册ContentProvider的时候,还要配置两个额外的属性。

    <provider android:name="com.example.contentproviderdemo.MyContentProder"
        android:authorities="com.example.provider"
        android:exported="true">
    </provider>
    

这样,我们就将这个application里面的数据通过ContentProvider暴露出去了,其他的application就可以通过getContentResolver()来访问这个application里面的数据。

2.在另外的application中进行对数据库的内容的操作

上面我们已经将数据暴露出来了,这里我们就在另外的application中来操作数据。

  • 我们在另外的一个application的布局文件中定义4个button,分别用来对contentprovide的数据进行增删改查。

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click1"
            android:text="查询"/>
         <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click2"
            android:text="删除"/>
          <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click3"
            android:text="添加"/>
           <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click4"
            android:text="更新"/>
    
    </LinearLayout>  
    
  • 在Mainctivity里面,我们通过设置button的点击事件来操作数据。

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        // 查询
        public void click1(View v) {
            Uri uri = Uri.parse("content://com.example.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 age =cursor.getString(2);
                    String score = cursor.getString(3);
                    System.out.println(name+" "+age+"  "+score);
                }
            }
        }
    
        // 删除
        public void click2(View v) {
            Uri uri = Uri.parse("content://com.example.provider/delete");
            int delete = getContentResolver().delete(uri, "_id=?", new String[]{"1"});
            System.out.println(delete);
        }
    
        // 添加
        public void click3(View v) {
            Uri uri = Uri.parse("content://com.example.provider/insert");
            ContentValues values =new ContentValues();
            values.put("name", "xiaoming");
            values.put("age", "100");
            values.put("score", "200");
            Uri insert = getContentResolver().insert(uri, values );
            System.out.println(insert);
        } 
        // 更新
        public void click4(View v) {
            Uri uri = Uri.parse("content://com.example.provider/update");
            ContentValues values =new ContentValues();
            values.put("score", "2000");
            int update = getContentResolver().update(uri, values , "_id =?", new String[]{"100"});
            System.out.println(update);
        }
    }
    

到这里为止,我们就已经会使用ContentProvider了。下面我们来写一个短信备份的案例。

使用ContentProvider实现手机短信备份

1.获取短信存储的信息

毫无疑问,手机短信存储在手机的数据库里面,所以我们首先要知道短信存储的情况。我们可以在手机文件夹的 \data\data\com.android.providers.telephony\databases\ 目录下找到mmssms.db文件,这就是存储短信的表,我们打开这张后发现,我们只需要通过查询这个表的3个字段就可以进行短信的完整备份,它们分别是:date表示短信的发送日期、address短信来源的号码、body表示短信的具体内容。

2.得到系统为短信设置的ContentProvider的Uri

想要得到这个,我们百度或者自己查下系统上层应用的源代码。如果我们要在源码里面找的话,需要在\providers\TelephonyProvider\src\com\android\providers\telephony\SmsProvider.java这个文件里面找。这里我粘一段静态代码块的内容参考:

 static {
    sURLMatcher.addURI("sms", null, SMS_ALL);
    sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
    sURLMatcher.addURI("sms", "inbox", SMS_INBOX);
    sURLMatcher.addURI("sms", "inbox/#", SMS_INBOX_ID);
    sURLMatcher.addURI("sms", "sent", SMS_SENT);
    //省略若干
    ...
    }

3.备份短信

备份短信的思路:从数据库中将短信获取后,将其序列化到SDcard中。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void click(View v){
        //设置Uri
        Uri uri=Uri.parse("content://sms");
        //查询所需要的数据
        Cursor cursor = getContentResolver().query(uri, new String[]{"address","date","body"},
                null, null, null);
        if(cursor!=null && cursor.getCount()>0){
            //获取xml解析器,开始序列化
            XmlSerializer serializer = Xml.newSerializer();
            //设置文件存储的位置
            File file =new File(Environment.getExternalStorageDirectory(),"smss.xml");
            //设置输出流

            FileOutputStream fos;
            try {
                fos = new FileOutputStream(file);
                serializer.setOutput(fos, "utf-8");
                //开始文档
                serializer.startDocument("utf-8", true);
                //根标签
                serializer.startTag(null, "smss");
                //将查询到的数据序列化到XML文件中
                while (cursor.moveToNext()) {

                    String address = cursor.getString(0);//短信人电话  为null
                    String date = cursor.getString(1);//短信发送时间
                    String body = cursor.getString(2);//短信内容
                    //根目录下的一级标题
                    serializer.startTag(null, "sms");
                    //设置address
                    serializer.startTag(null, "address");
                    serializer.text(address);
                    serializer.endTag(null, "address");

                    //设置date
                    serializer.startTag(null, "date");
                    serializer.text(date);
                    serializer.endTag(null, "date");

                    //设置body
                    serializer.startTag(null, "body");
                    serializer.text(body);
                    serializer.endTag(null, "body");

                    serializer.endTag(null, "sms");
                }
                serializer.endTag(null, "smss");
                //结束文档
                serializer.endDocument();
                Toast.makeText(this, "序列化完成", 0).show();;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }
}

最后,我们需要添加相应的权限。

<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值