Android ContentProvider内容提供者

来源:互联网 发布:做淘宝赚钱吗怎么做 编辑:程序博客网 时间:2024/06/08 05:26

定义
ContentProvider为不同的软件之间数据共享,提供统一的接口
当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据

主要方法
public boolean onCreate()// 在创建ContentProvider时调用
public Cursor query(Uri, String[], String, String[], String) //用于查询指定Uri的ContentProvider,返回一个Cursor
public Uri insert(Uri, ContentValues) //用于添加数据到指定Uri的ContentProvider中,(外部应用向ContentProvider中添加数据)
public int update(Uri, ContentValues, String, String[]) //用于更新指定Uri的ContentProvider中的数据
public int delete(Uri, String, String[])// 用于从指定Uri的ContentProvider中删除数据
public String getType(Uri) //用于返回指定的Uri中的数据的MIME类型

Uri
Uri 通用资源标志符(Universal Resource Identifier)Uri代表要操作的数据。
Android中可用的每种资源(图像、视频等)都可以用Uri来表示。Uri的结构由以下几个部分组成
scheme、authority、path、query、fragment
其中authority又分为host和port。
它的格式根据划分的详细程度可以分为三种
如下:
[scheme:][scheme-specific-part][#fragment]
[scheme:][//authority][path][?query][#fragment]
[scheme:][//host:port][path][?query][#fragment]——最详细的划分形式

例如:
Uri:
http://www.baidu.com:8080/yourpath/fileName.html?id=15&name=du#dmk

对应的:
scheme:http:
fragment:dmk
query:id=15&name=du
authority:www.baidu.com:8080
path:yourpath/fileName.html
host和port:www.baidu.com和8080

注意:
在Uri中除了scheme、authority是必须要有的,其它的几个path、query、fragment,它们每一个可以选择性的要或不要,但顺序不能变

用代码获取uri:
getScheme() :获取Uri中的scheme字符串部分,在这里是http
getSchemeSpecificPart():获取Uri中的scheme-specific-part:部分,这里是:http://www.baidu.com:8080/yourpath/fileName.html?
getFragment():获取Uri中的fragment部分,即dmk
getAuthority():获取Uri中Authority部分,即www.baidu.com:8080
getPath():获取Uri中path部分,即/yourpath/fileName.html
getQuery():获取Uri中的query部分,即id=15&name=du
getHost():获取Authority中的Host字符串,即www.baidu.com
getPost():获取Authority中的Port字符串,即8080

使用contentProvider的流程

重写一个contentProviter

public class TestContentProvider extends ContentProvider {    //这里的AUTHORITY就是我们在AndroidManifest.xml中配置的authorities    public static final String AUTHORITY = "com.lh.knowledge.contentprovider";    //匹配成功后的匹配码    private static final int MATCH_ALL_CODE = 100;    private static final int MATCH_ONE_CODE = 101;    private static UriMatcher uriMatcher;//uri匹配器    private Cursor cursor = null;//游标    List<TestBean> testBeanList = new ArrayList<>();    @Override    public boolean onCreate() {        initData();        //添加要匹配的uri,匹配不成功返回NO_MATCH(-1)        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);        /**         * uriMatcher.addURI(authority, path, code); 其中         * authority:主机名(用于唯一标示一个ContentProvider,这个需要和清单文件中的authorities属性相同)         * path:路径路径(可以用来表示我们要操作的数据,路径的构建应根据业务而定)         * code:返回值(用于匹配uri的时候,作为匹配成功的返回值)         */        uriMatcher.addURI(AUTHORITY, "student", MATCH_ALL_CODE);// 匹配记录集合        uriMatcher.addURI(AUTHORITY, "student/#", MATCH_ONE_CODE);// 匹配单条记录        return false;    }    private void initData() {        TestBean testBean1 = new TestBean();        testBean1.setId(1);        testBean1.setName("aaa");        testBean1.setPrice(5.2);        testBean1.setSex(false);        testBeanList.add(testBean1);        TestBean testBean2 = new TestBean();        testBean1.setId(2);        testBean1.setName("bbb");        testBean1.setPrice(6.2);        testBean1.setSex(true);        testBeanList.add(testBean2);        TestBean testBean3 = new TestBean();        testBean1.setId(3);        testBean1.setName("ccc");        testBean1.setPrice(0.2);        testBean1.setSex(false);        testBeanList.add(testBean3);    }    /**     * @param uri     * @param projection     * @param selection     * @param selectionArgs     * @param sortOrder     * @return     */    @Nullable    @Override    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {        return null;    }    @Nullable    @Override    public String getType(@NonNull Uri uri) {        return null;    }    @Nullable    @Override    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {        int match = uriMatcher.match(uri);        if (match != MATCH_ALL_CODE) {//这里不能匹配集合,只能匹配单个            throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());        }        //        int indexId = values.getAsInteger("indexId");        Uri insertUri = ContentUris.withAppendedId(uri, indexId);        if (indexId > 0) {            TestBean testBean = new TestBean();            testBean.setId(indexId);            testBean.setName("content provider userid " + indexId);            testBeanList.add(testBean);            return insertUri;        }        return null;    }    @Override    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {        //匹配uri        switch (uriMatcher.match(uri)) {            case MATCH_ALL_CODE://集合                int i = testBeanList.size();                testBeanList.clear();                return i;            case MATCH_ONE_CODE://单个                int indexId = Integer.parseInt(selection);                testBeanList.remove(indexId);                return 1;            default://抛出异常,没有匹配到uri                //throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());                return 0;        }    }    @Override    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {        return 0;    }}

清单文件注册,这里是用精准配置

<!--内容提供者,精准匹配-->        <provider            android:name=".content_provider.TestContentProvider"            android:authorities="com.lh.knowledge.contentprovider"            android:exported="true" />

在client中使用

public class ContentProviderActivity extends Activity {    private ContentResolver contentResolver;    private final Uri STUDENT_ALL_URI = Uri.parse("content://" + TestContentProvider.AUTHORITY + "/student");    private final Uri STUDENT_ONE_URI = Uri.parse("content://" + TestContentProvider.AUTHORITY + "/student/#");    private Handler handler = new Handler() {        public void handleMessage(Message msg) {            //这里说明内容提供者的uri正确,随机操作增删改查            /**             * @param uri             * @param projection             * @param selection             * @param selectionArgs             * @param sortOrder             * @return cursor             */            Cursor cursorAll = contentResolver.query(STUDENT_ALL_URI, null, null, null, null);            //查询userid为1的用户            Cursor cursorOne = contentResolver.query(STUDENT_ONE_URI, null, "1", null, null);            //删除userid为2的用户,返回当前删除条数            int i = contentResolver.delete(STUDENT_ONE_URI, "2", null);            //这里的方法都与TestContentProvider中的方法相对应        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //获得内容提供者解析器        contentResolver = getContentResolver();        //注册内容观察者        contentResolver.registerContentObserver(STUDENT_ALL_URI, true, new PersonOberserver(handler));    }    /**     * 观察者,如果找到了当前uri的提供者,则会回调     */    public class PersonOberserver extends ContentObserver {        private Handler handler;        public PersonOberserver(Handler handler) {            super(handler);            this.handler = handler;        }        @Override        public void onChange(boolean selfChange) {            super.onChange(selfChange);            //向handler发送消息,找到了当前的提供者            Message msg = new Message();            handler.sendMessage(msg);        }    }}
原创粉丝点击