androoid framework学习之ContentProvider组件(很不错)

来源:互联网 发布:网络稳定查询 编辑:程序博客网 时间:2024/05/16 17:49

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 0
原创粉丝点击