在自定义内容提供程序中调用删除方法

12

我正在学习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;


 }

我正在尝试从主Activity调用delete方法来删除单个条目,而不是整个数据库。我想为在主Activity中的数组列表视图中显示的选定记录使用一个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;
    }

我知道上面的代码不起作用,但这是我现在理解的最接近的方式。

非常感谢任何对此的帮助。

1个回答

26
cr.delete(earthquakeProvider.CONTENT_URI, null, null);

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

内容URI:(来源)

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 observer, boolean syncToNetwork)的语句。这有助于通知游标重新获取数据库查询,并且在自动化方面非常有帮助。

另外,在您的ContentProvider代码中,uri.getPathSegments().get(1)是错误的。由于行ID始终位于URI的最后,因此您需要使用:uri.getLastPathSegment() -- uri.getPathSegments().get(1)将在第一个斜杠后获取路径。想想在content://com.example.transportationprovider/land/bus/3情况下它的作用是什么。 - jcwenger
谢谢,我使用第一个建议的代码进行了更改。但是当我在模拟器中运行它时,出现了致命错误:java.lang.IllegalArgumentException: Unsupported URI: content://com.paad.provider.earthquake/earthquakes/1。这应该是正确的URI,但它不起作用...? - Jeff
这是来自LOGCAT的信息:ERROR/AndroidRuntime(370): FATAL EXCEPTION: main ERROR/AndroidRuntime(370): java.lang.IllegalArgumentException: 不支持的URI:content://com.paad.provider.earthquake/earthquakes/1 ERROR/AndroidRuntime(370): at com.paad.earthquake.EarthquakeProvider.delete(EarthquakeProvider.java:103)。第103行是EarthquakeProvider中的“default: throw new Illegal...”行。我可以复制整个错误日志,但它无法适应评论部分。 - Jeff
@eRaisedToX,请查看https://dev59.com/SnE85IYBdhLWcg3wx2n2并自己做一些功课。 - jcwenger
@jcwenger :D 做了功课,找到了答案 :), 无论如何还是谢谢。 - eRaisedToX
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接