我正在为Udacity构建一个名为热门电影应用的应用程序,该应用程序将从movieDB获取电影信息并在第一个活动中显示海报,而不是如果用户点击任何海报,它将带他到detailActivity,其中将显示所有电影细节。
现在我已经完成了第1阶段,第2阶段我应该让用户能够制作一个最喜欢的电影列表,该列表将显示在第一个活动和deatilActivity中,并将从数据库中提取并发送到数据库。
我已经创建了数据库并且我保存了数据,但我不知道如何检索它并将其显示给用户,请帮助我这样做。
下面是我的代码:
第一个活动gridView for posters:
public class PhotoGrid extends Fragment {
//Create a string array variable for every item that we are going to recive from
// the movieDB
String[] movieId, movieTitle, movieReleaseDate, movieVoteAverage, movieOverview, moviePosterPath;
//use string1 to attach the poster path for every poster with the url so we can call the image
static String[] string1;
// define gridView here so we can use it in onPostexecute()
GridView gridView;
//movieUrl is used for the sortby setting
String movieUrl;
SQLiteDatabase db;
databaseHelper databaseHelper;
Cursor cursor;
ContentProvider contentProvider;
public PhotoGrid() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_refresh) {
updateMovie();
return true;
} else if (id == R.id.action_settings) {
//if action_setting clicked SettingActivity will start
Intent intent = new Intent(getActivity(), SettingActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
public void updateMovie() {
FetchMoviesPosters movieTask = new FetchMoviesPosters();
//make popularity as the default order or call for movieposters in settings
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getActivity());
String sortBy = sharedPreferences.getString(getString(R.string.pref_sortby_key),
getString(R.string.pref_sortby_default));
movieTask.execute(sortBy);
}
@Override
public void onStart() {
super.onStart();
//update movies list on start
updateMovie();
}
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_photo_grid, container, false);
databaseHelper = new databaseHelper(getActivity(),MovieContract.MovieEntry.TABLE_NAME,null,2);
db = databaseHelper.getReadableDatabase();
gridView = (GridView) rootView.findViewById(R.id.grid_view);
updateMovie();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//Here handle the on poster click action by assigning the clicked poster info
//to strings and send them to detail activity with different keys to be able to
// control each item alone
String movieIDText = movieId[i];
String movieTitleText = movieTitle[i];
String movieOverViewText = movieOverview[i];
String movieReleaseDateText = movieReleaseDate[i];
String movieRatingText = movieVoteAverage[i];
String movieDetailImage = moviePosterPath[i];
Intent intent = new Intent(getActivity(), DetailActivity.class);
intent.putExtra("movie_id", movieIDText);
intent.putExtra("movie_overview", movieOverViewText);
intent.putExtra("movie_title", movieTitleText);
intent.putExtra("movie_release_date", movieReleaseDateText);
intent.putExtra("movie_rating", movieRatingText);
intent.putExtra("image_path", movieDetailImage);
startActivity(intent);
}
});
return rootView;
}
//ImageAdapter is used to control images dimensions and load them in the
// imageview using Picasso
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private String[] mThumbIds;
public ImageAdapter(Context c, String[] str2) {
mContext = c;
mThumbIds = str2;
}
@Override
public int getCount() {
if (mThumbIds != null) {
return mThumbIds.length;
} else {
return 0;
}
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(700, 1200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(4, 4, 4, 4);
} else {
imageView = (ImageView) convertView;
}
Picasso.with(mContext).load(mThumbIds[position]).into(imageView);
return imageView;
}
}
public class FetchMoviesPosters extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchMoviesPosters.class.getSimpleName();
//in this function the different order settings are defined
private String setOrder(String sortBy) {
if (sortBy.equals(getString(R.string.pref_sorting_popularity))) {
movieUrl = "https://api.themoviedb.org/3/movie/popular?";
} else if (sortBy.equals(getString(R.string.pref_sorting_highest_rating))) {
movieUrl = "https://api.themoviedb.org/3/movie/top_rated?";
}
else if (sortBy.equals(getString(R.string.pref_sorting_favorite))){
cursor = databaseHelper.retrieveData(db);
if (cursor.moveToFirst()){
do {
String id, title, overView, releaseDate, rating, posterPath;
id = cursor.getString(0);
title = cursor.getString(1);
overView = cursor.getString(2);
releaseDate = cursor.getString(3);
rating = cursor.getString(4);
posterPath = cursor.getString(5);
contentProvider = new ContentProvider(id , title , overView
, releaseDate, rating , posterPath);
}while (cursor.moveToNext());
}
}
return sortBy;
}
private String[] MoviesJasonPrase(String moviesPosterStr ) throws JSONException {
final String M_Result = "results";
final String M_ID = "id";
final String M_Title = "original_title";
final String M_Release = "release_date";
final String M_Vote = "vote_average";
final String M_OverV = "overview";
final String M_Poster = "poster_path";
JSONObject moviesJson = new JSONObject(moviesPosterStr);
JSONArray resultsArray = moviesJson.getJSONArray(M_Result);
movieId = new String[resultsArray.length()];
movieTitle = new String[resultsArray.length()];
movieReleaseDate = new String[resultsArray.length()];
movieVoteAverage = new String[resultsArray.length()];
movieOverview = new String[resultsArray.length()];
moviePosterPath = new String[resultsArray.length()];
for (int i = 0; i < resultsArray.length(); i++) {
JSONObject movie = resultsArray.getJSONObject(i);
movieId[i] = movie.getString(M_ID);
movieTitle[i] = movie.getString(M_Title);
movieReleaseDate[i] = movie.getString(M_Release);
movieVoteAverage[i] = movie.getString(M_Vote);
movieOverview[i] = movie.getString(M_OverV);
moviePosterPath[i] = movie.getString(M_Poster);
}
return moviePosterPath;
}
@Override
protected String[] doInBackground(String... params) {
if (params.length == 0) {
return null;
}
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String moviePostersJsonStr = null;
try {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getActivity());
String sortBy = sharedPreferences.getString(getString(R.string.pref_sortby_key),
getString(R.string.pref_sorting_popularity));
setOrder(sortBy);
final String APPID_PARAM = "api_key";
Uri builtUri = Uri.parse(movieUrl).buildUpon()
.appendQueryParameter(APPID_PARAM, BuildConfig.THE_MOVIE_DB)
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
// Create the request to TheMovieDB, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuilder buffer = new StringBuilder();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line).append("\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
moviePostersJsonStr = buffer.toString();
} catch (IOException e) {
Log.e("PhotoGrid", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PhotoGrid", "Error closing stream", e);
}
}
}
try {
return MoviesJasonPrase(moviePostersJsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String[] Strings) {
if (Strings != null) {
string1 = new String[Strings.length];
for (int i = 0; i < Strings.length; i++) {
//receive poster images path
String[] getImage = Strings[i].split("-");
//concatenate path to url "http://image.tmdb.org/t/p/w185/"
string1[i] = "http://image.tmdb.org/t/p/w185/" + getImage[0];
}
ImageAdapter imageAdapter = new ImageAdapter(getActivity(), string1);
//put images after going though the adapter in the gridview
gridView.setAdapter(imageAdapter);
}
}
}
}
detailActivity:
public class DetailFragment extends Fragment {
String ID;
String title;
String overView;
String releaseDate;
String rating;
String posterPath;
String movieKey;
databaseHelper myDB ;
ImageButton favorite;
public DetailFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_detail, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent intent = new Intent(getActivity(), SettingActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
myDB = new databaseHelper(getActivity(), MovieContract.MovieEntry.TABLE_NAME,null,2);
favorite = (ImageButton) rootView.findViewById(R.id.favorite);
final Intent intent = getActivity().getIntent();
// The detail Activity called via intent. Inspect the intent for
// movies data using movie ID.
if (intent != null && intent.hasExtra("movie_id")) {
//if true put each item in a textview and load the poster in imageView
ID = intent.getStringExtra("movie_id");
title = intent.getStringExtra("movie_title");
((TextView) rootView.findViewById(R.id.title_text))
.setText(title);
overView = intent.getStringExtra("movie_overview");
((TextView) rootView.findViewById(R.id.overview_text))
.setText(overView);
releaseDate = intent.getStringExtra("movie_release_date");
((TextView) rootView.findViewById(R.id.release_date_text))
.setText(releaseDate);
rating = intent.getStringExtra("movie_rating");
((TextView) rootView.findViewById(R.id.rating_text))
.setText(rating);
posterPath = intent.getStringExtra("image_path");
String posterImage = "http://image.tmdb.org/t/p/w185/" + posterPath;
ImageView imageView = (ImageView) rootView.findViewById(R.id.detail_image);
Picasso.with(getActivity()).load(posterImage).resize(500, 800).into(imageView);
}
Button button = (Button) rootView.findViewById(R.id.play);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playTrailer();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(String.valueOf("http://www.youtube.com/watch?v="+ movieKey)));
startActivity(intent);
}
});
Button button1 = (Button) rootView.findViewById(R.id.open_reviews);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String id = ID;
Intent intent1 = new Intent(getActivity(), ReviewActivity.class);
intent1.putExtra("movie_id", id);
startActivity(intent1);
}
});
addData();
return rootView;
}
public void playTrailer() {
FetchMoviesTrailer fetchMoviesTrailer = new FetchMoviesTrailer();
fetchMoviesTrailer.execute(ID);
}
public void addData(){
favorite.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean isInsearted = myDB.insert(ID, title, overView, releaseDate,
rating, posterPath);
if (isInsearted)
Toast.makeText(getActivity(),"Added to Favorite", Toast.LENGTH_SHORT)
.show();
else
Toast.makeText(getActivity(),"Not Added to Favorite", Toast.LENGTH_SHORT)
.show();
}
}
);
}
public class FetchMoviesTrailer extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchMoviesTrailer.class.getSimpleName();
//in this function the different order settings are defined
private String[] MoviesJasonPrase(String moviesTrailerStr) throws JSONException {
final String T_Result = "results";
final String T_key = "key";
JSONObject moviesJson = new JSONObject(moviesTrailerStr);
JSONArray resultsArray = moviesJson.getJSONArray(T_Result);
String[] strings = new String[resultsArray.length()];
for (int i = 0; i < resultsArray.length(); i++) {
JSONObject movie = resultsArray.getJSONObject(i);
movieKey = movie.getString(T_key);
strings[i] = movieKey;
}
return strings;
}
@Override
protected String[] doInBackground(String... params) {
if (params.length == 0) {
return null;
}
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String movieTrailerJsonStr = null;
try {
final String APPID_PARAM = "api_key";
final String Traile_Url = "http://api.themoviedb.org/3/movie/" + ID
+ "/videos?";
Uri builtUri = Uri.parse(Traile_Url).buildUpon()
.appendQueryParameter(APPID_PARAM, BuildConfig.THE_MOVIE_DB)
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
// Create the request to TheMovieDB, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuilder buffer = new StringBuilder();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line).append("\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
movieTrailerJsonStr = buffer.toString();
} catch (IOException e) {
Log.e("PhotoGrid", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PhotoGrid", "Error closing stream", e);
}
}
}
try {
return MoviesJasonPrase(movieTrailerJsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String[] strings) {
super.onPostExecute(strings);
}
}
}
DataBase助手: public class databaseHelper扩展了SQLiteOpenHelper {
SQLiteDatabase db ;
public static final int DATABASE_VERSION = 2;
public static final String DATABASE_NAME = "FavoriteMovies.db";
public databaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_Movie_TABLE = "CREATE TABLE " + MovieEntry.TABLE_NAME + " (" +
MovieEntry.ID_COLUMAN + " TEXT PRIMARY KEY," +
MovieEntry.TITLE_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.OVERVIEW_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.RELEASE_DATE_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.RATING_COLUMAN + " TEXT NOT NULL, " +
MovieEntry.POSTAR_PATH_COLUMAN+ " TEXT NOT NULL " +
" );";
db.execSQL(SQL_CREATE_Movie_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS" + MovieEntry.TABLE_NAME);
onCreate(db);
}
public boolean insert(String id, String title , String overView , String date, String rating,
String poster){
db = super.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(MovieEntry.ID_COLUMAN,id);
contentValues.put(MovieEntry.TITLE_COLUMAN,title);
contentValues.put(MovieEntry.OVERVIEW_COLUMAN,overView);
contentValues.put(MovieEntry.RELEASE_DATE_COLUMAN,date);
contentValues.put(MovieEntry.RATING_COLUMAN,rating);
contentValues.put(MovieEntry.POSTAR_PATH_COLUMAN, poster);
long isAdded = db.insert(MovieEntry.TABLE_NAME, null ,contentValues);
if (isAdded == -1) {
return false;
}
else
return true;
}
public Cursor retrieveData(SQLiteDatabase db){
Cursor cursor;
String[] projection = {MovieEntry.ID_COLUMAN, MovieEntry.TITLE_COLUMAN,
MovieEntry.OVERVIEW_COLUMAN, MovieEntry.RELEASE_DATE_COLUMAN, MovieEntry.RATING_COLUMAN,
MovieEntry.POSTAR_PATH_COLUMAN};
cursor = db.query(MovieEntry.TABLE_NAME, projection, null,null,null,null,null);
return cursor;
}
}
数据库合同:
public class MovieContract {
public MovieContract(){}
public static abstract class MovieEntry implements BaseColumns{
public static final String TABLE_NAME = "favorite";
public static final String ID_COLUMAN = "ID";
public static final String TITLE_COLUMAN = "title";
public static final String OVERVIEW_COLUMAN = "overView";
public static final String RELEASE_DATE_COLUMAN = "releaseDate";
public static final String RATING_COLUMAN = "rating";
public static final String POSTAR_PATH_COLUMAN = "posterPath";
}
}
内容提供商:
public class ContentProvider {
private String id;
private String title;
private String overView;
private String releaseDate;
private String rating;
private String posterPath;
public ContentProvider(String ID, String Title,String OverView, String ReleaseDate,
String Rating, String PosterPath){
this.id = ID;
this.title = Title;
this.overView = OverView;
this.releaseDate = ReleaseDate;
this.rating = Rating;
this.posterPath = PosterPath;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getOverView() {
return overView;
}
public void setOverView(String overView) {
this.overView = overView;
}
public String getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(String releaseDate) {
this.releaseDate = releaseDate;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getPosterPath() {
return posterPath;
}
public void setPosterPath(String posterPath) {
this.posterPath = posterPath;
}
}
答案 0 :(得分:0)
这是Udacity课程中的全部内容。我建议您查看这些视频。
但是,基本思想是您需要在内容提供程序类中创建query()
方法。来自Udacity的Sunshine示例看起来像这样:
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// Here's the switch statement that, given a URI, will determine what kind of request it is,
// and query the database accordingly.
Cursor retCursor;
switch (sUriMatcher.match(uri)) {
// "weather/*/*"
case WEATHER_WITH_LOCATION_AND_DATE:
{
retCursor = getWeatherByLocationSettingAndDate(uri, projection, sortOrder);
break;
}
// "weather/*"
case WEATHER_WITH_LOCATION: {
retCursor = getWeatherByLocationSetting(uri, projection, sortOrder);
break;
}
// "weather"
case WEATHER: {
retCursor = mOpenHelper.getReadableDatabase().query(
WeatherContract.WeatherEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
// "location"
case LOCATION: {
retCursor = mOpenHelper.getReadableDatabase().query(
WeatherContract.LocationEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
从那里,如果您没有使用CursorLoader,则需要在内容解析器上调用查询方法并传入参数。
以下是Google的一个示例:
// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows
我还会看一下this link来阅读有关内容提供商的更多信息。