Search code examples
androidandroid-sqliteandroid-contentprovidersqliteopenhelper

How to delete a row in SQLiteDatabase - Android Content Provider


I’m struggling to write a method that deletes a row from the SQLiteDatabase. I have a list of songs in a gridview where when a user clicks one of the items from the list the app will take them to my SongDetailFragment activity which contains more information about the song and a star button where if a song in in the database the star button is “switched on”, conversely if the item is NOT in the database the star button is “switched-off”

When a user click the star button I'm able to add a song successfully in the database and my star button is “switched-on”. Now I want to press the same button again and call deleteFromDB() to delete the song that was added to the database. So I have the following code in my onClick:

 public void onClick(View v)
            {

                if  (mIsFavourite) {

                   deleteFromDB();

                }

                else {
                    insertData();
                    mIsFavourite = true;
                }

The problem is deleteFromDB() method is not working correctly as I can see that the song is not deleting from the database. I’m not sure what is the correct syntax to fix it.

Here is my method:

   private void deleteFromDB() {

        ContentValues songValues = new ContentValues();


        getActivity().getContentResolver().delete(SongContract.SongEntry.CONTENT_URI,
                SongContract.SongEntry.COLUMN_TITLE + " = ?",
                new String[]{songValues.getAsString(song.getTitle())});

      //switch off button
        imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_off);
    }

Here is my delete method snippet from my ContentProvider class:

  @Override
    public int delete(Uri uri, String selection, String[] selectionArgs){
        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final int match = sUriMatcher.match(uri);
        int numDeleted;
        switch(match){
            case SONG:
                numDeleted = db.delete(
                        SongContract.SongEntry.TABLE_NAME, selection, selectionArgs);
                // reset _ID
                db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" +
                        SongContract.SongEntry.TABLE_NAME + "'");
                break;
            case SONG_WITH_ID:
                numDeleted = db.delete(SongContract.SongEntry.TABLE_NAME,
                        SongContract.SongEntry._ID + " = ?",
                        new String[]{String.valueOf(ContentUris.parseId(uri))});
                // reset _ID
                db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" +
                        SongContract.SongEntry.TABLE_NAME + "'");

                break;
            default:
                throw new UnsupportedOperationException("Unknown uri: " + uri);
        }

        return numDeleted;
    }

Here is my SongDetailFragment:

public  class SongDetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>{
    private  Song song;
    private static final int CURSOR_LOADER_ID = 0;
    ImageButton imgViewFavButton;
    Boolean mIsFavourite = false;

   // private final Context mContext;

    public SongDetailFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.song_fragment_detail, container, false);


        Intent intent = getActivity().getIntent();
        if (intent != null && intent.hasExtra("song")) {


            song = intent.getParcelableExtra("song");
            //display title
            ((TextView) rootView.findViewById(R.id.detail_title_textview))
                    .setText(song.getTitle());

            ((TextView)rootView.findViewById(R.id.detail_description_textview))
                    .setText(song.getDescription());


            ((TextView)rootView.findViewById(R.id.song_releasedate_textview))
                    .setText(song.getReleaseDate());

            double dRating = song.getVoteAverage();
            String sRating = String.valueOf(dRating);

            ((TextView)rootView.findViewById(R.id.song_rating_textview))
                    .setText(sRating + "/10 ");

            //show song poster


            ImageView imageView = (ImageView) rootView.findViewById(R.id.song_detail_poster_imageview);
            Picasso.with(getActivity()).load(song.getPoster()).into(imageView);
        }

        imgViewFavButton = (ImageButton) rootView.findViewById(R.id.imgFavBtn);

        checkFavourites();

        imgViewFavButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {

                if  (mIsFavourite) {

                   deleteFromDB();

                }

                else {
                    insertData();
                    mIsFavourite = true;
                }


            }
        });

        return rootView;
    }

    // insert data into database

    public void insertData(){
        ContentValues songValues = new ContentValues();
        songValues.put(SongContract.SongEntry.COLUMN_ID, song.getsong_id());
        songValues.put(SongContract.SongEntry.COLUMN_IMAGE, song.getPoster());
        songValues.put(SongContract.SongEntry.COLUMN_TITLE, song.getTitle());
        songValues.put(SongContract.SongEntry.COLUMN_OVERVIEW, song.getDescription());
        songValues.put(SongContract.SongEntry.COLUMN_RELEASEDATE, song.getReleaseDate());
        songValues.put(SongContract.SongEntry.COLUMN_RATING, song.getVoteAverage().toString());

           //Insert our ContentValues
        getActivity().getContentResolver().insert(SongContract.SongEntry.CONTENT_URI,
                songValues);

         imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_on);

    }

    private void deleteFromDB() {

        ContentValues songValues = new ContentValues();


        getActivity().getContentResolver().delete(SongContract.SongEntry.CONTENT_URI,
                SongContract.SongEntry.COLUMN_TITLE + " = ?",
                new String[]{songValues.getAsString(song.getTitle())});


        imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_off);
    }



    private void checkFavourites() {
        Cursor c =
                getActivity().getContentResolver().query(SongContract.SongEntry.CONTENT_URI,
                        null,
                        SongContract.SongEntry.COLUMN_ID + " = ?",
                        new String[]{song.getsong_id()},
                        null);

        if (c != null) {
            c.moveToFirst();
            int index = c.getColumnIndex(SongContract.SongEntry.COLUMN_ID);

            if (c.getCount() > 0 && c.getString(index).equals(song.getsong_id())) {
                mIsFavourite = true;
                imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_on);
            }

            else{
                imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_off);
            }

            c.close();

        }



    }


    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args){
        return new CursorLoader(getActivity(),
                SongContract.songEntry.CONTENT_URI,
                null,
                null,
                null,
                null);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState){
        super.onViewCreated(view, savedInstanceState);
    }


    // Set the cursor in our CursorAdapter once the Cursor is loaded
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {




    }

    // reset CursorAdapter on Loader Reset
    @Override
    public void onLoaderReset(Loader<Cursor> loader){

    }

}

Solution

  • Notice this line right here:

     ContentValues songValues = new ContentValues();
     getActivity().getContentResolver().delete(SongContract.songEntry.CONTENT_URI,
                SongContract.songEntry.COLUMN_TITLE + " = ?",
                new String[]{songValues.getAsString(song.getTitle())});
    

    You set songValues to an empty ContentValues object, and later call getAsString() which will return null since it doesn't contain any key for song.getTitle().

    Just change your array to have the song title, you don't need ContentValues here:

    new String[]{song.getTitle()});