美文网首页
六、ContentProvider

六、ContentProvider

作者: 浮生若梦OvO | 来源:发表于2019-06-20 22:01 被阅读0次

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

    内容提供者:提供了统一的访问数据库的方式,可以让其他应用程序来调用。

    二、编写内容提供者

    • 在工程中添加一个内容提供者的类,继承了ContentProvider类型,实现了增删改查的方法;`

    • 在清单文件中配置一个provider节点,指定authorities(相当于网站的域名,用来唯一标示一个内容提供者)、exported为true

    (从4.1开始,exported没有指定为true,表示其他应用程序不能访问这个内容提供者);
    
    代码:
    
    package com.itheima.accountdb;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.net.Uri;
    
    public class AccountContentProvider extends ContentProvider {
    
        private static final int INSERT = 0;
        private static final int DELETE = 1;
        private static final int QUERY = 2;
        private static final int UPDATE = 3;
        private AccountDBHelper helper;
    
        //mUriMatcher uri匹配,NO_MATCH 匹配uri时如果没有匹配成功返回NO_MATCH
        private static UriMatcher  mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    
        //mUriMatcher的岗前培训 content://com.itheima.accountdb.AccountContentProvider/insert
        static{
            //添加可以匹配到的uri
            //authority 内容提供者的主机名
            //path 访问的路径
            //code 匹配,当匹配成功时会返回这个匹配码
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "insert", INSERT);
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "delete", DELETE);
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "query", QUERY);
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "update", UPDATE);
        }
    
        /**
         * 内容提供者一创建的时候会调用这个方法
         * 初始化实例对象
         */
        @Override
        public boolean onCreate() {
            helper = new AccountDBHelper(getContext());
            return false;
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            if(mUriMatcher.match(uri) == INSERT){
    
                SQLiteDatabase db = helper.getWritableDatabase();
                db.insert("account", null, values);
                db.close();
            }else{
                System.out.println("口令不正确,请走开...");
            }
            return null;
        }
    
        @Override
        public int delete(Uri arg0, String arg1, String[] arg2) {
            return 0;
        }
    
        @Override
        public String getType(Uri uri) {
            return null;
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
            return null;
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                String[] selectionArgs) {
            return 0;
        }
    }
    
    

    配置文件:

     <!-- authorities:主机名,唯一标示内容提供者;exported,从4.1开始,exported没有指定为true,表示其他应用程序不能访问这个内容提供者 -->
        <provider
            android:name="com.itheima.accountdb.AccountContentProvider"
            android:authorities="com.itheima.accountdb.AccountContentProvider"
            android:exported="true" >
        </provider>
    
    

    三、内容提供者工作的原理

    内容提供者解析器是通过uri匹配要访问的内容提供者和访问路径的;

    四、内容提供者的增删改查的实现

    代码:
    
    package com.itheima.accountdb;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.net.Uri;
    
    public class AccountContentProvider extends ContentProvider {
    
        private static final int INSERT = 0;
        private static final int DELETE = 1;
        private static final int QUERY = 2;
        private static final int UPDATE = 3;
        private AccountDBHelper helper;
    
        //mUriMatcher uri匹配,NO_MATCH 匹配uri时如果没有匹配成功返回NO_MATCH
        private static UriMatcher  mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    
        //mUriMatcher的岗前培训 content://com.itheima.accountdb.AccountContentProvider/insert
        static{
            //添加可以匹配到的uri
            //authority 内容提供者的主机名
            //path 访问的路径
            //code 匹配,当匹配成功时会返回这个匹配码
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "insert", INSERT);
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "delete", DELETE);
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "query", QUERY);
            mUriMatcher.addURI("com.itheima.accountdb.AccountContentProvider", "update", UPDATE);
        }
    
        /**
         * 内容提供者一创建的时候会调用这个方法
         * 初始化实例对象
         */
        @Override
        public boolean onCreate() {
            helper = new AccountDBHelper(getContext());
            return false;
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            if(mUriMatcher.match(uri) == INSERT){
    
                SQLiteDatabase db = helper.getWritableDatabase();
                db.insert("account", null, values);
                db.close();
            }else{
                System.out.println("口令不正确,请走开...");
            }
            return null;
        }
    
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            int n = 0;
            if(mUriMatcher.match(uri) == DELETE){
    
                SQLiteDatabase db = helper.getWritableDatabase();
                n  = db.delete("account", selection, selectionArgs);
                db.close();
            }else{
                System.out.println("口令不正确,请走开...");
            }
    
            return n ;
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
    
            if(mUriMatcher.match(uri) == QUERY){
    
                SQLiteDatabase db = helper.getWritableDatabase();
                Cursor cursor  = db.query("account",projection,selection , selectionArgs, null, null, null);
                return  cursor;
            }else{
                System.out.println("口令不正确,请走开...");
                return null;
            }
    
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                String[] selectionArgs) {
            int n = 0;
            if(mUriMatcher.match(uri) == UPDATE){
    
                SQLiteDatabase db = helper.getWritableDatabase();
                n = db.update("account", values, selection, selectionArgs);
                db.close();
    
            }else{
                System.out.println("口令不正确,请走开...");
            }
    
            return n ;
        }
    
        @Override
        public String getType(Uri uri) {
            return null;
        }
    
    }
    
    

    五、内容提供者的使用场景

    - 当需要给其他应用程序提供访问数据的接口(内容提供者的增删改查的方法);`
    
    - 当需要访问其他应用程序的数据库中的数据时,需要使用内容提供者解析器来访问内容提供者;
    
    - 更多的是去访问系统暴露出来的数据, 联系人的应用 、短信的应用。
    

    六、插入短信

    - 路径 uri:content://sms/
    - 短信表中需要关系的几列:address、date、type、body
    
    代码:
        ContentResolver resolver = getContentResolver();
        //调用短信内容提供者增删改查方法需要使用uri
        Uri uri = Uri.parse("content://sms/");
        ContentValues values = new ContentValues();
    
        values.put("address", "18910903535");
        values.put("date", System.currentTimeMillis());
        values.put("type", 1);
        values.put("body", "itheimasdfdsfdsfdsf");
    
        resolver.insert(uri,values);
    
    

    七、内容提供者uri的写法

    content://com.itheima.accountdb.AccountContentProvider/insert
    http://www.baidu.com/image/1.jpg
    组成部分:
            scheme名称、主机名(唯一标示内容提供者的)、path路径(操作的类型)、访问的数据资源;
    
    

    八、短信的备份

    步骤:
        1、知道查询短信数据库表的uri;
        2、通过内容提供者解析器查询短信数据;
        3、把查询出来的短信数据序列化到xml的文件上;
    
    

    代码:

    package com.itheima.copysms;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import org.xmlpull.v1.XmlSerializer;
    
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Xml;
    import android.view.View;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void backup(View v) {
    
            try {
    
                //1、知道查询短信数据库表的uri
                ContentResolver resolver = getContentResolver();
                Uri uri = Uri.parse("content://sms/");
                //2、通过内容提供者解析器查询短信数据;
                Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, "date desc");
    
                XmlSerializer s = Xml.newSerializer();
    
                FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/sms_backup.xml"));
                s.setOutput(fos, "UTF-8");
    
                s.startDocument("UTF-8", true);
                s.startTag(null, "smss");
    
                while(cursor.moveToNext()){
                    String address = cursor.getString(0);
                    long date = cursor.getLong(1);
                    int type = cursor.getInt(2);
                    String body = cursor.getString(3);
                    //3、把查询出来的短信数据序列化到xml的文件上;
                    s.startTag(null, "sms");
    
                    s.startTag(null, "address");
                    s.text(address);
                    s.endTag(null, "address");
    
                    s.startTag(null, "date");
                    s.text(date+"");
                    s.endTag(null, "date");
    
                    s.startTag(null, "type");
                    s.text(type+"");
                    s.endTag(null, "type");
    
                    s.startTag(null, "body");
                    s.text(body+"");
                    s.endTag(null, "body");
    
                    s.endTag(null, "sms");
                }
    
                s.endTag(null, "smss");
                s.endDocument();
                fos.close();
                cursor.close();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    

    九、短信的还原操作

    步骤:
    1、读取已经备份的短信数据文件,使用pull解析xml格式的数据,读到list集合里面;
    2、还原数据数据之前,先删除原来的短信数据;
    3、通过内容提供者解析忘短信应用程序中插入短信数据;
    
    代码:
    
    package com.itheima.restoresms;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserException;
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.content.ContentValues;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Xml;
    import android.view.View;
    
    import com.itheima.restoresms.domain.SMSInfo;
    
    public class MainActivity extends Activity {
    
        private SMSInfo sms;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void restoresms(View view) {
            try {
                // 1、读取已经备份的短信数据文件,使用pull解析xml格式的数据,读到list集合里面;
                File file = new File(Environment.getExternalStorageDirectory()
                        + "/sms_backup.xml");
                FileInputStream fis = new FileInputStream(file);
    
                List<SMSInfo> list = getSMSList(fis);
                // 2、还原数据数据之前,先删除原来的短信数据;
                ContentResolver resolver = getContentResolver();
                Uri uri = Uri.parse("content://sms/");
                resolver.delete(uri, null, null);
                System.out.println("=====删除了原来的短信=======");
                // 3、通过内容提供者解析忘短信应用程序中插入短信数据;
                for(SMSInfo sms : list){
                    ContentValues values = new ContentValues();
    
                    values.put("address", sms.getAddress());
                    values.put("date", sms.getDate());
                    values.put("type", sms.getType());
                    values.put("body", sms.getBody());
                    resolver.insert(uri, values);
                }
                System.out.println("======还原短信成功=========");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private List<SMSInfo> getSMSList(FileInputStream fis) {
    
            try {
                XmlPullParser parser = Xml.newPullParser();
                parser.setInput(fis, "UTF-8");
    
                List<SMSInfo> list = new ArrayList<SMSInfo>();
                int type = parser.getEventType();
                while (type != XmlPullParser.END_DOCUMENT) {
                    switch (type) {
                    case XmlPullParser.START_TAG:// 标签的开始位置
                        if ("sms".equals(parser.getName())) {
                            sms = new SMSInfo();
                        } else if ("address".equals(parser.getName())) {
                            String address = parser.nextText();
                            sms.setAddress(address);
                        } else if ("date".equals(parser.getName())) {
                            String date = parser.nextText();
                            sms.setDate(date);
                        } else if ("type".equals(parser.getName())) {
                            String smsType = parser.nextText();
                            sms.setType(smsType);
                        } else if ("body".equals(parser.getName())) {
                            String body = parser.nextText();
                            sms.setBody(body);
                        }
                        break;
    
                    case XmlPullParser.END_TAG:// 标签的结束位置
                        if ("sms".equals(parser.getName())) {
                            list.add(sms);
                            System.out.println("---sms------" + sms);
                            sms = null;
                        }
                        break;
                    }
                    //解析下一个事件类型
                    type= parser.next();
                }
                return list;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    
    

    十、联系人数据库的表结构

    image.png
    raw_contacts:contact_id 联系人的ID;
    data:联系人的信息;
    mimetypes:联系人信息字段的名称;
    
    

    步骤:

    1、知道使用内容提供者读取以上三张表时它们的uri;
        data:content://com.android.contacts/data/
        raw_contacts:content://com.android.contacts/raw_contacts/
    2、通过内容提供者关联查询这三张表;
    
    

    代码:

    权限:
    
         <uses-permission android:name="android.permission.READ_CONTACTS"/>
        <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
    
    MainActivity.java:
    
        package com.itheima.readcontacts;
    
        import android.app.Activity;
        import android.content.ContentResolver;
        import android.database.Cursor;
        import android.net.Uri;
        import android.os.Bundle;
        import android.view.View;
    
        public class MainActivity extends Activity {
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
            }
    
            public void readContacts(View view) {
    
                ContentResolver resolver = getContentResolver();
    
                Uri uri = Uri.parse("content://com.android.contacts/raw_contacts/");
    
                Cursor cursor = resolver.query(uri, new String[]{"_id"}, null, null, null);
    
                while(cursor.moveToNext()){
                    long contact_id = cursor.getLong(0);
                    System.out.println("=========contact_id="+contact_id);
    
                    Uri datauri = Uri.parse("content://com.android.contacts/data/");
                    //mimetype 代表mimetypes表中一条记录,可以简单的理解为view_data视图
                    Cursor dataCursor = resolver.query(datauri, new String[]{"mimetype","raw_contact_id","data1"}, "raw_contact_id=?", new String[]{contact_id+""}, null);
    
                    while(dataCursor.moveToNext()){
                        String mimetype = dataCursor.getString(0);
                        long raw_contact_id = dataCursor.getLong(1);
                        String data1 = dataCursor.getString(2);
    
                        System.out.println("raw_contact_id="+raw_contact_id+"; mimetype="+mimetype+"; data1="+data1);
                    }
                }
            }
    
        }
    
    

    十一、联系人的还原

    步骤:
    1、在raw_contacts插入一条数据:contact_id=id=总记录数+1;
    2、在data表中插入数据:mimetype_id,raw_contact_id,data1;
    
    

    代码:

    package com.itheima.insertcontact;
    
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void insert(View view) {
    
            ContentResolver resolver = getContentResolver();
    
            Uri rawconturi = Uri
                    .parse("content://com.android.contacts/raw_contacts/");
            Cursor rawcursor = resolver.query(rawconturi, null, null, null, null);
            int rows = rawcursor.getCount();
    
            ContentValues values = new ContentValues();
            values.put("contact_id", rows + 1);
            // 在raw_contacts表中插入一条数据
            resolver.insert(rawconturi, values);
    
            Uri datauri = Uri.parse("content://com.android.contacts/data/");
    
            ContentValues nameValues = new ContentValues();
    
            nameValues.put("mimetype", "vnd.android.cursor.item/name");
            nameValues.put("raw_contact_id", rows + 1);
            nameValues.put("data1", "wangwu");
            resolver.insert(datauri, nameValues);
    
            ContentValues phoneValues = new ContentValues();
    
            phoneValues.put("mimetype", "vnd.android.cursor.item/phone_v2");
            phoneValues.put("raw_contact_id", rows + 1);
            phoneValues.put("data1", "13900000099");
            resolver.insert(datauri, phoneValues);
    
            ContentValues emailValues = new ContentValues();
    
            emailValues.put("mimetype", "vnd.android.cursor.item/email_v2");
            emailValues.put("raw_contact_id", rows + 1);
            emailValues.put("data1", "wangwu@itcast.cn");
            resolver.insert(datauri, emailValues);
    
            rawcursor.close();
    
        }
    }
    
    

    十二、内容观察者

    内容观察者:主要是用来观察内容提供者里面数据的变化情况;
    
    

    十三、短信窃听器

    代码:

    package com.itheima.smslistener;
    
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.database.ContentObserver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Handler;
    
    public class MainActivity extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        //得到内容提供者的解析器
        ContentResolver resolver = getContentResolver();
        //指定目标提供者的uri
        Uri uri = Uri.parse("content://sms/");
        //给指定的内容提供者注册一个内容观察者
        resolver.registerContentObserver(uri, true, new SmsContentObserver(new Handler()));
    }
    
    private class SmsContentObserver extends ContentObserver{
    
        public SmsContentObserver(Handler handler) {
            super(handler);
        }
    
        /**
         * 内容提供者中的数据发生变化时调用这个方法
         */
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
    
            ContentResolver resolver = getContentResolver();
            Uri uri = Uri.parse("content://sms/");
    
            Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, "date desc");
            cursor.moveToNext();   
            String address = cursor.getString(0);
            long date = cursor.getLong(1);
            int type = cursor.getInt(2);
            String body = cursor.getString(3);
            System.out.println("address="+address+"; date="+date+"; type="+type+"; body="+body);
        }`
    
    }
    

    十四、界面提醒方式

    • Toast

    • Dialog

    • Notification --通知

      
      // 高板本发布通知
       * //获取到通知的管理者
      NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
      
      //构建一个通知对象 --链式调用
      Notification noti = new Notification.Builder(this)
      .setContentTitle("这是通知的标题")
      .setContentText("这是通知的内容")
      .setSmallIcon(R.drawable.ic_launcher)
      .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
      .build();
      
      //发布一条通知
      manager.notify(1, noti);*/
      
      // 低版本发通知
      
      // 获取到通知的管理者
      NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
      
      //定义一个通知对象,指定显示的小图片 、 显示的翻滚文字 、 发布通知的事件
      Notification noti = new Notification(R.drawable.ic_launcher, "您有一条未读的消息", System.currentTimeMillis());
      Intent intent = new Intent();
      intent.setAction(Intent.ACTION_CALL);
      intent.setData(Uri.parse("tel://10086"));
      
      //定义点击通知之后跳转的效果
      PendingIntent cotnentIntent = PendingIntent.getActivity(this, 1, intent, 0);
      
      //用于指定点击之后跳转的效果和拖动通知下来之后显示的内容
      noti.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容", cotnentIntent);
      
      // 发布一条通知
      manager.notify(1, noti);`
      
      
    • 十五、使用内容提供者的步骤

    • 定义一个类,继承ContentProvider

      <pre xml:space="preserve" data-mce-style="font-size: 13px; font-family: Consolas, &amp;apos; liberation mono&amp;apos;, courier, monospace; background-color: #f8f8f8; overflow-x: auto; overflow-y: auto; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 6px 10px 6px 10px; margin: 15px 0px 15px 0px; border: 1px solid #cccccc;" style="margin: 15px 0px; padding: 6px 10px; border: 1px solid rgb(204, 204, 204); line-height: 1.57143em; font-family: Monaco, Courier, monospace; font-size: 13px; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px;">`/**
       * 这是银行的内部人员 - 内容提供者
       * 里面存在CRUD的方法,对外暴露这四个方法,其他应用可以根据不同的方法执行不同的操作
       *
       */
      public class BcakDoor extends ContentProvider {
          ...
      }` </pre>
      
    • 注册内容提供者,要指定作者名

      <pre xml:space="preserve" data-mce-style="font-size: 13px; font-family: Consolas, &amp;apos; liberation mono&amp;apos;, courier, monospace; background-color: #f8f8f8; overflow-x: auto; overflow-y: auto; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 6px 10px 6px 10px; margin: 15px 0px 15px 0px; border: 1px solid #cccccc;" style="margin: 15px 0px; padding: 6px 10px; border: 1px solid rgb(204, 204, 204); line-height: 1.57143em; font-family: Monaco, Courier, monospace; font-size: 13px; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px;">`<!-- 注册内容提供者的时候要加上作者名,这个作者名有一点类似隐式意图注册中的action动作。
      

      当其他应用来操作这个内容提供者的时候,必须要带上这个作者名,否则将不会为它干活 -->
      <provider android:name="com.itheima.db.BcakDoor"
      android:authorities="com.itheima.db.BANK"></provider>` </pre>

    • 在内容提供者内部声明URI匹配器

        <pre xml:space="preserve" data-mce-style="font-size: 13px; font-family: Consolas, &amp;apos; liberation mono&amp;apos;, courier, monospace; background-color: #f8f8f8; overflow-x: auto; overflow-y: auto; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 6px 10px 6px 10px; margin: 15px 0px 15px 0px; border: 1px solid #cccccc;" style="margin: 15px 0px; padding: 6px 10px; border: 1px solid rgb(204, 204, 204); line-height: 1.57143em; font-family: Monaco, Courier, monospace; font-size: 13px; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px;">`//定义一个URI的匹配器,只要有人来访问CRUD的方法,都先用这个匹配器去判断或者
        //叫做匹配来访的uri, 如果uri,匹配,就放行让其执行后续的代码,否则将返回不可以执行。
      
        static UriMatcher  matcher = new UriMatcher(UriMatcher.NO_MATCH);` </pre>
      
    • 使用静态代码块预设匹配规则

       <pre xml:space="preserve" data-mce-style="font-size: 13px; font-family: Consolas, &amp;apos; liberation mono&amp;apos;, courier, monospace; background-color: #f8f8f8; overflow-x: auto; overflow-y: auto; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 6px 10px 6px 10px; margin: 15px 0px 15px 0px; border: 1px solid #cccccc;" style="margin: 15px 0px; padding: 6px 10px; border: 1px solid rgb(204, 204, 204); line-height: 1.57143em; font-family: Monaco, Courier, monospace; font-size: 13px; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px;">`static{
           //预设好了一个匹配规则,来访的uri必须匹配以下的规则,也就是主机名必须匹配主机名,
           //path必须匹配path
           //一般这里的path都不写一些无意义的单词,通常都写表名,这是为了更好的查看当前来访的到底是想操作哪一张表
           matcher.addURI("com.itheima.db.BANK", "account", 1);
           /*matcher.addURI("com.itheima.db.BANK", "stu", 2);
           matcher.addURI("com.itheima.db.BANK", "stu", 2);
           matcher.addURI("com.itheima.db.BANK", "stu", 2);
           matcher.addURI("com.itheima.db.BANK", "stu", 2);*/
       }` </pre>
      
    • 在CRUD方法内部先判断uri是否匹配

        <pre xml:space="preserve" data-mce-style="font-size: 13px; font-family: Consolas, &amp;apos; liberation mono&amp;apos;, courier, monospace; background-color: #f8f8f8; overflow-x: auto; overflow-y: auto; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 6px 10px 6px 10px; margin: 15px 0px 15px 0px; border: 1px solid #cccccc;" style="margin: 15px 0px; padding: 6px 10px; border: 1px solid rgb(204, 204, 204); line-height: 1.57143em; font-family: Monaco, Courier, monospace; font-size: 13px; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px;"> `@Override
            public int delete(Uri uri, String selection, String[] selectionArgs) {
                if(matcher.match(uri) == 1){ //表名口令都对,主机名对了,path也对了
                    System.out.println("delete...");
      
                    DB db  = new DB(getContext());
                    SQLiteDatabase database = db.getWritableDatabase(); 
                    database.delete("account", selection, selectionArgs);
                    database.close();
                }else { //如果不匹配
                    throw  new IllegalArgumentException("口令错误,滚犊子~~");
                }
                return 0;
            }` </pre>
      
    • 如果匹配,就执行数据库的CRUD

    • 在其他应用里面先获取内容解析者

        <pre xml:space="preserve" data-mce-style="font-size: 13px; font-family: Consolas, &amp;apos; liberation mono&amp;apos;, courier, monospace; background-color: #f8f8f8; overflow-x: auto; overflow-y: auto; border-top-left-radius: 3px 3px; border-top-right-radius: 3px 3px; border-bottom-right-radius: 3px 3px; border-bottom-left-radius: 3px 3px; padding: 6px 10px 6px 10px; margin: 15px 0px 15px 0px; border: 1px solid #cccccc;" style="margin: 15px 0px; padding: 6px 10px; border: 1px solid rgb(204, 204, 204); line-height: 1.57143em; font-family: Monaco, Courier, monospace; font-size: 13px; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px;">`//1\. 获取到内容解析者
        ContentResolver resolver = getContentResolver();` </pre>
      
    • 定义URI,然后访问CRUD方法

        `//定义往数据库添加的数据
        ContentValues values = new ContentValues();
        values.put("name", "zhangsan");
        values.put("money", 500);
        //定义了访问内容提供者的口令,必须以content打头  http://www.baidu.com/image
        Uri uri = Uri.parse("content://com.itheima.db.BANK/xiaojidunmogu");
      
        //3执行增加的方法
        resolver.insert(uri, values);`
      

    相关文章

      网友评论

          本文标题:六、ContentProvider

          本文链接:https://www.haomeiwen.com/subject/mqwlqctx.html