安卓中的四大组件_ContentProvider

本文深入探讨了在信息技术领域中关键的操作与应用,包括数据库管理、内容提供者使用、短信备份与恢复、联系人操作及内容观察者机制。文章详细介绍了如何创建数据库、使用SQLiteOpenHelper、创建内容提供者并实现Uri匹配,以及如何通过内容提供者进行短信备份和恢复、联系人查询与添加等操作。同时,文章还讲解了内容观察者在监测系统变化方面的应用,以及其在不同场景下的实践案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 创建数据库. SQLiteOpenHelper.

  • 调用的过程.

    1. 证监会程序, 创建一个内容提供者, 并且在清单文件中添加一个authorities属性.

    2. 证监会程序的内容提供者需要添加一些Uri标识(分机号), 为了方便去区分是操作哪一张表.

      mUriMatcher.addURI("com.ycy.domain.person", "person/insert", 1);
      
    3. 需要在内容提供者中的insert方法中判断, 被传进来的Uri对象匹配以下, 是否和我们上面添加的uri相匹配.

      int match = mUriMatcher.match(uri);
      switch (match) {
      case 1: // 对person表添加的操作
          System.out.println("对person表添加");
          break;
      default:
          throw new IllegalArgumentException("Uri 匹配失败, Uri: " + uri);
      }
      
    4. 其他的程序, 拿着证监会程序的内容提供者的Uri, 就可以访问.

  • 短信备份和恢复.

    • sms表就是系统用来存放所有的短信的.
    • 操作sms表的Uri: content://sms

    • 备份的内容: address, date, type, body

    通过内容提供者,获取系统数据库中所有的短信

    private List<Sms> getSmsListFromProvider() {
        Uri uri = Uri.parse("content://sms");
        ContentResolver resolver = getContentResolver();
        Cursor cursor = resolver.query(uri, new String[] { "address", "date",
                "type", "body" }, null, null, null);
        List<Sms> smsList = null;
        if (cursor != null && cursor.getCount() > 0) {
            smsList = new ArrayList<Sms>();
            Sms sms = null;
            while (cursor.moveToNext()) {
                sms = new Sms(cursor.getString(0), cursor.getLong(1),
                        cursor.getInt(2), cursor.getString(3));
                smsList.add(sms);
                sms = null;
            }
        }
        return smsList;
    }   
    

    从sd卡中取出备份的短信,并通过内容提供者插入到系统短信数据库中

    private boolean restoreSmsFromLocal(List<Sms> list) {
        ContentResolver resolver = getContentResolver();
        Uri uri = Uri.parse("content://sms");
        ContentValues values = new ContentValues();
        for (Sms sms : list) {
            values.put("address", sms.getAddress());
            values.put("date", sms.getDate());
            values.put("type", sms.getType());
            values.put("body", sms.getBody());
            resolver.insert(uri, values);
        }
        return true;
    }
    
  • 操作联系人.

    • raw_contacts 表存放着所有联系人列表, 此表中没有存储联系人的详细信息.

    • data 表中存放着每一个联系人的详细数据.

    • 查询所有联系人步骤:

      1. 查询rawcontacts表中所有的数据. 获取出每一个联系人的id.

        select _id from raw_contacts;
        
      2. 根据第一步查到每一个人的_id, 去data表中查询对应这个联系人的所有数据.

        select data1, mimetype from data where raw_contact_id = 1;
        
    • 添加一个联系人

      1. 查询rawcontacts表的最后一条记录的contactid. 再此基础上+1得到一个新的id.

      2. 向raw_contacts添加一条数据. 把上面得到的最新的id添加进去.

      3. 根据新的id, 向data表中添加三条数据.

        • 姓名
        • 号码
        • 邮箱
    • 操作rawcontacts表的Uri: content://com.android.contacts/rawcontacts

    • 操作data表的Uri: content://com.android.contacts/data

      private Uri rawcontactsUri = Uri.parse("content://com.android.contacts/raw_contacts");
      private Uri dataUri = Uri.parse("content://com.android.contacts/data");
      private ContentResolver resolver = getContentResolver();
      

      通过内容提供者读取出系统联系人,并存入集合中

      private List<ContactsInfo> readContacts() {
          Cursor rawcontactsCursor = resolver.query(rawcontactsUri,
                  new String[] { "_id" }, null, null, null);
          List<ContactsInfo> list = null;
          if (rawcontactsCursor != null && rawcontactsCursor.getCount() > 0) {
              Cursor dataCursor = null;
              ContactsInfo contacts = null;
              list = new ArrayList<ContactsInfo>();
              String data1 = "", mimetype = "";
              while (rawcontactsCursor.moveToNext()) {
                  int id = rawcontactsCursor.getInt(0);
      
                  contacts = new ContactsInfo();
                  dataCursor = resolver.query(dataUri, new String[] { "data1",
                          "mimetype" }, "raw_contact_id=?", new String[] { id
                          + "" }, null);
      
                  if (dataCursor != null && dataCursor.getCount() > 0) {
                      while (dataCursor.moveToNext()) {
                          data1 = dataCursor.getString(0);
                          mimetype = dataCursor.getString(1);
      
                          if ("vnd.android.cursor.item/name".equals(mimetype)) {
                              contacts.setName(data1);
                          } else if ("vnd.android.cursor.item/phone_v2"
                                  .equals(mimetype)) {
                              contacts.setPhone(data1);
                          } else if ("vnd.android.cursor.item/email_v2"
                                  .equals(mimetype)) {
                              contacts.setEmail(data1);
                          }
                      }
                      dataCursor.close();
                  }
      
                  list.add(contacts);
              }
      
              rawcontactsCursor.close();
          }
          return list;
      }
      

      通过内容提供者,将数据添加到系统联系人数据库中

      private void writeContacts() {
      Cursor cursor = resolver.query(rawcontactsUri,
              new String[] { "_id" }, null, null,
              "_id desc limit 1");
      int contact_id;
      if (cursor != null && cursor.moveToFirst()) {
          contact_id = cursor.getInt(0);
          cursor.close();
      } else {
          contact_id = 0;
      }
      int newContact_id = contact_id + 1;
      
      // 插入到raw_contacts表中
      ContentValues values = new ContentValues();
      values.put("contact_id", newContact_id);
      
      resolver.insert(rawcontactsUri, values);
      
      // 插入到data表中
      // 插入姓名
      ContentValues dataValues = new ContentValues();
      dataValues.put("mimetype", "vnd.android.cursor.item/name");
      dataValues.put("raw_contact_id", newContact_id);
      dataValues.put("data1", "name12345678");
      resolver.insert(dataUri, dataValues);
      
      // 插入电话
      dataValues.put("mimetype", "vnd.android.cursor.item/phone_v2");
      dataValues.put("raw_contact_id", newContact_id);
      dataValues.put("data1", "12345678");
      resolver.insert(dataUri, dataValues);
      
      // 插入邮箱
      dataValues.put("mimetype", "vnd.android.cursor.item/email_v2");
      dataValues.put("raw_contact_id", newContact_id);
      dataValues.put("data1", "12345678@name12345678.com");
      resolver.insert(dataUri, dataValues);
      

      }

  • 内容观察者(观察某个数据库数据是否改变) ContentObserver

    • 观察手机发出去的短信.

      • 发件箱的Uri: content://sms/outbox

        // 观察系统sms表是否有变化
        ContentResolver resolver = getContentResolver();
        Uri uri = Uri.parse("content://sms");
        
        // 注册一个内容观察者, 观察系统短信中sms表的变化, sms一旦发生变化, 会触发MyContentObserver类的onChange方法
        resolver.registerContentObserver(uri, true, new MyContentObserver(new Handler()));
        
        /**
         * @author andong
         * 内容观察者类
         */
        class MyContentObserver extends ContentObserver {
        
            public MyContentObserver(Handler handler) {
                super(handler);
            }
        
            @Override
            public void onChange(boolean selfChange) {
                System.out.println("sms表发生改变了...");
        
                // 查询发件箱里的短信.
                Uri outBoxUri = Uri.parse("content://sms/outbox");
                String[] projection = {"address", "date", "body"};
                Cursor cursor = getContentResolver().query(outBoxUri, projection, null, null, null);
                if(cursor != null && cursor.getCount() > 0) {
                    while(cursor.moveToNext()) {
                        String address = cursor.getString(0);
                        long date = cursor.getLong(1);
                        String body = cursor.getString(2);
        
                        String strDate = DateFormat.getTimeFormat(MainActivity.this).format(date);
        
                        System.out.println("号码: " + address + ", 日期: " + strDate + ", 内容: " + body);
                    }
                    cursor.close();
                }
            }
        }
        
  • 内容观察者使用步骤

    1. 在警察应用中观察一个Uri.

    2. 在证监会应用中的增删改三个方法, 发出通知Uri, 数据改变了.

    3. 警察的应用中的内容观察者的onChange方法会被执行.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值