如何删除 SQLiteDatabase 中的一行 - Android Content Provider
How to delete a row in SQLiteDatabase - Android Content Provider
我正在努力编写一个从 SQLiteDatabase 中删除一行的方法。我在 gridview 中有一个歌曲列表,当用户单击列表中的一个项目时,应用程序会将它们带到我的 SongDetailFragment activity,其中包含有关歌曲的更多信息和一个星形按钮,如果歌曲在在数据库中,星号按钮“打开”,相反,如果该项目不在数据库中,星号按钮“关闭”
当用户单击星号按钮时,我可以在数据库中成功添加一首歌曲,并且我的星号按钮已“打开”。现在我想再次按下同一个按钮并调用 deleteFromDB() 来删除添加到数据库中的歌曲。所以我的 onClick 中有以下代码:
public void onClick(View v)
{
if (mIsFavourite) {
deleteFromDB();
}
else {
insertData();
mIsFavourite = true;
}
问题是 deleteFromDB() 方法无法正常工作,因为我可以看到歌曲没有从数据库中删除。我不确定修复它的正确语法是什么。
这是我的方法:
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);
}
这是我的 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;
}
这是我的 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){
}
}
注意这里的这一行:
ContentValues songValues = new ContentValues();
getActivity().getContentResolver().delete(SongContract.songEntry.CONTENT_URI,
SongContract.songEntry.COLUMN_TITLE + " = ?",
new String[]{songValues.getAsString(song.getTitle())});
您将 songValues 设置为空的 ContentValues object,然后调用 getAsString()
,这将 return 为空,因为它不包含 song.getTitle()
的任何键。
只需更改您的数组以包含歌曲标题,此处不需要 ContentValues:
new String[]{song.getTitle()});
我正在努力编写一个从 SQLiteDatabase 中删除一行的方法。我在 gridview 中有一个歌曲列表,当用户单击列表中的一个项目时,应用程序会将它们带到我的 SongDetailFragment activity,其中包含有关歌曲的更多信息和一个星形按钮,如果歌曲在在数据库中,星号按钮“打开”,相反,如果该项目不在数据库中,星号按钮“关闭”
当用户单击星号按钮时,我可以在数据库中成功添加一首歌曲,并且我的星号按钮已“打开”。现在我想再次按下同一个按钮并调用 deleteFromDB() 来删除添加到数据库中的歌曲。所以我的 onClick 中有以下代码:
public void onClick(View v)
{
if (mIsFavourite) {
deleteFromDB();
}
else {
insertData();
mIsFavourite = true;
}
问题是 deleteFromDB() 方法无法正常工作,因为我可以看到歌曲没有从数据库中删除。我不确定修复它的正确语法是什么。
这是我的方法:
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);
}
这是我的 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;
}
这是我的 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){
}
}
注意这里的这一行:
ContentValues songValues = new ContentValues();
getActivity().getContentResolver().delete(SongContract.songEntry.CONTENT_URI,
SongContract.songEntry.COLUMN_TITLE + " = ?",
new String[]{songValues.getAsString(song.getTitle())});
您将 songValues 设置为空的 ContentValues object,然后调用 getAsString()
,这将 return 为空,因为它不包含 song.getTitle()
的任何键。
只需更改您的数组以包含歌曲标题,此处不需要 ContentValues:
new String[]{song.getTitle()});