Попытка получить доступ к курсору после его закрытия

Я использую следующий код для удаления изображения. Это работает в первый раз, но когда я пытаюсь захватить изображение и удалить его, я получаю StaleDataException:

08-07 14:57:24.156: E/AndroidRuntime(789): java.lang.RuntimeException: Unable to               
       resume activity {com.example.cap_im/com.example.cap_im.MainActivity}:  
       android.database.StaleDataException: Attempted to access a cursor after it has been closed.

public void deleteImageFromGallery(String captureimageid) {
    Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

    getContentResolver().delete(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            BaseColumns._ID + "=?", new String[] { captureimageid });

    String[] projection = { MediaStore.Images.ImageColumns.SIZE,
            MediaStore.Images.ImageColumns.DISPLAY_NAME,
            MediaStore.Images.ImageColumns.DATA, BaseColumns._ID, };

    Log.i("InfoLog", "on activityresult Uri u " + u.toString());

    try {
        if (u != null) {
            cursor = managedQuery(u, projection, null, null, null);
        }
        if ((cursor != null) && (cursor.moveToLast())) {

            int i = getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    BaseColumns._ID + "=" + cursor.getString(3),   null);
            Log.v(TAG, "Number of column deleted : " + i);
        }
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

5 ответов

Функция, managedQuery() устарела.

Пожалуйста, используйте getContentResolver().query(),

Параметры одинаковые.

В вашем finally блок, вы закрываете курсор, но не устанавливаете его null, Таким образом, в следующий раз ваш метод вызывается, cursor.getString(3) не удается, так как курсор был закрыт.

Обходной путь: Установить cursor в null в вашем finally блок.

Правильное решение: не используйте переменную экземпляра для вашего cursorвместо этого используйте локальную переменную в вашем методе.

У меня была похожая проблема. В моем случае с кодом все в порядке, но я использовал устаревший метод managedQuery, а не тот, который предложил Том Лин

public String getPath(Uri uri) {
    if (uri == null) {
        return null;
    }
    String result = null;

    String[] projection = {MediaStore.Images.Media.DATA};
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);

    // deprecated:
    // Cursor cursor = managedQuery(uri, projection, null, null, null);

    if (cursor != null) {

        int columnIndex = 0;
        try {
            columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            result = cursor.getString(columnIndex);
        } catch (IllegalArgumentException e) {
            Log.e("While getting path for file", e);
        } finally {
            try {
                if (!cursor.isClosed()) {
                    cursor.close();
                }
                cursor = null;
            } catch (Exception e) {
                Log.e("While closing cursor", e);
            }
        }
    }
    return result;
}

Если я использую устаревший метод, он все равно работает, если я опускаю finally. В документе также четко указано, что при использовании этого метода нельзя закрывать курсор.

Определенно работайте с этим кодом, используйте getContentResolver(). Query() вместо managedQuery(). Потому что managedQuery() устарела. его работа для меня идеально. Спасибо

Также не используйте managedQuery() это устарело.

Удали это:

protected SQLiteDatabase database;

и сделать это местным

В основном 2 метода выполняются одновременно и один метод называется database.close() и 2-й метод все еще получает доступ к данным, поэтому Exception

использовать этот:

   public class db {

    DataBaseHelper dbHelper;
    Context mContext;


    public db(Context context) {
        this.mContext = context;
    }

    public db open() throws SQLException {
        dbHelper = new DataBaseHelper(mContext);
        return this;
    }


    public void close() {
        dbHelper.close();
    }

    public void insertdb( int id,String ph_num, String call_type, String calldate, String call_duration, String upload_status) {
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(DataBaseHelper.id,id);
        values.put(DataBaseHelper.phone_number, ph_num);
        values.put(DataBaseHelper.call_type, call_type);
        values.put(DataBaseHelper.call_date, calldate);
        values.put(DataBaseHelper.call_duration, call_duration);
        values.put(DataBaseHelper.upload_status, upload_status);
        database.insert(DataBaseHelper.table_name, null, values);
        database.close();
        // Log.d("Database helper", "values inserted");
    }


    public ArrayList<HashMap<String, String>> getAllUsers() {
        ArrayList<HashMap<String, String>> wordList;
        wordList = new ArrayList<HashMap<String, String>>();
        String selectQuery = "SELECT  * FROM call_logtable";
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        Cursor cursor = database.rawQuery(selectQuery, null);
        if (cursor.moveToFirst()) {
            do {
                HashMap<String, String> map = new HashMap<String, String>();
                map.put("id", cursor.getString(0));
                map.put("phone_number", cursor.getString(1));
                map.put("call_type", cursor.getString(2));
                map.put("call_date", cursor.getString(3));
                map.put("call_duration", cursor.getString(4));
                wordList.add(map);
            } while (cursor.moveToNext());
        }
        cursor.close(); // just added
        database.close();
        return wordList;
    }

    /**
     * Compose JSON out of SQLite records
     * @return
     */
    public String composeJSONfromSQLite(){
        ArrayList<HashMap<String, String>> wordList;
        wordList = new ArrayList<HashMap<String, String>>();
        String selectQuery = "SELECT  * FROM call_logtable where upload_status = '"+"no"+"'";
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        Cursor cursor = database.rawQuery(selectQuery, null);
        if (cursor.moveToFirst()) {
            do {
                HashMap<String, String> map = new HashMap<String, String>();
                map.put("id", cursor.getString(0));
                map.put("phone_number", cursor.getString(1));
                map.put("call_type", cursor.getString(2));
                map.put("call_date", cursor.getString(3));
                map.put("call_duration", cursor.getString(4));
                wordList.add(map);
            } while (cursor.moveToNext());
        }
        cursor.close(); // just added
        database.close();
        Gson gson = new GsonBuilder().create();
        //Use GSON to serialize Array List to JSON
        return gson.toJson(wordList);
    }


    public int dbSyncCount(){
        int count = 0;
        String selectQuery = "SELECT  * FROM call_logtable where upload_status = '"+"no"+"'";
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        Cursor cursor = database.rawQuery(selectQuery, null);
        count = cursor.getCount();
        cursor.close(); // just added
        database.close();
        return count;
    }


    public void updateSyncStatus(String id, String status){
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        String updateQuery = "Update call_logtable set upload_status = '"+ status +"' where id="+"'"+ id +"'";
        Log.d("query", updateQuery);
        database.execSQL(updateQuery);
        database.close();
    }

    public Cursor getinformation()
    {
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        String[] columns={DataBaseHelper.phone_number,DataBaseHelper.call_type,DataBaseHelper.call_date,DataBaseHelper.call_duration,DataBaseHelper.upload_status};
        return database.query(DataBaseHelper.table_name,columns,null,null,null,null,null);
    }

    public void delete()
    {
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        // String[] columns={DataBaseHelper.phone_number,DataBaseHelper.call_type,DataBaseHelper.call_date,DataBaseHelper.call_duration};
        database.delete(DataBaseHelper.table_name, null, null);
    }


    StringBuffer readSpecificfrom_db(String type)
    {
        String ph_number=null;
        String call_type=null;
        String call_date=null;
        String call_duration=null;
        String upload_status=null;
        StringBuffer sb = new StringBuffer();
        //sb.append("Call Log :");
        Cursor cursor_object=getinformation();
        cursor_object.moveToFirst();
        do {
            if((cursor_object.getString(1)).equals(type)) {
                ph_number = cursor_object.getString(0);
                call_type = cursor_object.getString(1);
                call_date = cursor_object.getString(2);
                call_duration = cursor_object.getString(3);
                if(type=="Missed") {
                    sb.append("\nPhone Number:--- " + ph_number +
                                    " \nCall Type:--- " + call_type +
                                    " \nCall Date:--- " + call_date
                            //   + " \nCall duration in sec :--- " + call_duration
                    );
                    sb.append("\n----------------------------------");
                }
                else
                {
                    sb.append("\nPhone Number:--- " + ph_number +
                            " \nCall Type:--- " + call_type +
                            " \nCall Date:--- " + call_date
                            + " \nCall duration in sec :--- " + call_duration);
                    sb.append("\n----------------------------------");
                }
            }
        }while(cursor_object.moveToNext());
        cursor_object.close(); // just added
        return sb;

    }

    StringBuffer readfrom_db()
    {
        String ph_number=null;
        String call_type=null;
        String call_date=null;
        String call_duration=null;
        String upload_status;
        //  int id=0;
        StringBuffer sb = new StringBuffer();
        // sb.append("Call Log :");
        Cursor cursor_object=getinformation();
        cursor_object.moveToFirst();
        do {
            ph_number=cursor_object.getString(0);
            call_type=cursor_object.getString(1);
            call_date=cursor_object.getString(2);
            call_duration=cursor_object.getString(3);
            sb.append("\nPhone Number:--- " + ph_number +
                    " \nCall Type:--- " + call_type +
                    " \nCall Date:--- " + call_date
                    + " \nCall duration in sec :--- " + call_duration);
            sb.append("\n----------------------------------");

        } while(cursor_object.moveToNext());
        cursor_object.close(); // just added
        return sb;
    }
}
Другие вопросы по тегам