从SQLite数据库中删除数据在Fragment中不起作用

时间:2017-05-02 19:01:07

标签: android sqlite android-sqlite android-contentresolver

我有一个Activity来处理我的电影数据片段的详细信息片段&我想实现收藏功能。但问题是我一次只能收藏一部电影。此外,每次我尝试添加/收藏电影时,它都会在数据库中显示它已被保存但从未在不受欢迎上删除。

这是我的代码:

MovieDetailsActivity

public class MovieDetailsActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    /* Set the content of the activity to use the activity_tv_show_details.xml layout file */
    setContentView(R.layout.activity_movie_details);
    Bundle movieDetails = new Bundle();

    /**get the movie's Object from the parent activity**/
    Movie movie = getIntent().getParcelableExtra("movie");
    movieDetails.putParcelable("movie", movie);
    Intent intent = getIntent();
    Uri mCurrentMovieUri = intent.getData();
    movieDetails.putString("currentMovieUri", mCurrentMovieUri.toString());

    /* Check for pre-existing instances of fragments(here explicitly check for savedInstance)
    and then begin fragment transaction accordingly */
    if (savedInstanceState == null) {
        MovieDetailsFragment defaultMovieFragment = new MovieDetailsFragment();
        defaultMovieFragment.setArguments(movieDetails);
        getSupportFragmentManager().beginTransaction()
                .add(R.id.containerMovieDetailActivity, defaultMovieFragment)
                .commit();
    }
   }
 }

MovieDetailsFragment

public class MovieDetailsFragment extends Fragment implements LoaderManager.LoaderCallbacks<MovieDetailsBundle> {

private static final int MOVIE_DETAIL_LOADER_ID = 2;

/* Arrays for holding movie details */


Movie movie;


public MovieDetailsFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_movie_detail, container, false);

    Bundle bundle = getArguments();
    position = bundle.getInt("position");
    currentMovieUri = Uri.parse(bundle.getString("currentMovieUri"));

    favoriteButton = (ImageButton) rootView.findViewById(R.id.favorite);

    if (savedInstanceState == null) {
        mReview = new ArrayList<>();
        mVideo = new ArrayList<>();
        mCredits = new ArrayList<>();
        mMovieDetailsBundle = new MovieDetailsBundle();
    }

    if ((bundle != null)) {
        movie = getArguments().getParcelable("movie");
        movieDetailTitleTextView.setText(movie.getMovieTitle());
        ...


        String[] projection = {
                MoviesEntry._ID,
                MoviesEntry.COLUMN_MOVIE_TITLE,
                MoviesEntry.COLUMN_MOVIE_RELEASE_DATE,
                MoviesEntry.COLUMN_MOVIE_OVERVIEW,
                MoviesEntry.COLUMN_MOVIE_POSTER_URL,
                MoviesEntry.COLUMN_MOVIE_BACKDROP_URL,
                MoviesEntry.COLUMN_MOVIE_RATING};

        // Perform a query on the provider using the ContentResolver.
        // Use the {@link MoviesEntry#CONTENT_URI} to access the pet data.
        Cursor cursor = getActivity().getContentResolver().query(
                MoviesEntry.CONTENT_URI,   // The content URI of the movies table
                projection,             // The columns to return for each row
                null,                   // Selection criteria
                null,                   // Selection criteria
                null);


        try {

            // Figure out the index of each column
            int idColumnIndex = cursor.getColumnIndex(MoviesEntry._ID);
            int titleColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_TITLE);

            int releaseDateColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_RELEASE_DATE);
            int overviewColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_OVERVIEW);
            int posterUrlColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_POSTER_URL);
            int backdropUrlColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_BACKDROP_URL);
            int ratingColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_RATING);

            // Iterate through all the returned rows in the cursor
          if (cursor.moveToFirst()){
                // Use that index to extract the String or Int value of the word
                // at the current row the cursor is on.
                currentID = cursor.getInt(idColumnIndex);
                currentTitle = cursor.getString(titleColumnIndex);
                currentReleaseDate = cursor.getString(releaseDateColumnIndex);
                currentOverview = cursor.getString(overviewColumnIndex);
                currentposterUrl = cursor.getString(posterUrlColumnIndex);
                currentBackdropUrl = cursor.getString(backdropUrlColumnIndex);
                currentRatings = cursor.getFloat(ratingColumnIndex);
            }
        } finally {
            // Always close the cursor when you're done reading from it. This releases all its
            // resources and makes it invalid.
            cursor.close();
        }

        if (currentTitle!=null) {
            //currentTitle = movie.getMovieTitle();
            if (currentTitle.equals(movie.getMovieTitle())) {
                favoriteButton.setImageResource(R.drawable.starred);
                favorite = true;
            }
        }else{
            favoriteButton.setImageResource(R.drawable.unstarred);
            favorite = false;
        }
        /*setting the ratingbar from @link: https://github.com/FlyingPumba/SimpleRatingBar*/
        SimpleRatingBar simpleRatingBar = (SimpleRatingBar) rootView.findViewById(R.id.movieRatingInsideMovieDetailsFragment);
        simpleRatingBar.setRating((float) (movie.getMovieVoteAverage()) / 2);
        favoriteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (favorite) {
                    // Only perform the delete if this is an existing movie.
                    if (currentMovieUri != null) {

                        // Call the ContentResolver to delete the movie at the given content URI.
                        // Pass in null for the selection and selection args because the mCurrentPetUri
                        // content URI already identifies the movie that we want.
                        int rowsDeleted = getActivity().getContentResolver().delete(currentMovieUri, null, null);

                        // Show a toast message depending on whether or not the delete was successful.
                        if (rowsDeleted == 0) {
                            // If no rows were deleted, then there was an error with the delete.
                            Toast.makeText(getContext(), getString(R.string.delete_movie_failed),
                                    Toast.LENGTH_SHORT).show();
                        } else {
                            // Otherwise, the delete was successful and we can display a toast.
                            Toast.makeText(getContext(), getString(R.string.delete_movie_successful),
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                    favoriteButton.setImageResource(R.drawable.unstarred);

                } else {
                    // Create a ContentValues object where column names are the keys,
                    // and movie attributes from the editor are the values.
                    ContentValues values = new ContentValues();
                    values.put(MoviesEntry.COLUMN_MOVIE_TITLE, movie.getMovieTitle());
                    values.put(MoviesEntry.COLUMN_MOVIE_RELEASE_DATE, movie.getMovieReleaseDate());
                    values.put(MoviesEntry.COLUMN_MOVIE_OVERVIEW, movie.getMovieOverview());
                    values.put(MoviesEntry.COLUMN_MOVIE_POSTER_URL, movie.getMoviePosterPath());
                    values.put(MoviesEntry.COLUMN_MOVIE_BACKDROP_URL, movie.getMovieBackdropPath());
                    values.put(MoviesEntry.COLUMN_MOVIE_RATING, movie.getMovieVoteAverage() / 2);

                    // Insert a new movie into the provider, returning the content URI for the new movie.
                    Uri newUri = getActivity().getContentResolver().insert(MoviesEntry.CONTENT_URI, values);

                    // Show a toast message depending on whether or not the insertion was successful
                    if (newUri == null) {
                        // If the new content URI is null, then there was an error with insertion.
                        Toast.makeText(getContext(), getString(R.string.insert_movie_failed),
                                Toast.LENGTH_SHORT).show();
                    } else {
                        // Otherwise, the insertion was successful and we can display a toast.
                        Toast.makeText(getContext(), getString(R.string.insert_movie_successful),
                                Toast.LENGTH_SHORT).show();
                    }
                    favoriteButton.setImageResource(R.drawable.starred);
                }

                favorite = !favorite;
            }
        });

        ...
@Override
public Loader<MovieDetailsBundle> onCreateLoader(int id, Bundle args) {
    Uri baseUri = Uri.parse((UrlsAndConstants.MovieDetailQuery.DEFAULT_URL) + movie.getMovieId());
    Uri.Builder uriBuilder = baseUri.buildUpon();
    uriBuilder.appendQueryParameter(API_KEY_PARAM, API_KEY_PARAM_VALUE);
    uriBuilder.appendQueryParameter(APPEND_TO_RESPONSE, VIDEOS_AND_REVIEWS_AND_CREDITS);
    return new DetailsMovieLoader(getActivity().getApplicationContext(), uriBuilder.toString());
}

@Override
public void onLoadFinished(Loader<MovieDetailsBundle> loader, )
  ...
}

public void updateDurationTextView(MovieDetailsBundle movieDetailsBundle) {

    ...
    movieRunTimeDuration.setText(mMovieDurationString);
}

@Override
public void onLoaderReset(Loader<MovieDetailsBundle> loader) {
  }
}

的ContentProvider

public class MovieProvider extends ContentProvider {
/**
 * URI matcher code for the content URI for the movies table
 */

private static final int MOVIES = 100;

/**
 * URI matcher code for the content URI for a single movie in the movie table
 */
private static final int MOVIE_ID = 200;

/**
 * UriMatcher object to match a content URI to a corresponding code.
 * The input passed into the constructor represents the code to return for the root URI.
 * It's common to use NO_MATCH as the input for this case.
 */
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

// Static initializer. This is run the first time anything is called from this class.
static {
    // The calls to addURI() go here, for all of the content URI patterns that the provider
    // should recognize. All paths added to the UriMatcher have a corresponding code to return
    // when a match is found.

    // The content URI of the form "content://com.example.android.movie/movie" will map to the
    // integer code {@link #MOVIES}. This URI is used to provide access to MULTIPLE rows
    // of the movie table.
    sUriMatcher.addURI(MovieContract.CONTENT_AUTHORITY, MovieContract.PATH_MOVIES, MOVIES);

    // The content URI of the form "content://com.example.android.movie/movie/#" will map to the
    // integer code {@link #MOVIES}. This URI is used to provide access to ONE single row
    // of the movie table.
    //
    // In this case, the "#" wildcard is used where "#" can be substituted for an integer.
    // For example, "content://com.example.android.movie/movie/3" matches, but
    // "content://com.example.android.movie/movie" (without a number at the end) doesn't match.
    sUriMatcher.addURI(MovieContract.CONTENT_AUTHORITY, MovieContract.PATH_MOVIES + "/#", MOVIE_ID);
}


/**
 * Database helper object
 */
private MovieDbHelper mDbHelper;

@Override
public boolean onCreate() {
    mDbHelper = new MovieDbHelper(getContext());
    return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                    String sortOrder) {
    // Get readable database
    SQLiteDatabase database = mDbHelper.getReadableDatabase();

    // This cursor will hold the result of the query
    Cursor cursor;

    // Figure out if the URI matcher can match the URI to a specific code
    int match = sUriMatcher.match(uri);

    switch (match) {
        case MOVIES:
            // For the MOVIES code, query the movie table directly with the given
            // projection, selection, selection arguments, and sort order. The cursor
            // could contain multiple rows of the movie table.
            cursor = database.query(MoviesEntry.TABLE_NAME, projection, selection, selectionArgs,
                    null, null, sortOrder);
            break;
        case MOVIE_ID:
            // For the MOVIE_ID code, extract out the ID from the URI.
            // For an example URI such as "content://com.example.android.movie/movie/3",
            // the selection will be "_id=?" and the selection argument will be a
            // String array containing the actual ID of 3 in this case.
            //
            // For every "?" in the selection, we need to have an element in the selection
            // arguments that will fill in the "?". Since we have 1 question mark in the
            // selection, we have 1 String in the selection arguments' String array.
            selection = MoviesEntry._ID + "=?";
            selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};

            // This will perform a query on the movie table where the _id equals 3 to return a
            // Cursor containing that row of the table.
            cursor = database.query(MoviesEntry.TABLE_NAME, projection, selection, selectionArgs,
                    null, null, sortOrder);
            break;
        default:
            throw new IllegalArgumentException("Cannot query unknown URI " + uri);
    }

    // Set notification URI on the Cursor,
    // so we know what content URI the Cursor was created for.
    // If the data at this URI changes, then we know we need to update the Cursor.
    cursor.setNotificationUri(getContext().getContentResolver(), uri);

    // Return the cursor
    return cursor;
}

@Override
public Uri insert(Uri uri, ContentValues contentValues) {
    final int match = sUriMatcher.match(uri);
    switch (match) {
        case MOVIES:
            return insertMovie(uri, contentValues);
        default:
            throw new IllegalArgumentException("Insertion is not supported for " + uri);
    }
}


/**
 * Insert a movie into the database with the given content values. Return the new content URI
 * for that specific row in the database.
 */
private Uri insertMovie(Uri uri, ContentValues values) {
   // Log.v("my_tag", "Received Uri to be matched insert is :"+uri.toString());
    Log.i("my_tag", "Received Uri to be matched insert is :"+uri.toString());
    // Check that the product name is not null
    String title = values.getAsString(MoviesEntry.COLUMN_MOVIE_TITLE);
    if (title == null) {
        throw new IllegalArgumentException("Product requires a name");
    }

    // Check that the product name is not null
    String releaseDate = values.getAsString(MoviesEntry.COLUMN_MOVIE_RELEASE_DATE);
    if (releaseDate == null) {
        throw new IllegalArgumentException("Product requires a detail");
    }

    // If the price is provided, check that it's greater than or equal to 0
    String overview = values.getAsString(MoviesEntry.COLUMN_MOVIE_OVERVIEW);
    if (overview == null) {
        throw new IllegalArgumentException("Product requires valid price");
    }

    String posterUrl = values.getAsString(MoviesEntry.COLUMN_MOVIE_POSTER_URL);
    if (posterUrl == null) {
        throw new IllegalArgumentException("Product requires valid quantity");
    }
    String backdropUrl = values.getAsString(MoviesEntry.COLUMN_MOVIE_BACKDROP_URL);
    if (backdropUrl == null) {
        throw new IllegalArgumentException("Product requires valid quantity");
    }
    Integer ratings = values.getAsInteger(MoviesEntry.COLUMN_MOVIE_RATING);
    if (ratings != null && ratings < 0) {
        throw new IllegalArgumentException("Product requires valid quantity");
    }

    // Get writeable database
    SQLiteDatabase database = mDbHelper.getWritableDatabase();

    // Insert the new product with the given values
    long id = database.insert(MoviesEntry.TABLE_NAME, null, values);

    Log.i("my_tag", "values is :"+values.toString());
   // Log.e("my_tag", "values is :"+values.toString());
   // Log.v("my_tag", "values is :"+values.toString());
    if (id == -1) {
        return null;
    }

    // Notify all listeners that the data has changed for the product content URI
    getContext().getContentResolver().notifyChange(uri, null);

    // Return the new URI with the ID (of the newly inserted row) appended at the end
    return ContentUris.withAppendedId(uri, id);
}

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

    // Get writeable database
    SQLiteDatabase database = mDbHelper.getWritableDatabase();

    // Track the number of rows that were deleted
    int rowsDeleted;

    final int match = sUriMatcher.match(uri);


        case MOVIES:
            // Delete all rows that match the selection and selection args
            rowsDeleted = database.delete(MoviesEntry.TABLE_NAME, selection, selectionArgs);
            break;
        case MOVIE_ID:
            // Delete a single row given by the ID in the URI
            selection = MoviesEntry._ID + "=?";
            selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
            Log.i("my_tag", "selection is :"+selection);
         //   Log.e("my_tag", "selection is :"+selection);
         //   Log.v("my_tag", "selection is :"+selection);
            Log.i("my_tag", "selectionArgs is :"+selectionArgs[0]);
          //  Log.e("my_tag", "selectionArgs is :"+selectionArgs[0]);
          //  Log.v("my_tag", "selectionArgs is :"+selectionArgs[0]);
            rowsDeleted = database.delete(MoviesEntry.TABLE_NAME, selection, selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Deletion is not supported for " + uri);
    }

    // If 1 or more rows were deleted, then notify all listeners that the data at the
    // given URI has changed
    if (rowsDeleted != 0) {
        getContext().getContentResolver().notifyChange(uri, null);
    }

    // Return the number of rows deleted
    return rowsDeleted;
}

@Override
public int update(Uri uri, ContentValues contentValues, String selection,
                  String[] selectionArgs) {
   ...
}

@Override
public String getType(Uri uri) {
    final int match = sUriMatcher.match(uri);
    switch (match) {
        case MOVIES:
            return MoviesEntry.CONTENT_LIST_TYPE;
        case MOVIE_ID:
            return MoviesEntry.CONTENT_ITEM_TYPE;
        default:
            throw new IllegalStateException("Unknown URI " + uri + " with match " + match);
    }
  }

}

0 个答案:

没有答案