从Uri到ContentProvider详解

来源:互联网 发布:php编程代码大全 编辑:程序博客网 时间:2024/05/16 12:02
  • Uri
     举例:content://org.crazyitxxxxx/words
  1. 协议部分:content:// 这部分是Android的ContentProvider规定默认协议
  2. authorities部分,org.crazyitxxxxx :ContentProvider的authorities.系统根据这个来操作那个ContentProvider。
  3. 资源部分:words。这部分是动态改变的。
   Uri还支持content://org.crazyitxxxxx/words/2
   含义:访问Word数据中ID为2的记录
 Uri还支持content://org.crazyitxxxxx/words/2/word
    含义:访问Word数据中ID为2的记录的Word字段
  1. ContentProvider所操作的数据除了来自数据库,也可以来自文件,xml等网络存储。
  2. ContentUri的withAppendId(uri,id)可以为路径加上id部分
                               parseId可以解析ID值  



  • 开发ContentProvider流程
  1. 创建ContentProvider子类,实现query(),insert(),update(),delete()方法
  2. 在AndroidManifest.xml文件中注册该ContentProvider,指定authorities属性。子元素<andorid:exported>指定是否能被其他应用调用
  3. 使用Context的getContentResolver()方法调用query(),insert(),updata(),delete()方法,实际上就是调用对应的Uri的相应方法。

  • ContentProvider的保安UriMacher
  1. 创建
     
public static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);、

  1.   注入Uri,以及指定的UriMacher对应的标志code

static {
    uriMatcher.addURI(Constants.Authorities, "words", STATUS_WORDS);

    uriMatcher.addURI(Constants.Authorities, "word/#", STATUS_WORD);
}

  1. int match(uri)  根据注册的uri得到code


int status = uriMatcher.match(uri);

switch (status) {

    case STATUS_WORDS:

        rows = wdb.delete(Constants.DictTable.TABLE, selection, selectionArgs);

        System.out.println("删除 完成 rows "+rows);

        break;

    case STATUS_WORD:

        long id = ContentUris.parseId(uri);

        String clause = Constants.DictTable.ID+" = "+id;

        String conditions = clause +" and "+ selection;

        rows = wdb.delete(Constants.DictTable.TABLE,conditions,selectionArgs);

        System.out.println("rows :"+rows);

        break;

}

  • 监听ContentProvider的数据改变之ContentObserver
  1.     getContext().getContextResolver().notifyChange(uri,null);在insert,delete,update中导致数据改变,调用此方法,null,就会通知注册在该Uri上的所用ContentObserver
  2.   注册监听。getContentResolver().registerContentObserver(uri,boolean,Observer),实现Observer类重写回调方法OnChanged()

代码:

public class MainActivity extends Activity
{

   @Override

   public void onCreate(Bundle savedInstanceState)

   {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);

      // 为content://sms的数据改变注册监听器

      getContentResolver().registerContentObserver(

         Uri.parse("content://sms"), true,

         new SmsObserver(new Handler()));

   }

   // 提供自定义的ContentObserver监听器类

   private final class SmsObserver extends ContentObserver

   {

      public SmsObserver(Handler handler)

      {

         super(handler);

      }

      public void onChange(boolean selfChange)

      {

         // 查询发送箱中的短信(处于正在发送状态的短信放在发送箱)

         Cursor cursor = getContentResolver().query(

            Uri.parse("content://sms/")

            , null, null, null, null);

         // 遍历查询得到的结果集,即可获取用户正在发送的短信

         while (cursor.moveToNext())

         {

            StringBuilder sb = new StringBuilder();

            // 获取短信的发送地址

            sb.append("address=").append(cursor

               .getString(cursor.getColumnIndex("address")));

            // 获取短信的标题

            sb.append(";subject=").append(cursor

               .getString(cursor.getColumnIndex("subject")));

            // 获取短信的内容

            sb.append(";body=").append(cursor

               .getString(cursor.getColumnIndex("body")));

            // 获取短信的发送时间

            sb.append(";time=").append(cursor

               .getLong(cursor.getColumnIndex("date")));

            System.out.println("发送短信:" + sb.toString());

         }

      }

   }

- 系统的ContentProvider

- 管理联系人的ContentProvider

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    contactList = (ListView) findViewById(R.id.lv_contact);

    initData();

}

private void initData() {

    Uri consUri = ContactsContract.Contacts.CONTENT_URI;

    Uri phoUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

    Uri emailUri = ContactsContract.CommonDataKinds.Email.CONTENT_URI;

    Uri uri = Uri.parse("content://com.android.contacts");

    Uri rawContactUri = uri.withAppendedPath(uri, "raw_contacts");

    Uri dataUri = uri.withAppendedPath(uri, "data");

    Uri mimeTypeUri = Uri.withAppendedPath(uri, "mimetypes");

    Cursor rawContactCousor = getContentResolver().query(rawContactUri, new String[]{"contact_id"}, null, null, null);

    while (rawContactCousor.moveToNext()) {

        String contactId = rawContactCousor.getString(0);

        System.out.println(contactId);

        Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"mimetype", "data1"}, "raw_contact_id = ?",new String[]{contactId}, null);

        String mimeType = null;

        while (dataCursor.moveToNext()) {

            mimeType = dataCursor.getString(0);

         //   Cursor mimeTypeCursor = getContentResolver().query(mimeTypeUri, new String[]{"mimetype"}, "raw_contact_id = ?", new String[]{StringId}, null);

           /* while (mimeTypeCursor.moveToNext()) {

                mimeType = mimeTypeCursor.getString(0);

                System.out.println("mimeType: " + mimeType);

            }

            mimeTypeCursor.close();*/

            String type = null;

            if ("vnd.android.cursor.item/email_v2".equals(mimeType)) {

                type = "email";

            } else if ("vnd.android.cursor.item/phone_v2".equals(mimeType)) {

                type = "phomeNumber";

            } else if ("vnd.android.cursor.item/name".equals(mimeType)) {

                type = "name";

            }

            String data = dataCursor.getString(1);

            System.out.println("name: "+type+" data: "+data);

        }

        dataCursor.close();

    }

    rawContactCousor.close();

}

2.获取短信数据:(区别于用Broadcast获取短信数据)

public class MainActivity extends AppCompatActivity {

    private Uri smsUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        smsUri = Uri.parse("content://sms");
        initData();
    }

    private void initData() {
        Cursor smsCursor = getContentResolver().query(smsUri, null, null, null, null);
        while(smsCursor.moveToNext()){
            String address = smsCursor.getString(smsCursor.getColumnIndex("address"));
            String body = smsCursor.getString(smsCursor.getColumnIndex("body"));
            System.out.println("address: "+address+" body: "+body);
        }
    }
}
0 0