android.content.UriMatcher

本文详细介绍Android中URI匹配器(UriMatcher)的使用方法,通过构建URI树形结构,简化复杂URI匹配逻辑,提高ContentProvider中对不同URI类型的处理效率。

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

Utility class to aid in matching URIs in content providers.

To use this class, build up a tree of UriMatcher objects. For example:

    private static final int PEOPLE = 1;
    private static final int PEOPLE_ID = 2;
    private static final int PEOPLE_PHONES = 3;
    private static final int PEOPLE_PHONES_ID = 4;
    private static final int PEOPLE_CONTACTMETHODS = 7;
    private static final int PEOPLE_CONTACTMETHODS_ID = 8;

    private static final int DELETED_PEOPLE = 20;

    private static final int PHONES = 9;
    private static final int PHONES_ID = 10;
    private static final int PHONES_FILTER = 14;

    private static final int CONTACTMETHODS = 18;
    private static final int CONTACTMETHODS_ID = 19;

    private static final int CALLS = 11;
    private static final int CALLS_ID = 12;
    private static final int CALLS_FILTER = 15;

    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static
    {
        sURIMatcher.addURI("contacts", "people", PEOPLE);
        sURIMatcher.addURI("contacts", "people/#", PEOPLE_ID);
        sURIMatcher.addURI("contacts", "people/#/phones", PEOPLE_PHONES);
        sURIMatcher.addURI("contacts", "people/#/phones/#", PEOPLE_PHONES_ID);
        sURIMatcher.addURI("contacts", "people/#/contact_methods", PEOPLE_CONTACTMETHODS);
        sURIMatcher.addURI("contacts", "people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID);
        sURIMatcher.addURI("contacts", "deleted_people", DELETED_PEOPLE);
        sURIMatcher.addURI("contacts", "phones", PHONES);
        sURIMatcher.addURI("contacts", "phones/filter/*", PHONES_FILTER);
        sURIMatcher.addURI("contacts", "phones/#", PHONES_ID);
        sURIMatcher.addURI("contacts", "contact_methods", CONTACTMETHODS);
        sURIMatcher.addURI("contacts", "contact_methods/#", CONTACTMETHODS_ID);
        sURIMatcher.addURI("call_log", "calls", CALLS);
        sURIMatcher.addURI("call_log", "calls/filter/*", CALLS_FILTER);
        sURIMatcher.addURI("call_log", "calls/#", CALLS_ID);
    }

Then when you need to match against a URI, call match(Uri), providing the URL that you have been given. You can use the result to build a query, return a type, insert or delete a row, or whatever you need, without duplicating all of the if-else logic that you would otherwise need. For example:

    public String getType(Uri url)
    {
        int match = sURIMatcher.match(url);
        switch (match)
        {
            case PEOPLE:
                return "vnd.android.cursor.dir/person";
            case PEOPLE_ID:
                return "vnd.android.cursor.item/person";
... snip ...
                return "vnd.android.cursor.dir/snail-mail";
            case PEOPLE_ADDRESS_ID:
                return "vnd.android.cursor.item/snail-mail";
            default:
                return null;
        }
    }

instead of:

    public String getType(Uri url)
    {
        List pathSegments = url.getPathSegments();
        if (pathSegments.size() >= 2) {
            if ("people".equals(pathSegments.get(1))) {
                if (pathSegments.size() == 2) {
                    return "vnd.android.cursor.dir/person";
                } else if (pathSegments.size() == 3) {
                    return "vnd.android.cursor.item/person";
... snip ...
                    return "vnd.android.cursor.dir/snail-mail";
                } else if (pathSegments.size() == 3) {
                    return "vnd.android.cursor.item/snail-mail";
                }
            }
        }
        return null;
    }

 

package com.example.datarestore; 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 DatabaseProvider extends ContentProvider { public static final int BOOK_ANY = 0; public static final int BOOK_ITEM = 1; private MyDatabaseHelper myDatabaseHelper; private static UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI("com.example.datarestore.provider","Book",BOOK_ANY); uriMatcher.addURI("com.example.datarestore.provider","Book/#",BOOK_ITEM); } public DatabaseProvider() { } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = myDatabaseHelper.getWritableDatabase(); int deleteRow = 0; if(uriMatcher.match(uri) == BOOK_ANY){ deleteRow = db.delete("Book",selection,selectionArgs); } else if (uriMatcher.match(uri) == BOOK_ITEM) { String Id = uri.getPathSegments().get(1); deleteRow = db.delete("Book","id = ?",new String[]{Id}); } return deleteRow; } @Override public String getType(Uri uri) { SQLiteDatabase db = myDatabaseHelper.getWritableDatabase(); String type = ""; if(uriMatcher.match(uri) == BOOK_ANY){ type = "vnd.android.cursor.dir/vnd.com.example.datarestore.provider.Book"; } else if (uriMatcher.match(uri) == BOOK_ITEM) { String Id = uri.getPathSegments().get(1); type = "vnd.android.cursor.item/vnd.com.example.datarestore.provider.Book"; } return type; } @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = myDatabaseHelper.getWritableDatabase(); long newId = db.insert("Book",null,values); Uri returnuri = Uri.parse("content://com.example.datarestore.provider/Book/"+newId); return returnuri; } @Override public boolean onCreate() { myDatabaseHelper = new MyDatabaseHelper(getContext(),"Bookstore.db",null,1); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = myDatabaseHelper.getWritableDatabase(); Cursor cursor = null; if(uriMatcher.match(uri) == BOOK_ANY){ cursor = db.query("Book",projection,selection,selectionArgs,null,null,sortOrder); } else if (uriMatcher.match(uri) == BOOK_ITEM) { String Id = uri.getPathSegments().get(1); cursor = db.query("Book",projection,"id = ?",new String []{Id},null,null,sortOrder); } return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = myDatabaseHelper.getWritableDatabase(); int updateRow = 0; if(uriMatcher.match(uri) == BOOK_ANY){ updateRow = db.update("Book",values,selection,selectionArgs); } else if (uriMatcher.match(uri) == BOOK_ITEM) { String Id = uri.getPathSegments().get(1); updateRow = db.update("Book",values,"id = ?",new String[]{Id}); } return updateRow; } }代码有什么问题,为什么显示 Process: com.example.providertest, PID: 25182 java.lang.IllegalArgumentException: Unknown URL content://com.example.datarestore.provider/Book
07-26
代码如下:package com.example.myapplication; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.util.Log; public class DatabaseProvider extends ContentProvider { // 授权标识 public static final String AUTHORITY = "com.example.myapplication.provider"; public static final Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY+"/person"); public static final String COLUMN_ID = "id"; public static final String COLUMN_NAME = "name"; public static final String COLUMN_NUMBER = "number"; public static final String COLUMN_ISSTAR = "isstar"; private static int personDir=0;//列表 private static int personItem=1;//单条记录 // 初始化:创建UriMatcher对象,参数UriMatcher.NO_MATCH表示初始状态(无匹配)。 // 添加匹配规则:使用addURI方法,参数为授权(authority)、路径(path)和自定义代码(code)。 // 使用:通过match方法匹配传入的Uri,返回自定义代码,然后根据代码进行相应处理。 private static UriMatcher uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);//初始状态没匹配到任何URI private SQLiteDatabase dbHelper; static {//只在类被加载时执行一次 uriMatcher.addURI(AUTHORITY, "person", personDir); // 整个表,匹配返回匹配吗personDir uriMatcher.addURI(AUTHORITY, "person/#", personItem); // 单条记录,#匹配由任意长度的数字字符组成的字符串 } //uri 映射至程序公开的数据表person //projection 是检索到的每个行所应包含的列的数组。 //selection 指定选择行的条件。 //sortOrder 指定在返回的 Cursor 中各行的显示顺序。 public DatabaseProvider() { } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // Implement this to handle requests to delete one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } @Override public String getType(Uri uri) { // TODO: Implement this to handle requests for the MIME type of the data // at the given URI. throw new UnsupportedOperationException("Not yet implemented"); } @Override public Uri insert(Uri uri, ContentValues values) { // TODO: Implement this to handle requests to insert a new row. throw new UnsupportedOperationException("Not yet implemented"); } @Override public boolean onCreate() { // TODO: Implement this to initialize your content provider on startup. return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { switch (uriMatcher.match(uri)){ case 0: Log.i("test","query所有"); return dbHelper.query(false,"person",projection,selection,selectionArgs,null,null,sortOrder,null); case 1: long id= ContentUris.parseId(uri); Log.i("test","query单个"); return dbHelper.rawQuery("select * from person where id=?",new String[]{id+""}); } return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO: Implement this to handle requests to update one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } }
07-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值