Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在内容提供程序内处理SQLiteConstraintException_Java_Android_Try Catch_Android Sqlite - Fatal编程技术网

Java 如何在内容提供程序内处理SQLiteConstraintException

Java 如何在内容提供程序内处理SQLiteConstraintException,java,android,try-catch,android-sqlite,Java,Android,Try Catch,Android Sqlite,我使用一个内容提供者从一个允许用户组织处方的数据库读/写。目前,我正在实现一个DialogFragment,允许用户输入新药物。该对话框包含两个编辑文本,一个用于强度,一个用于药物名称 表的设计使名称、强度成为唯一的键。以下是我的插入方法: public Uri insert(Uri uri, ContentValues values) { final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); final int

我使用一个内容提供者从一个允许用户组织处方的数据库读/写。目前,我正在实现一个DialogFragment,允许用户输入新药物。该对话框包含两个编辑文本,一个用于强度,一个用于药物名称

表的设计使名称、强度成为唯一的键。以下是我的插入方法:

public Uri insert(Uri uri, ContentValues values) {
    final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    final int match = sUriMatcher.match(uri);
    long _id; // Value used for inserts.
    Uri returnUri;

    switch(match){
        case MEDICATION:
            _id = db.insert(PMContract.MedicationEntry.TABLE_NAME, null, values);
            if(_id > 0)
                returnUri = PMContract.MedicationEntry.buildMedicationUri(_id);
            else
                throw new UnsupportedOperationException("Failed to insert row into: " + uri);
            break;
        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
    }
正如您所猜测的,如果用户输入一个已经存在的名称和强度,则会发生SQLiteConstraintException。然而,我在这里所做的只是抛出一个不支持的操作异常,这是我从一个关于内容提供者的教程中学到的

我想做的是,专门处理输入重复密钥的情况,这样我就可以通过Toast将该信息传递给用户

我已尝试在我进行插入呼叫的位置添加try/catch:

try{
    getActivity().getContentResolver().insert(PMContract.MedicationEntry.CONTENT_URI, values);
} catch(SQLiteConstraintException e){
}
case MEDICATION:
    try {
        _id = db.insert(PMContract.MedicationEntry.TABLE_NAME, null, values);
    } catch(SQLiteConstraintException e){
        String s = e.getMessage();
    } catch(Exception e1){
        String s1 = e1.getMessage();
    }

    if(_id > 0)
        returnUri = PMContract.MedicationEntry.buildMedicationUri(_id);
    else
        throw new UnsupportedOperationException("Failed to insert row into: " + uri);
    break;
但是SQLiteConstraintException不是被捕获的异常,而是一个不受支持的操作异常

如何调整ContentProvider代码,以便知道何时存在ConstraintException,并将其他所有内容视为不支持的OperationException

编辑

我已尝试在db.insert调用周围包装一个try/catch块:

try{
    getActivity().getContentResolver().insert(PMContract.MedicationEntry.CONTENT_URI, values);
} catch(SQLiteConstraintException e){
}
case MEDICATION:
    try {
        _id = db.insert(PMContract.MedicationEntry.TABLE_NAME, null, values);
    } catch(SQLiteConstraintException e){
        String s = e.getMessage();
    } catch(Exception e1){
        String s1 = e1.getMessage();
    }

    if(_id > 0)
        returnUri = PMContract.MedicationEntry.buildMedicationUri(_id);
    else
        throw new UnsupportedOperationException("Failed to insert row into: " + uri);
    break;

我使用调试器查看db.insert引发的异常。然而,调试器在两个catch块中都没有命中断点,即使错误文本打印在logcat中。我不确定为什么会将异常打印到logcat,但调试器没有命中这些断点。

不抛出异常,而是将null作为Uri返回-然后您可以检查插入调用的结果-如果您得到null返回值,您知道这是一个约束问题。

尝试Ian的建议并编辑我的问题后,我意识到我也有同样的问题

将代码行更改为db.insertOrThrow会导致发生ConstraintException时抛出,我能够在DialogFragment中捕捉到它:

// In the ContentProvider
_id = db.insertOrThrow(PMContract.MedicationEntry.TABLE_NAME, null, values);

// In the Dialog Fragment
try{
    getActivity().getContentResolver().insert(PMContract.MedicationEntry.CONTENT_URI, values);
    dismiss();
} catch(SQLiteConstraintException e){
    Toast.makeText(getActivity(), "A medication with this name and strength already exists.", Toast.LENGTH_SHORT).show();
} catch(UnsupportedOperationException uoe){
    Toast.makeText(getActivity(), "Unable to insert new medication.", Toast.LENGTH_SHORT).show();
}

我考虑过类似的事情,但是如果我有一个空Uri,它仍然可能是任何SQLiteException,不是吗?不,在insert方法中只捕获SQLiteConstraintException,并且只在这些情况下返回null。嗯,我似乎无法捕获异常。我在问题中添加了一个小代码片段来演示我的尝试。