2014-01-15 3 views
1

У меня есть список с некоторыми элементами, которые сохраняются в базе данных, и я обращаюсь к ним с помощью настраиваемого поставщика контента.Обновление базы данных с использованием Content Provider

В моем основном действии я реализовал ResourceCursorAdapter.

Когда я долгое время нажимаю на элемент списка, я получаю контекстное меню, в котором у меня есть параметры обновления.

Параметр edit запускает другое действие с помощью некоторых edittexts, где я должен иметь возможность обновлять значения выбранного элемента (я также использую эту активность для создания нового элемента, и я делаю это правильно).

Проблема, которую я получаю, заключается в том, что я не обновляю и не удаляю элементы, поэтому я думаю, что я не использую права ID для доступа к базе данных. Это мой код:

пользовательского контента поставщика - Обновление и удаление методов

@Override 
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 
    int count = 0; 
    database = mDbHelper.getWritableDatabase(); 
    int match = mUriMatcher.match(uri); 

    switch (match){ 
     case URI_TRAVELS: 
      //nada 
      break; 
     case URI_TRAVEL_ITEM: 
      String id = uri.getPathSegments().get(1); 
      count = database.update(TravelsDatabaseHelper.TABLE_NAME, values, Travels._ID + 
        " = " + id + (!TextUtils.isEmpty(selection) ? " AND (" + 
          selection + ')' : ""), selectionArgs); 
      break; 
     default: 
      throw new IllegalArgumentException("Unknown URI: " + uri); 
    } 
    getContext().getContentResolver().notifyChange(uri, null); 
    return count; 
} 

@Override 
public int delete(Uri uri, String selection, String[] selectionArgs) { 
    int count = 0; 
    database = mDbHelper.getWritableDatabase(); 
    int match = mUriMatcher.match(uri); 

    switch (match){ 
     case URI_TRAVELS: 
      //nada 
      break; 
     case URI_TRAVEL_ITEM: 
      String id = uri.getPathSegments().get(1); 
      count = database.delete(TravelsDatabaseHelper.TABLE_NAME, Travels._ID + " = " + id + 
        (!TextUtils.isEmpty(selection) ? " AND (" + 
          selection + ')' : ""), selectionArgs); 
      break; 
     default: 
      throw new IllegalArgumentException("Unknown URI: " + uri); 
    } 
    getContext().getContentResolver().notifyChange(uri, null); 
    return count; 
} 

Основная деятельность - Обновление и удаление методов

public void updateTravel(String city, String country, int year, String note, String id){ 
    ContentValues updateValues = new ContentValues(); 
    updateValues.put(Travels.CITY, city); 
    updateValues.put(Travels.COUNTRY, country); 
    updateValues.put(Travels.YEAR, year); 
    updateValues.put(Travels.NOTE, note); 

    getContentResolver().update(TravelsProvider.CONTENT_URI, updateValues, Travels._ID+"="+id, null); 
} 


private void deleteTravel(String id){ 
    /**Accede a la funcion delete() del Content Provider*/ 
    getContentResolver().delete(TravelsProvider.CONTENT_URI, Travels._ID+"="+id, null); 
} 

Основное направление деятельности - Контекстное меню, где я методы удаления и обновления вызовов

public boolean onContextItemSelected(MenuItem item) { 

    AdapterContextMenuInfo menu_info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); 
    int itemPos = menu_info.position; 
    Cursor cursor = mAdapter.getCursor(); 
    cursor.moveToPosition(itemPos); 

    switch (item.getItemId()) { 
     case R.id.edit_travel: 
      Intent intent = new Intent(this, EditTravelActivity.class); 
      intent.putExtra(TravelActivity.EXTRA_ID, cursor.getString(cursor.getColumnIndex(Travels._ID))); 
      startActivityForResult(intent, REQUEST_CODE_UPDATE_TRAVEL); 
      return true; 
     case R.id.delete_travel: 
      String ids = cursor.getString(cursor.getColumnIndex(Travels._ID)); 
      deleteTravel(ids); 
      return true; 
     default: 
      return super.onContextItemSelected(item); 
    } 
} 

protected void onActivityResult (int requestCode, int resultCode, Intent data) { 
    //... 
      case REQUEST_CODE_UPDATE_TRAVEL: 
       String ucity = data.getExtras().getString(TravelActivity.EXTRA_CITY); 
       String ucountry = data.getExtras().getString(TravelActivity.EXTRA_COUNTRY); 
       int uyear = data.getExtras().getInt(TravelActivity.EXTRA_YEAR); 
       String unote = data.getExtras().getString(TravelActivity.EXTRA_NOTE); 
       String uid = data.getExtras().getString(TravelActivity.EXTRA_ID); 

       updateTravel(ucity, ucountry, uyear, unote, uid); 
       break; 
     } 
    } 
} 

ОБНОВЛЕНИЕ - Согласно ответу NigelK в

Это мой «UriMatcher» и другие соответствующие определения Заботиться:

private static final String AUTHORITY = "com.example.travellist"; 
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/travels"); 

private static final int URI_TRAVELS = 1; 
private static final int URI_TRAVEL_ITEM = 2; 

private static final UriMatcher mUriMatcher; 
static { 
    mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    mUriMatcher.addURI(AUTHORITY, "travels", URI_TRAVELS); 
    mUriMatcher.addURI(AUTHORITY, "travels/#", URI_TRAVEL_ITEM); 
} 

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

Согласно вашему ответу, я судимый делать это на 2 пути:

private void deleteTravel(long id){ 
    /*METHOD 1*/ 
    getContentResolver().delete(TravelsProvider.CONTENT_URI, Travels._ID+"="+id, null); 
    /*METHOD 2*/ 
    Uri uri = ContentUris.withAppendedId(TravelsProvider.CONTENT_URI, id); 
    getContentResolver().delete(uri, null, null); 
} 

public int delete(Uri uri, String selection, String[] selectionArgs) { 

    //... 

    switch (match){ 
     case URI_TRAVELS: 
      //nada 
      break; 
     case URI_TRAVEL_ITEM: 
      /*METHOD 1*/ 
      count = database.delete(TravelsDatabaseHelper.TABLE_NAME, selection, selectionArgs); 
      break; 
      /*METHOD 2*/ 
      String rowId = uri.getPathSegments().get(1); 
      selection = Travels._ID +" = "+ rowId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); 
      count = database.delete(TravelsDatabaseHelper.TABLE_NAME, selection, selectionArgs); 
      break; 
     //... 
} 

В первом пути, она продолжает Whithout удаления элемента. Во втором случае, в строке Строка rowId = uri.getPathSegments(). Get (1); бросает мне эту ошибку: Недостижимый код!

ответ

2

Большинство поставщиков контента содержат ярлык URI, который позволяет вам обращаться к определенной строке, добавляя идентификатор строки в URI содержимого. Где вы делаете следующее, вы предоставляете выбор «WHERE _id = идентификатор», который вполне допустимо:

.delete(TravelsProvider.CONTENT_URI, Travels._ID+"="+id, null); 

Ури выше будет что-то вроде: содержание: //com.package.provider/content

короткий отрезок, который применяет действие только идентификатор добавляется к URI, имеет вид:

uri = ContentUris.withAppendedId(TravelsProvider.CONTENT_URI, id); 
.delete(uri, null, null); 

Ури выше теперь будет что-то вроде: содержание: //com.package.провайдер/контент/1234

Проблема у вас в том, что в ваших методах delete() и update() вы пытаетесь разобраться со второй формой, а не с первой (которая является формой URI, которую вы используете в вызов). Расширить uriMatcher сказать разницу, что-то вроде:

uriMatcher.addURI("your.package.provider", "content", URI_TRAVEL_ITEM); 
uriMatcher.addURI("your.package.provider", "content/#", URI_TRAVEL_ITEM_ID); 

В Delete(), а так же для обновления():

switch (match){ 
    case URI_TRAVELS: 
     //nada 
     break; 

    case URI_TRAVEL_ITEM: 
     count = database.delete(TravelsDatabaseHelper.TABLE_NAME, selection, selectionArgs); 
     break; 

    case URI_TRAVEL_ITEM_ID: 
     String rowID = uri.getPathSegments().get(1); 
     selection = Travels._ID + "=" + rowID 
    + (!TextUtils.isEmpty(selection) ? 
     " AND (" + selection + ')' : ""); 
     count = database.delete(TravelsDatabaseHelper.TABLE_NAME, selection, selectionArgs); 
     break; 

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

Так где нет идентификатора добавляется к URI (он соответствует URI_TRAVEL_ITEM), это простое удаление, основанное на выборе и аргументах. Если к URI добавлен идентификатор (он соответствует URI_TRAVEL_ITEM_ID), получите идентификатор из URI с помощью getPathSegments(). Get (1) и используйте это значение для увеличения выделенного пробега (так что это относится только к этой строке) перед удалением.

У вас есть оба типа URI, и остальная часть вашего кода должна (я надеюсь) работать.

+0

Я обновил сообщение в соответствии с вашим ответом. Все еще не работает, поэтому, возможно, я пропустил что-то. Пожалуйста, посмотрите – masmic

+0

Возможно, проблема в mainActivity, где я получаю идентификатор элемента, используя 'String ids = cursor.getString (cursor.getColumnIndex (Travels._ID));' Возможно, это не способ получить Идентификатор товара? – masmic

+0

Недопустимый код - это то, что вы пропустили «случай URI_TRAVEL_ITEM_ID:» - см. Мой ответ, где он идет. Все еще глядя на остальные ... – NigelK

Смежные вопросы