您好我正在研究Udacity热门电影项目。我必须将用户在内容提供商中选择的电影存储为他的收藏夹。我创建了一个内容提供程序,我使用游标加载器从中获取数据,并在用户选择收藏夹选项时显示它的回收器视图。我的问题是数据没有在我的应用中保留。从我的堆栈中删除应用程序并重新打开应用程序后,收藏夹屏幕为空。我做错了什么?
这是我的主要活动:
public class MainActivity extends AppCompatActivity implements CustomCursorAdapter.CustomCursorAdapterOnClickHandler,ImagesAdapter.ImagesAdapterOnClickHandler,LoaderManager.LoaderCallbacks<Cursor> {
private final String POPULAR_WEBSITE = "https://api.themoviedb.org/3/movie/popular?API_KEY";
private final String RATED_WEBSITE = "https://api.themoviedb.org/3/movie/top_rated?API_KEY";
// private final String RATED_WEBSITE = "https://api.themoviedb.org/3/movie/top_rated?API_KEY";
private ArrayList<String> list = new ArrayList<>();
ImagesAdapter adapter;
TextView errorTextView ;
ProgressBar progressBar;
RecyclerView recyclerView;
Bundle savedState = null;
ArrayList<MoviesClass> moviesClassList = new ArrayList<>();
final String TAG = MainActivity.class.getSimpleName();
CustomCursorAdapter simpleCursorAdapter;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
errorTextView = (TextView)findViewById(R.id.tv_error_message);
progressBar=(ProgressBar)findViewById(R.id.progressBar);
recyclerView = (RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
getLoaderManager().initLoader(1,null,this);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2);
simpleCursorAdapter = new CustomCursorAdapter(this,null,this);
recyclerView.setLayoutManager(layoutManager);
adapter = new ImagesAdapter(this);
recyclerView.setAdapter(adapter);
this.runOnUiThread(new Runnable() {
public void run() {
try {
if (NetworkUtility.isOnline()) {
loadData(POPULAR_WEBSITE);
} else {
// Toast.makeText(MainActivity.this, "No internet connection", Toast.LENGTH_LONG).show();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this,android.R.style.Theme_Material_Light_Dialog_Alert);
// Setting Dialog Title
alertDialog.setTitle(R.string.no_internet_connection);
// Setting Dialog Message
alertDialog.setMessage(R.string.exit);
// Setting Positive "Yes" Button
alertDialog.setPositiveButton(R.string.positive_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
// Write your code here to invoke YES event
Toast.makeText(getApplicationContext(), R.string.exit_activity, Toast.LENGTH_SHORT).show();
finish();
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton(R.string.negative_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
Toast.makeText(getApplicationContext(),R.string.connection_check, Toast.LENGTH_SHORT).show();
dialog.cancel();
MainActivity.this.recreate();
}
});
// Showing Alert Message
alertDialog.show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void loadData(String data) {
showDataView();
new DownloadTask().execute(data);
}
@Override
public void mClick(int position) {
Intent intent = new Intent(this, MovieDetails.class);
MoviesClass currentMovie = moviesClassList.get(position);
intent.putExtra("current movie", currentMovie);
startActivity(intent);
}
private void showDataView() {
errorTextView.setVisibility(View.INVISIBLE);
recyclerView.setVisibility(View.VISIBLE);
}
public void showError() {
errorTextView.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.INVISIBLE);
}
@Override
public CursorLoader onCreateLoader(int i, Bundle bundle) {
CursorLoader cursorLoader = new CursorLoader(this,FavouritesContractClass.FavouriteMovies.CONTENT_URI,null,null,null,null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader loader, Cursor o) {
// simpleCursorAdapter = new CustomCursorAdapter(this,o,this);
simpleCursorAdapter.swapCursor(o);
}
@Override
public void onLoaderReset(Loader loader) {
simpleCursorAdapter.swapCursor(null);
}
@Override
public void click(int position) {
}
public class DownloadTask extends AsyncTask<String,Void,ArrayList<String>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(ArrayList<String> s) {
progressBar.setVisibility(View.INVISIBLE);
showDataView();
adapter.setAdapterData(s);
// onSaveInstanceState(savedState);
}
@Override
protected ArrayList<String> doInBackground(String... strings) {
String response = null;
ArrayList<String> imagesList = new ArrayList<>();
ArrayList<String> uriList = new ArrayList<>();
if (strings.length == 0)
return null;
try {
response = NetworkUtility.makeHttpRequest(strings[0]);
if (response == null)
Toast.makeText(MainActivity.this, R.string.error_message, Toast.LENGTH_SHORT).show();
moviesClassList = ParseData.getMoviesObject(response);
for(int i =0; i< moviesClassList.size();i++)
Log.i(TAG, moviesClassList.get(0).getmId());
MoviesClass moviesClass = null;
for (int i = 0; i < moviesClassList.size(); i++) {
moviesClass = moviesClassList.get(i);
Log.i("movie name is",moviesClass.getmTitle());
imagesList.add(moviesClass.getmPosterPath());
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.appendEncodedPath("/image.tmdb.org/t/p/w185")
.appendEncodedPath(imagesList.get(i)).build();
uriList.add(builder.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
return uriList;
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.popular_sort:
loadData(POPULAR_WEBSITE);
return true;
case R.id.rated_sort:
loadData(RATED_WEBSITE);
return true;
case R.id.fav_sort:
/*try {
while (cursor.moveToNext()) {
Log.i("url is ", cursor.getString(cursor.getColumnIndex("url")));
list.add(cursor.getString(cursor.getColumnIndex("url")));
}
}finally {
cursor.close();
}*/
recyclerView.setAdapter(simpleCursorAdapter);
simpleCursorAdapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
这是我的内容提供商类;
public class FavouritesContentProvider extends ContentProvider {
public static final int MOVIES = 100;
public static final int MOVIE_ID = 101;
private MovieDbOpenHelper dbOpenHelper;
Cursor cursor;
@Override
public boolean onCreate() {
Context context = getContext();
dbOpenHelper = new MovieDbOpenHelper(context,null,null,1);
return true;
}
public UriMatcher sUriMatcher = buildUriMatcher();
private UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(FavouritesContractClass.AUTHORITY,FavouritesContractClass.PATH_FAVOURITES,MOVIES);
uriMatcher.addURI(FavouritesContractClass.AUTHORITY,FavouritesContractClass.PATH_FAVOURITES + "/#",MOVIE_ID);
return uriMatcher;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getReadableDatabase();
int match = sUriMatcher.match(uri);
switch (match) {
case MOVIES:
cursor = sqLiteDatabase.query(FavouritesContractClass.FavouriteMovies.TABLE_NAME, strings, s, strings1, null, null, s1);
break;
case MOVIE_ID:
cursor = sqLiteDatabase.query(FavouritesContractClass.FavouriteMovies.TABLE_NAME, strings, s, strings1, null, null, s1);
break;
default:
throw new UnsupportedOperationException("Unknown uri:" + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(),uri);
return cursor;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
int match = sUriMatcher.match(uri);
switch (match) {
case MOVIES:
// directory
return "vnd.android.cursor.dir" + "/" + FavouritesContractClass.AUTHORITY + "/" + FavouritesContractClass.FavouriteMovies.CONTENT_URI;
case MOVIE_ID:
// single item type
return "vnd.android.cursor.item" + "/" + FavouritesContractClass.AUTHORITY + "/" + FavouritesContractClass.FavouriteMovies.CONTENT_URI;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();
int match = sUriMatcher.match(uri);
Uri returnUri = null;
switch (match) {
case MOVIES:
long id = sqLiteDatabase.insertWithOnConflict(FavouritesContractClass.FavouriteMovies.TABLE_NAME, null, contentValues,SQLiteDatabase.CONFLICT_IGNORE);
if (id > 0)
returnUri = ContentUris.withAppendedId(FavouritesContractClass.FavouriteMovies.CONTENT_URI, id);
else
Toast.makeText(getContext(), "Already exists.", Toast.LENGTH_SHORT).show();
break;
default:
throw new UnsupportedOperationException("Unknown uri" + uri);
}
getContext().getContentResolver().notifyChange(uri,null);
return returnUri;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
return 0;
}
}
这是电影详细信息类:
public class MovieDetails extends AppCompatActivity implements View.OnClickListener {
public final String trailerBaseUri = "https://api.themoviedb.org/3/movie/";
String movieId;
Uri movieFinalUri, movieReviewUri;
ArrayList<MovieTrailerClass> movieTrailersList;
String movieReviewsList;
Uri.Builder builder;
MoviesClass currentMovie;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_details);
TextView title = (TextView) findViewById(R.id.title_tv);
TextView synopsis = (TextView) findViewById(R.id.synopsis_tv);
TextView userRating = (TextView) findViewById(R.id.rating_tv);
TextView date = (TextView) findViewById(R.id.date_tv);
ImageView imageView = (ImageView) findViewById(R.id.poster_thumbnail);
Intent intent = getIntent();
ImageView trailer1 = (ImageView) findViewById(R.id.trailer1);
ImageView trailer2 = (ImageView) findViewById(R.id.trailer2);
trailer1.setOnClickListener(this);
trailer2.setOnClickListener(this);
if (intent.hasExtra("current movie")) {
currentMovie = intent.getParcelableExtra("current movie");
builder = new Uri.Builder();
builder.scheme("http")
.appendEncodedPath("/image.tmdb.org/t/p/w185")
.appendEncodedPath(currentMovie.getmPosterPath()).build();
movieId = currentMovie.getmId();
title.setText(currentMovie.getmTitle());
synopsis.setText(currentMovie.getmSynopsis());
userRating.setText(currentMovie.getmRating() + "/10");
date.setText(currentMovie.getmReleaseDate());
movieFinalUri = Uri.parse(trailerBaseUri).buildUpon().appendPath(movieId).appendPath("videos").appendQueryParameter("api_key", "ebd331efd1f9bec67a9aa215b256ebe1")
.appendQueryParameter("language", "en").build();
Picasso.with(getApplicationContext())
.load(builder.toString())
.placeholder(R.drawable.popcorn_placeholder)
.error(R.drawable.error)
.resize(800, 1000)
.into(imageView);
movieTrailersList = new ArrayList<>();
DownloadTask task = new DownloadTask();
task.execute(movieFinalUri.toString());
movieReviewUri = Uri.parse(trailerBaseUri).buildUpon().appendPath(movieId).appendPath("reviews").appendQueryParameter("api_key", "ebd331efd1f9bec67a9aa215b256ebe1")
.appendQueryParameter("language", "en").build();
ReviewDownloadTask task1 = new ReviewDownloadTask();
task1.execute(movieReviewUri.toString());
// String movieReviewsExtra = getIntent().getStringExtra("movieReviewList");
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.trailer1:
openTrailer(movieTrailersList.get(0).getKey());
break;
case R.id.rating_tv:
Intent intent = new Intent(MovieDetails.this, ReviewActivity.class);
intent.putExtra("movieReviewList", movieReviewsList);
startActivity(intent);
/* case R.id.trailer3:
openTrailer(movieTrailersList.get(2).getKey());
break;*/
}
}
public void openTrailer(String key) {
Uri uri = Uri.parse("https://www.youtube.com/watch?").buildUpon().appendQueryParameter("v", key).build();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
}
public void openReview(String url) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW);
if(intent.resolveActivity(getPackageManager())!=null) {
intent.setData(uri);
startActivity(intent);
}else
Toast.makeText(this, "Unable to find browser to launch movie trailer!", Toast.LENGTH_SHORT).show();
}
public void markAsFavourite(View view) {
ContentValues contentValues = new ContentValues();
contentValues.put(FavouritesContractClass.FavouriteMovies.MOVIE_URL, builder.toString());
contentValues.put(FavouritesContractClass.FavouriteMovies.MOVIE_ID, movieId);
/*if(checkAlreadyExist()){
Toast.makeText(getApplicationContext(), "Already Exist!", Toast.LENGTH_SHORT).show();
} else {*/
Uri uri = getContentResolver().insert(FavouritesContractClass.FavouriteMovies.CONTENT_URI, contentValues);
if (uri != null) {
Toast.makeText(this, R.string.movie_saved_toast, Toast.LENGTH_SHORT).show();
Log.i("insert successsful", uri.toString());
} else
Log.i("insert not successsful", "suc");
}
class DownloadTask extends AsyncTask<String, Void, ArrayList<MovieTrailerClass>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
protected ArrayList<MovieTrailerClass> doInBackground(String... strings) {
try {
String response = NetworkUtility.makeHttpRequest(movieFinalUri.toString());
if (response != null) {
JSONObject baseObj = new JSONObject(response);
JSONArray resObject = baseObj.getJSONArray("results");
Gson gson = new Gson();
movieTrailersList = gson.fromJson(resObject.toString(), new TypeToken<List<MovieTrailerClass>>() {
}.getType());
} else {
Toast.makeText(MovieDetails.this, R.string.error_message, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return movieTrailersList;
}
}
public class ReviewDownloadTask extends AsyncTask<String, Void, String> {
String response = null;
@Override
protected void onPostExecute(String s) {
Gson gson = new Gson();
ArrayList<MovieReviewResults> movieReviewResults = gson.fromJson(movieReviewsList, new TypeToken<List<MovieReviewResults>>() {
}.getType());
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
for (MovieReviewResults movieReviewObject : movieReviewResults) {
TextView textView = new TextView(getApplicationContext());
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setGravity((Gravity.CENTER));
linearLayout.addView(textView);
textView.setText(movieReviewObject.getContent());
TextView textView1 = new TextView(getApplicationContext());
textView1.setGravity((Gravity.CENTER));
textView1.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
linearLayout.addView(textView1);
textView1.setText(movieReviewObject.getAuthor());
}
}
@Override
protected String doInBackground(String... strings) {
try {
response = NetworkUtility.makeHttpRequest(strings[0]);
if (response != null) {
JSONObject baseObj = new JSONObject(response);
JSONArray resObject = baseObj.getJSONArray("results");
movieReviewsList = resObject.toString();
} else {
Toast.makeText(MovieDetails.this, R.string.error_message, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return movieReviewsList;
}
}
public boolean checkAlreadyExist()
{
String query = "SELECT " + FavouritesContractClass.FavouriteMovies.MOVIE_ID + " FROM " + FavouritesContractClass.FavouriteMovies.TABLE_NAME + " WHERE " + FavouritesContractClass.FavouriteMovies.MOVIE_ID + " = " + movieId;;
MovieDbOpenHelper dbOpenHelper = new MovieDbOpenHelper(getApplicationContext(),null,null,1);
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
Log.i(" ai mger","here");
if (cursor.getCount() > 0)
{
Log.i("fpund","funf");
return true;
}
else
return false;
}
}
答案 0 :(得分:0)
如果希望提交更改并beginTransaction
提交更改,则可能需要在插入/更新/删除setTransactionSuccessful
之前尝试调用endTransaction
。请参阅下面的代码(注意:我没有测试此代码,因为我在平板电脑上写这个代码)
您还应该查看docs以获取更多信息。
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
SQLiteDatabase sqLiteDatabase = dbOpenHelper.getWritableDatabase();
int match = sUriMatcher.match(uri);
Uri returnUri = null;
switch (match) {
case MOVIES:
sqLiteDatabase.beginTransaction();
try {
long id = sqLiteDatabase.insertWithOnConflict(FavouritesContractClass.FavouriteMovies.TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_IGNORE);
if (id > 0)
returnUri = ContentUris.withAppendedId(FavouritesContractClass.FavouriteMovies.CONTENT_URI, id);
sqLiteDatabase.setTransactionSuccessful();
} finally {
sqLiteDatabase.endTransaction();
}
break;
default:
throw new UnsupportedOperationException("Unknown uri" + uri);
}
getContext().getContentResolver().notifyChange(uri,null);
return returnUri;
}