Search code examples
androidandroid-sqliteandroid-contentproviderandroid-database

Deleting from a ContentProvider?


I want to delete the first item in my content provider. I'm trying to do this by deleting the row with id 0 (as shown below). This does not work--the app will not run with this code.

public void onClickDeleteExercise(View view){
    int ret_val = getContentResolver().delete(MyProvider.CONTENT_URI, MyProvider.id+ " = ? ", new String[]{"0"});
    Toast.makeText(getBaseContext(), "First exercise deleted", Toast.LENGTH_LONG).show();
}

My provider has defined these:

static final String PROVIDER_NAME = "com.example.contentproviderexample.MyProvider";
static final String URL = "content://" + PROVIDER_NAME + "/cte";
static final Uri CONTENT_URI = Uri.parse(URL);

static final String id = "id";
static final String name = "name";
static final int uriCode = 1;

How would I go about deleting from this? Thank you!!


Solution

  • app:

    getContentResolver().delete(Provider.CONTENT_URI,Provider._ID + "=" + id, null);
    

    provider:

    public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/")
    
    public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_URI,
            ENTRIES_TABLE_NAME);
    
    public static final String _ID = "_id";
    
    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        database.delete(ENTRIES_TABLE_NAME, where, whereArgs);
        return 0;
    }
    

    hint:

    • to exclude errors if u use android studio make breakpoint on

      public int delete(..) {
          database.delete() <=  here breakpoint
       }
      

    and see if after execute in app getContentResolver() the debugger will move you to this breakpoint

    • if it fails u have not registered content provider properly
    • if u will hit breakpoint implementation of database.delete is incorect

    If I want to delete the first item, would I just set id to 0?

    depends if your _id is PRIMARY_KEY in table

    • SQlite database Engine has a mechanism that creates a unique ROWID for every new row you insert.
    • if you table have a PRIMARY_KEY then it will eventually becomes the alias for that ROW_ID

      class SQLiteDatabase 
      
      /**
       * Convenience method for deleting rows in the database.
       *
       * @param table the table to delete from
       * @param whereClause the optional WHERE clause to apply when deleting.
       *            Passing null will delete all rows.
       * @param whereArgs You may include ?s in the where clause, which
       *            will be replaced by the values from whereArgs. The values
       *            will be bound as Strings.
       * @return the number of rows affected if a whereClause is passed in, 0
       *         otherwise. To remove all rows and get a count pass "1" as the
       *         whereClause.
       */
       public int delete(String table, String whereClause, String[] whereArgs) {}
      

    so to pas id as int u need:

    database.delete(TABLE_NAME, KEY_ID + " = ?",new String[]{Long.toString(id)});
    

    or simple:

    String[] whereArgs = new String[] {String.valueOf(rowId)};
    

    Caution: Rowids will change when the db is vacuumed

    So please take extra care when you define a table and need to reference records using rowids.

    From the official documentation:

    “Rowids can change at any time and without notice. If you need to depend on your rowid, make it an INTEGER PRIMARY KEY, then it is guaranteed not to change”.

    • add also AUTOINCREMENT so you are sure that the same rowid(s) are not reused when rows are deleted.

    In one of my tables sqlite3 table

    I got key message_id and it is beginning from value = 1

    • If u not sure about Key Value use on Android device SQLIte Debugger very excellent app