[安卓基础]学习第九天

一、为什么需要内容提供者

1-1.回忆定义数据库

  1. 新建一个类继承SQLiteOpenHelper
public class MyOpenHelper extends SQLiteOpenHelper {

    public MyOpenHelper(Context context) {
        super(context, "test.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) {
        // TODO Auto-generated method stub

    }

}
  1. 打开数据库
MyOpenHelper myOpenHelper = new MyOpenHelper(this);

        SQLiteDatabase db = myOpenHelper.getWritableDatabase();
  1. 读取数据库
    Cursor cursor = db.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 + ": " + phone);
        }

    }
  1. chmod linux下修改文改文件的权限

二、内容提供者的原理

image

- 内容提供者把数据进行封装,其他应用都是用过内容解析者来访问
- 定义内容提供者,定义一个类继承ContentProvider

三、实现内容提供者的步骤

  1. 定义一个类继承ContentProvider
public class TestdbProvider extends ContentProvider {

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        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
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

}
  1. 在清单文件进行配置
    <provider
        android:name="com.elnui.day09_db.TestdbProvider"
        android:authorities="com.elnui.testdbprovider"
        android:exported="true"
        android:enabled="true">
    </provider>
  1. Url和Uri说明
  2. 写一个静态代码块,添加匹配规则
    static
    {
        /**
         * authority 和清单文件里面定义的要一样
         * path 任意的路径
         * 
         * com.elnui.provider/query
         * */
        sUriMather.addURI("com.elnui.provider", "query", QUERY_SUCCESS);
    }

[完整的TestdbProvider类代码]

public class TestdbProvider extends ContentProvider {

    // 定义一个urimatcher,路径匹配器
    private static final UriMatcher sUriMather = new UriMatcher(UriMatcher.NO_MATCH);

    private static final int QUERY_SUCCESS = 1;

    private MyOpenHelper myOpenHelper;

    // 定义静态代码块,添加匹配规则,规则可以多个
    static
    {
        /**
         * authority 和清单文件里面定义的要一样
         * path 任意的路径
         * 
         * com.elnui.provider/query
         * */
        sUriMather.addURI("com.elnui.testdbprovider", "query", QUERY_SUCCESS);
    }

    @Override
    public boolean onCreate() {
        myOpenHelper = new MyOpenHelper(getContext());
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {

        int code = sUriMather.match(uri);
        if(code == QUERY_SUCCESS){  // 说明路径匹配成功
            /**
             *  数据库的查询
             * */
            SQLiteDatabase db = myOpenHelper.getReadableDatabase();

            /**
             * table 表名
             * columns 查询的列,由参数String[] projection给出
             * selection 查询的条件
             * selectionArgs 查询的条件参数
             * */
            Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder);

            // 注意,这里的Cursor不能关
            return cursor;
        }else{
            throw new IllegalArgumentException("路径不匹配,请检查");
        }
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

}
  1. 解析
    Uri uri = Uri.parse("content://com.elnui.testdbprovider/query");    // 路径和内容提供者路径一样,前面还应加协议content://
    /**
     * uri 
     * projection 查询列
     * selection
     * selectionArgs
     * sortOrder
     * */
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);

    if(cursor != null){
        while(cursor.moveToNext()){
            String name = cursor.getString(1);
            String phone = cursor.getString(2);

            System.out.println("___2" + name + ": " + phone);
        }
    }

四、备份短信案例

public void click1(View v){

        try {
            // 获取XmlSerializer序列化实例
            XmlSerializer serializer = Xml.newSerializer();

            // 设置序列化参数
            File file = new File(Environment.getExternalStorageDirectory().getPath(),"backup.xml");
            FileOutputStream fos = new FileOutputStream(file);
            serializer.setOutput(fos, "utf-8");

            // 开始写
            serializer.startDocument("utf-8", true);
            serializer.startTag(null, "smss");



            // 使用内容解析者去解析即可
            Uri uri = Uri.parse("content://sms/inbox");

            Cursor cursor = getContentResolver().query(uri, new String[]{"address","date","body"}, null, null, null);
            if(cursor != null){
                while(cursor.moveToNext()){
                    String addr = cursor.getString(0);
                    String date = cursor.getString(1);
                    String body = cursor.getString(2);

                    System.out.println("___" + addr + date + body);

                    // 写sms节点
                    serializer.startTag(null, "sms");

                    // address
                    serializer.startTag(null, "address");
                    serializer.text(addr);
                    serializer.endTag(null, "address");

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

                    // 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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

五、利用内容提供者插入短信

public void click1(View v){
        Uri uri = Uri.parse("content://sms");
        ContentValues values = new ContentValues();
        values.put("address","10086");
        values.put("body","你的花费余额不足!");
        values.put("date",  System.currentTimeMillis());
        getContentResolver().insert(uri, values);
    }

六、读取联系人的案例

6-1. 三张重要的表

  1. data表

    • raw_contact_id ,实际上是raw_contacts表
    • mimetype_id ,1-email, 2-im, 3-nickname,5-phone, 7-name, 8-address,实际上对应mimetype表
  2. raw_contacts表

  3. mimetypes

6-2.实现步骤

  1. 读raw_contacts表的contact_id字段,获取联系人总数
  2. 根据raw_contacts_id读取data表的data1列和mimetype列

6-3.小细节

getContentResolver().query(data_uri, new String[]{"data1","mimetype_id"}, "raw_contact_id=?", new String[]{contact_id}, null);
查询的不是data表,查询的是view_data的视图

七、插入联系人

  1. 先往raw_contact表,contact_id列插入元素
  2. 同步到data表,data1列存所以联系人数据
public void click1(View v){
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri data_uri = Uri.parse("content://com.android.contacts/data");

        String name = et_name.getText().toString().trim();
        String address = et_address.getText().toString().trim();
        String emall = et_email.getText().toString().trim();
        String phone = et_phone.getText().toString().trim();

        // 查询raw_contacts中共几条数据
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        int count = cursor.getCount();
        int countid = count+1;

        ContentValues values = new ContentValues();
        values.put("contact_id", countid);

        getContentResolver().insert(uri, values);

        ////////////////////////////////////////////////////////////////////////
        // 插入名字
        ContentValues valuesName = new ContentValues();
        valuesName.put("data1", name);  //把数据插入到data1列
        valuesName.put("raw_contact_id", countid);//插入的数据属于那条联系人
        valuesName.put("mimetype","vnd.android.cursor.item/name");  //插入的 数据的数据类型是名字
        getContentResolver().insert(data_uri, valuesName);

        // 插入地址
        ContentValues valuesAddress = new ContentValues();
        valuesAddress.put("data1", address);    //把数据插入到data1列
        valuesAddress.put("raw_contact_id", countid);//插入的数据属于那条联系人
        valuesAddress.put("mimetype","vnd.android.cursor.item/postal-address_v2");  //插入的 数据的数据类型是名字
        getContentResolver().insert(data_uri, valuesAddress);

        // 插入email
        ContentValues valuesMail = new ContentValues();
        valuesMail.put("data1", emall); //把数据插入到data1列
        valuesMail.put("raw_contact_id", countid);//插入的数据属于那条联系人
        valuesMail.put("mimetype","vnd.android.cursor.item/email_v2");  //插入的 数据的数据类型是名字
        getContentResolver().insert(data_uri, valuesMail);

        // 插入号码
        ContentValues valuesPhone = new ContentValues();
        valuesPhone.put("data1", phone);    //把数据插入到data1列
        valuesPhone.put("raw_contact_id", countid);//插入的数据属于那条联系人
        valuesPhone.put("mimetype","vnd.android.cursor.item/phone_v2"); //插入的 数据的数据类型是名字
        getContentResolver().insert(data_uri, valuesPhone);


    }

八、内容观察者

==内容提供者==是四大组件,需要在清单文件配置

8-1.被观察的提供者中添加

            // 数据库被改了,自己发送消息
            getContext().getContentResolver().notifyChange(uri, null);

8-2.内容观察者

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 注册内存观察者
        Uri uri = Uri.parse("content://com.elnui.testdbprovider");
        getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler()));
    }

    private class MyObserver extends ContentObserver{

        public MyObserver(Handler handler) {
            super(handler);
        }
        @Override
        public void onChange(boolean selfChange) {
            System.out.println("___[ContentObserver]数据被修改了");
            super.onChange(selfChange);
        }
    }

九、内容观察者应用场景

十、安卓中的动画

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值