【问题标题】:Calling delete method in custom content provider在自定义内容提供程序中调用删除方法
【发布时间】:2011-03-10 23:46:29
【问题描述】:

我正在学习 Android,但遇到了一个涉及调用自定义内容提供程序的问题。我一直在使用指导书中的示例,虽然它描述了如何创建自定义提供程序,但没有明确的示例如何调用其中的特定方法。我正在专门研究如何从自定义内容提供程序中删除一条记录。

这是自定义内容提供程序 (EarthquakeProvider.java) 的代码:

@Override


public int delete(Uri uri, String where, String[] whereArgs) {
int count;

switch (uriMatcher.match(uri)) {
  case QUAKES:
    count = earthquakeDB.delete(EARTHQUAKE_TABLE, where, whereArgs);
    break;

  case QUAKE_ID:
    String segment = uri.getPathSegments().get(1);
    count = earthquakeDB.delete(EARTHQUAKE_TABLE, KEY_ID + "="
                                + segment
                                + (!TextUtils.isEmpty(where) ? " AND (" 
                                + where + ')' : ""), whereArgs);
    break;

  default: throw new IllegalArgumentException("Unsupported URI: " + uri);
}

getContext().getContentResolver().notifyChange(uri, null);
return count;


 }

我试图从主活动中调用删除方法来删除单个条目,而不是整个数据库。我想为在主活动的数组列表视图中显示的选定记录使用大约 OnLongClickListener

这是我迄今为止在我的主要活动中针对此方法提出的建议:

earthquakeListView.setOnItemLongClickListener(new OnItemLongClickListener() {

    @Override
    public boolean onItemLongClick(AdapterView _av, View _v, int _index,
            long arg3) {
        ContentResolver cr = getContentResolver();
        cr.delete(earthquakeProvider.CONTENT_URI, null, null); 

        return false;
    }

我知道上面的代码不起作用,但这是我目前理解的最接近的。

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: android android-contentprovider android-contentresolver onlongclicklistener


    【解决方案1】:
    cr.delete(earthquakeProvider.CONTENT_URI, null, null);
    

    这是你的问题。首先,一些背景:

    内容 URI:(source)

    content://authority/path/##
    

    最后的数字是可选的。如果存在,URI 引用数据库中的特定行,其中 row._id=(数字)。如果不存在,它将引用整个表。

    delete() 调用接受一个 URI、一个 where 子句和一组被替换的字符串。示​​例:假设您有一个人员数据库。

    cr.delete(
       Person.CONTENT_URI, 
       "sex=? AND eyecolor=?", 
       new String[]{"male", "blue"});
    

    将搜索整个 person 表,并删除性别为男性且眼睛颜色为蓝色的任何人。

    如果 where 子句和 where 值为 null,则 delete() 调用将匹配 表中的每一行。这会导致您看到的行为。

    有两种方法可以指定你想要的行:

    第一个选项,您可以将数字附加到 URI:

    cr.delete(
        EarthquakeProvider.CONTENT_URI.buildUpon().appendPath(String.valueOf(_id)).build(),
        null, null);
    

    这会将 URI 限制为特定行,并且路径将通过您的 case QUAKE_ID: 语句,因此无论如何只会删除一行。

    第二个选项,你可以使用 where 子句:

    cr.delete(EarthquakeProvider.CONTENT_URI, "_id=?", String.valueOf(_id)));
    

    无论哪种方式,您都可以根据需要将删除限制为单行。后者使代码更漂亮,但前者更高效,因为 ContentProvider 和 ContentObservers 的工作方式。

    最后一点:在您的 ContentProvider 中,您需要添加一个调用 ContentResolver.notifyChange(Uri uri, ContentObserver 观察者, boolean syncToNetwork)。这有助于通知游标重新获取数据库查询,并有助于自动化。

    【讨论】:

    • 另外,在您的 ContentProvider 代码中,uri.getPathSegments().get(1) 是错误的。由于行 id 在 URI 中始终是最后一个,因此您需要: uri.getLastPathSegment() -- uri.getPathSegments().get(1) 将为您提供第一个斜杠之后的路径。想想它在 content://com.example.transportationprovider/land/bus/3 的情况下做了什么
    • 谢谢,我使用第一个建议的代码进行了更改。我在模拟器中运行它时遇到致命错误:java.lang.IllegalArgumentException: Unsupported URI: content://com.paad.provider.earthquake/earthquakes/1。这应该是正确的 URI,但它不起作用...?
    • 这是来自 LOGCAT: ERROR/AndroidRuntime(370): FATAL EXCEPTION: main ERROR/AndroidRuntime(370): java.lang.IllegalArgumentException: Unsupported URI: content://com.paad.provider .earthquake/earthquakes/1 错误/AndroidRuntime(370):在 com.paad.earthquake.EarthquakeProvider.delete(EarthquakeProvider.java:103)。第 103 行是地震提供者中的“默认:抛出新的非法...”行。我可以复制整个错误日志,但它不适合评论部分。
    • 对。因此,URI 匹配器不起作用。您需要它来匹配带有数字的uri。您需要类似:uriMatcher.addURI(AUTHORITY, EarthquakeProvider.CONTENT_URI.toString+"/#", QUAKE_ID); - 它没有在你的 uriMatcher 正在寻找的东西列表中找到你的 uri,所以你的第二个 case 块永远不会被调用。这是与您最初的问题不同的问题。
    • 好的,现在可以了。非常感谢你的帮助。我发现出了什么问题:我正在调用“com.paad.provider.earthquake”,并且在 URI 匹配器中它被列为“com.paad.provider.Earthquake”。啊,区分大小写!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多