Moved DiscoverTask to own class and started using MovieProvider
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -37,7 +37,7 @@
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package="com.example.android.popularmovies">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.example.android.popularmovies;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -12,9 +12,11 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.example.android.popularmovies.data.FileUtils;
|
||||
import com.example.android.popularmovies.data.MovieContract.MovieEntry;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* Created by Aaron Helton on 1/31/2016
|
||||
*/
|
||||
@@ -31,6 +33,27 @@ public class DetailFragment extends Fragment
|
||||
private boolean viewCreated;
|
||||
private boolean displayTitle = false;
|
||||
|
||||
private final String[] projection = {
|
||||
MovieEntry.COLUMN_TITLE,
|
||||
MovieEntry.COLUMN_DESC,
|
||||
MovieEntry.COLUMN_IMG_PATH,
|
||||
MovieEntry.COLUMN_RELEASE,
|
||||
MovieEntry.COLUMN_RUNTIME,
|
||||
MovieEntry.COLUMN_RATING,
|
||||
MovieEntry.COLUMN_VOTE_CNT,
|
||||
MovieEntry.COLUMN_GENRES
|
||||
};
|
||||
|
||||
|
||||
@SuppressWarnings("all") private final int TITLE = 0;
|
||||
@SuppressWarnings("all") private final int OVERVIEW = 1;
|
||||
@SuppressWarnings("all") private final int IMG_PATH = 2;
|
||||
@SuppressWarnings("all") private final int RELEASE = 3;
|
||||
@SuppressWarnings("all") private final int RUNTIME = 4;
|
||||
@SuppressWarnings("all") private final int RATING = 5;
|
||||
@SuppressWarnings("all") private final int VOTE_COUNT = 6;
|
||||
@SuppressWarnings("all") private final int GENRES = 7;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
@@ -49,7 +72,7 @@ public class DetailFragment extends Fragment
|
||||
savedInstanceState.getStringArray("MOVIE_GENRES")
|
||||
);
|
||||
} else {
|
||||
Integer id = intent.getIntExtra("MOVIE_ID", -1);
|
||||
Long id = intent.getLongExtra("MOVIE_ID", -1);
|
||||
if(id != -1)
|
||||
{
|
||||
setMovie(id);
|
||||
@@ -107,23 +130,28 @@ public class DetailFragment extends Fragment
|
||||
}
|
||||
|
||||
|
||||
public void setMovie(Integer id)
|
||||
{
|
||||
new AsyncTask<Integer, Void, Movie>() {
|
||||
@Override
|
||||
public Movie doInBackground(Integer... params)
|
||||
{
|
||||
if(params.length < 1)
|
||||
return null;
|
||||
return Movie.getMovie(params[0], DetailFragment.this.getContext());
|
||||
}
|
||||
public void setMovie(Long id) {
|
||||
Cursor cur = getActivity().getContentResolver().query(MovieEntry.buildMovieUriWithId(id),
|
||||
projection, null, null, null);
|
||||
if (cur == null || !cur.moveToFirst())
|
||||
return;
|
||||
movie = new Movie(
|
||||
cur.getString(TITLE),
|
||||
cur.getString(OVERVIEW),
|
||||
FileUtils.getImage(cur.getString(IMG_PATH)),
|
||||
cur.getString(RELEASE),
|
||||
cur.getInt(RUNTIME),
|
||||
cur.getDouble(RATING),
|
||||
cur.getInt(VOTE_COUNT),
|
||||
parseGenres(cur.getString(GENRES))
|
||||
);
|
||||
cur.close();
|
||||
setMovieInfo(movie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute(Movie movie)
|
||||
{
|
||||
DetailFragment.this.setMovieInfo(movie);
|
||||
}
|
||||
}.execute(id);
|
||||
private String[] parseGenres(String genres)
|
||||
{
|
||||
return genres.split("_");
|
||||
}
|
||||
|
||||
private void setMovieInfo(Movie movie)
|
||||
@@ -133,7 +161,7 @@ public class DetailFragment extends Fragment
|
||||
movie.applyPoster(poster);
|
||||
overview.setText(movie.getOverview());
|
||||
release.setText(movie.getReleaseDate());
|
||||
rating.setText(movie.getRating() + "/10");
|
||||
rating.setText(movie.getRating() + getString(R.string.out_of_ten));
|
||||
title.setText(movie.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
package com.example.android.popularmovies;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
@@ -18,16 +13,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.nytegear.android.network.NetworkUtil;
|
||||
import com.nytegear.android.view.AsyncImage;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
@@ -42,9 +27,9 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
|
||||
private static final Integer PREFERRED_COLUMN_WIDTH = 100;
|
||||
private OnMovieSelectedListener mListener;
|
||||
private RecyclerView mMoviesGridView;
|
||||
private GridLayoutManager mManager;
|
||||
private MovieAdapter mAdapter;
|
||||
private String prevSort;
|
||||
|
||||
private String sort;
|
||||
private boolean loadingMovies;
|
||||
private int currentPage;
|
||||
|
||||
@@ -60,6 +45,7 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
|
||||
mAdapter = new MovieAdapter();
|
||||
mAdapter.setMovieItemClickedListener(this);
|
||||
currentPage = 1;
|
||||
sort = Utility.getSort(getActivity());
|
||||
}
|
||||
|
||||
public void onSaveInstanceState(Bundle bundle)
|
||||
@@ -76,7 +62,7 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
|
||||
Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.fragment_discover, container, false);
|
||||
ButterKnife.bind(this, root);
|
||||
//Create Recyclerview Programmatically so that we can get an auto-fit-like functionality
|
||||
//Create Recyclerview Programmatically so that we can get auto-fit-like functionality
|
||||
mMoviesGridView = new RecyclerView(this.getContext()) {
|
||||
@Override
|
||||
protected void onMeasure(int widthSpec, int heightSpec) {
|
||||
@@ -95,18 +81,15 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
|
||||
mMoviesGridView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
if (currentPage < 11) //check for scroll down
|
||||
{
|
||||
int visibleItemCount = recyclerView.getLayoutManager().getChildCount();
|
||||
int totalItemCount = recyclerView.getLayoutManager().getItemCount();
|
||||
int pastVisiblesItems =
|
||||
((GridLayoutManager) recyclerView.getLayoutManager())
|
||||
.findFirstVisibleItemPosition();
|
||||
int visibleItemCount = recyclerView.getLayoutManager().getChildCount();
|
||||
int totalItemCount = recyclerView.getLayoutManager().getItemCount();
|
||||
int pastVisiblesItems =
|
||||
((GridLayoutManager) recyclerView.getLayoutManager())
|
||||
.findFirstVisibleItemPosition();
|
||||
|
||||
if (!loadingMovies) {
|
||||
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
|
||||
addMovies();
|
||||
}
|
||||
if (!loadingMovies) {
|
||||
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
|
||||
addMovies();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +100,7 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
|
||||
mMoviesGridView.setHorizontalScrollBarEnabled(false);
|
||||
mMoviesGridView.setVerticalScrollBarEnabled(false);
|
||||
mMoviesGridView.setHasFixedSize(true);
|
||||
mManager = new GridLayoutManager(this.getContext(), 1);
|
||||
GridLayoutManager mManager = new GridLayoutManager(this.getContext(), 1);
|
||||
mMoviesGridView.setLayoutManager(mManager);
|
||||
mMoviesGridView.setAdapter(mAdapter);
|
||||
movieContainer.addView(mMoviesGridView);
|
||||
@@ -131,32 +114,38 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getContext());
|
||||
if(!prefs.getString(getString(R.string.pref_sort_key), getString(R.string.pref_sort_default))
|
||||
.equalsIgnoreCase(prevSort))
|
||||
{
|
||||
if(!sort.equals(Utility.getSort(getActivity()))) {
|
||||
mAdapter.emptyDataset();
|
||||
currentPage=1;
|
||||
currentPage = 1;
|
||||
addMovies();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void movieClicked(Integer id, String title)
|
||||
public void movieClicked(Long id)
|
||||
{
|
||||
mListener.onMovieSelected(id, title);
|
||||
mListener.onMovieSelected(id);
|
||||
}
|
||||
|
||||
public void addMovies() {
|
||||
if(currentPage < 11)
|
||||
{
|
||||
loadingMovies = true;
|
||||
DiscoverTask task = new DiscoverTask() {
|
||||
DiscoverTask task = new DiscoverTask(this.getActivity()) {
|
||||
@Override
|
||||
public void onProgressUpdate(String... update)
|
||||
{
|
||||
if(update.length == 2)
|
||||
{
|
||||
mAdapter.addMovie(Long.parseLong(update[0]), update[1]);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onPostExecute(Void result) {
|
||||
loadingMovies = false;
|
||||
}
|
||||
};
|
||||
Log.d(LOG_TAG, "CURRENT PAGE: " + currentPage);
|
||||
task.execute(currentPage++);
|
||||
}
|
||||
|
||||
@@ -180,72 +169,6 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
|
||||
}
|
||||
|
||||
public interface OnMovieSelectedListener {
|
||||
void onMovieSelected(Integer id, String title);
|
||||
}
|
||||
|
||||
private class DiscoverTask extends AsyncTask<Integer, MovieAdapter.MovieReference, Void>
|
||||
{
|
||||
private final String LOG_TAG = DiscoverTask.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public Void doInBackground(Integer... params)
|
||||
{
|
||||
int page = 1;
|
||||
if(params.length > 0)
|
||||
page = params[0];
|
||||
String TMDB_DISCOVER_URL = Movie.TMDB_URL_BASE+"/discover/movie?";
|
||||
Context context = DiscoverFragment.this.getActivity();
|
||||
SharedPreferences prefs =
|
||||
PreferenceManager
|
||||
.getDefaultSharedPreferences(DiscoverFragment.this.getActivity());
|
||||
String SORT = prefs.getString(getString(R.string.pref_sort_key), getString(R.string.pref_sort_default));
|
||||
prevSort = SORT;
|
||||
if(SORT.equalsIgnoreCase(getString(R.string.pref_sort_popularity_value)))
|
||||
SORT = "popularity.desc";
|
||||
else if (SORT.equalsIgnoreCase(getString(R.string.pref_sort_rating_value)))
|
||||
SORT = "vote_average.desc";
|
||||
else
|
||||
SORT = "release_date.desc";
|
||||
try {
|
||||
Uri.Builder builder = Uri.parse(TMDB_DISCOVER_URL).buildUpon()
|
||||
.appendQueryParameter("sort_by", SORT)
|
||||
.appendQueryParameter("api_key", Movie.API_KEY)
|
||||
.appendQueryParameter("page", Integer.toString(page));
|
||||
//Hack to avoid strange results in release date or vote average sorts
|
||||
if(SORT.equals("release_date.desc") || SORT.equals("vote_average.desc"))
|
||||
builder.appendQueryParameter("vote_count.gte", "250");
|
||||
Uri uri = builder.build();
|
||||
String moviesJSON = NetworkUtil.getURL(new URL(uri.toString()).toString());
|
||||
JSONObject movieList;
|
||||
if(moviesJSON != null)
|
||||
movieList = new JSONObject(moviesJSON);
|
||||
else
|
||||
return null;
|
||||
JSONArray results = movieList.getJSONArray("results");
|
||||
for(int i = 0; i < results.length(); i++)
|
||||
{
|
||||
Integer id = results.getJSONObject(i).getInt("id");
|
||||
String title = results.getJSONObject(i).getString("original_title");
|
||||
String posterURL = Movie.TMDB_POSTER_URL+
|
||||
results.getJSONObject(i).getString("poster_path");
|
||||
AsyncImage image = new AsyncImage(context,
|
||||
BitmapFactory.decodeResource(context.getResources(),
|
||||
R.drawable.loading));
|
||||
image.setImageURL(posterURL);
|
||||
publishProgress(new MovieAdapter.MovieReference(id, title, image));
|
||||
}
|
||||
} catch (MalformedURLException ex) {
|
||||
Log.e(LOG_TAG, "Malformed URL: " + ex.getMessage(), ex);
|
||||
} catch (JSONException ex) {
|
||||
Log.e(LOG_TAG, "Malformed JSON: " + ex.getMessage(), ex);
|
||||
}
|
||||
return null; //Satisfy return
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressUpdate(MovieAdapter.MovieReference... progress)
|
||||
{
|
||||
DiscoverFragment.this.mAdapter.addMovie(progress[0]);
|
||||
}
|
||||
void onMovieSelected(Long id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
package com.example.android.popularmovies;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import com.example.android.popularmovies.data.FileUtils;
|
||||
import com.example.android.popularmovies.data.MovieContract;
|
||||
import com.nytegear.android.network.NetworkUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 2/16/16.
|
||||
*
|
||||
* The DiscoverTask is responsible for fetching movies from theMovieDb's /discover/movie endpoint.
|
||||
* What the task does is it first downloads a list of movies at the specified page from the endpoint
|
||||
* Once the movies have been pulled down, it parses each id in the list, and checks to see if that
|
||||
* movie already exists in the database. If it doesn't, it silently downloads the movie and puts it
|
||||
* in the database. Either way, it then calls the publicProgress method with the TMDB_ID of the
|
||||
* movie, which can be used to fetch it from the DB for any activity/fragment listening.
|
||||
*/
|
||||
public class DiscoverTask extends AsyncTask<Integer, String, Void>
|
||||
{
|
||||
private final String LOG_TAG = DiscoverTask.class.getSimpleName();
|
||||
private final String TMDB_DISCOVER_URL = Movie.TMDB_URL_BASE + "/discover/movie?";
|
||||
private Context mContext;
|
||||
|
||||
public DiscoverTask(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void doInBackground(Integer... params)
|
||||
{
|
||||
int page = 1;
|
||||
if(params.length > 0)
|
||||
page = params[0];
|
||||
|
||||
if(NetworkUtil.isInternetAvailable(mContext)) {
|
||||
getMoviesWithNetworkAvailable(page);
|
||||
} else {
|
||||
getMoviesWithoutNetwork(page);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void getMoviesWithNetworkAvailable(int page)
|
||||
{
|
||||
Log.d(LOG_TAG, "Getting Movies with Available Network!");
|
||||
//Get Sort Parameter
|
||||
String SORT = Utility.getSort(mContext);
|
||||
if(SORT.equalsIgnoreCase(mContext.getString(R.string.pref_sort_popularity_value)))
|
||||
SORT = "popularity.desc";
|
||||
else if (SORT.equalsIgnoreCase(mContext.getString(R.string.pref_sort_rating_value)))
|
||||
SORT = "vote_average.desc";
|
||||
else
|
||||
SORT = "release_date.desc";
|
||||
|
||||
try
|
||||
{
|
||||
Uri.Builder builder = Uri.parse(TMDB_DISCOVER_URL).buildUpon()
|
||||
.appendQueryParameter("sort_by", SORT)
|
||||
.appendQueryParameter("api_key", Movie.API_KEY)
|
||||
.appendQueryParameter("page", Integer.toString(page));
|
||||
|
||||
//Hack to avoid strange results in vote average sorts.
|
||||
//TODO: Make this a setting.
|
||||
if(SORT.equals("vote_average.desc"))
|
||||
builder.appendQueryParameter("vote_count.gte", "250");
|
||||
Uri uri = builder.build();
|
||||
String moviesJSON = NetworkUtil.getURL(new URL(uri.toString()).toString());
|
||||
|
||||
|
||||
JSONObject movieList;
|
||||
if(moviesJSON != null)
|
||||
movieList = new JSONObject(moviesJSON);
|
||||
else {
|
||||
Log.e(LOG_TAG, "Catastrophe! We were unable to get the movies from " +
|
||||
Movie.TMDB_URL_BASE + "! Retrieving movies from local database only.");
|
||||
getMoviesWithoutNetwork(page);
|
||||
return;
|
||||
}
|
||||
|
||||
//Assuming all went well, we should have some JSON to parse now.
|
||||
JSONArray results = movieList.getJSONArray("results");
|
||||
for(int i = 0; i < results.length(); i++)
|
||||
{
|
||||
Integer id = results.getJSONObject(i).getInt("id");
|
||||
|
||||
//Intentional violation of SRP here, to avoid querying the database twice for
|
||||
//imgPath. Instead, we can use the path itself to determine if it was in the db.
|
||||
String imgFilePath = existsInDatabase(id);
|
||||
if(imgFilePath == null) {
|
||||
Movie movie = Movie.getMovie(id, mContext);
|
||||
if(movie == null)
|
||||
continue;
|
||||
ContentValues values = new ContentValues();
|
||||
try {
|
||||
imgFilePath = FileUtils.storeImage(mContext,
|
||||
Movie.getPoster(mContext,
|
||||
results.getJSONObject(i).getString("poster_path")),
|
||||
id + ".png");
|
||||
} catch (IOException ex) {
|
||||
Log.e(LOG_TAG, "Error Getting/Storing Poster: " + ex.getMessage(), ex);
|
||||
imgFilePath = FileUtils.storeImage(
|
||||
mContext,
|
||||
BitmapFactory.decodeResource(mContext.getResources(),
|
||||
R.drawable.noimage),
|
||||
id + ".png");
|
||||
}
|
||||
values.put(MovieContract.MovieEntry.COLUMN_TMDB_ID, id);
|
||||
values.put(MovieContract.MovieEntry.COLUMN_DESC, movie.getOverview());
|
||||
values.put(MovieContract.MovieEntry.COLUMN_IMG_PATH, imgFilePath);
|
||||
values.put(MovieContract.MovieEntry.COLUMN_RATING, movie.getRating());
|
||||
values.put(MovieContract.MovieEntry.COLUMN_RELEASE, movie.getReleaseDate());
|
||||
values.put(MovieContract.MovieEntry.COLUMN_POPULARITY,
|
||||
results.getJSONObject(i).getDouble("popularity"));
|
||||
values.put(MovieContract.MovieEntry.COLUMN_RUNTIME, movie.getRunTime());
|
||||
values.put(MovieContract.MovieEntry.COLUMN_TITLE, movie.getTitle());
|
||||
values.put(MovieContract.MovieEntry.COLUMN_VOTE_CNT, movie.getVoteCount());
|
||||
values.put(MovieContract.MovieEntry.COLUMN_GENRES,
|
||||
parseGenres(movie.getGenres()));
|
||||
|
||||
mContext.getContentResolver().insert(MovieContract.MovieEntry.CONTENT_URI,
|
||||
values);
|
||||
} else {
|
||||
Log.v(LOG_TAG, "IT'S IN THE DATABASE! WHOO!");
|
||||
}
|
||||
publishProgress(Long.toString(id), imgFilePath);
|
||||
}
|
||||
} catch (MalformedURLException ex) {
|
||||
Log.e(LOG_TAG, "Malformed URL: " + ex.getMessage(), ex);
|
||||
} catch (JSONException ex) {
|
||||
Log.e(LOG_TAG, "Malformed JSON: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String parseGenres(String[] genres)
|
||||
{
|
||||
StringBuilder genreEntry = new StringBuilder();
|
||||
for(int i = 0; i < genres.length; i++)
|
||||
{
|
||||
genreEntry.append(genres[i]);
|
||||
if(i != genres.length-1)
|
||||
genreEntry.append('_');
|
||||
}
|
||||
return genreEntry.toString();
|
||||
}
|
||||
|
||||
private String existsInDatabase(int id)
|
||||
{
|
||||
Cursor cursor =
|
||||
mContext.getContentResolver().query(
|
||||
MovieContract.MovieEntry.CONTENT_URI,
|
||||
null,
|
||||
MovieContract.MovieEntry.COLUMN_TMDB_ID + " = ?",
|
||||
new String[]{Long.toString(id)},
|
||||
null
|
||||
);
|
||||
if(cursor == null || !cursor.moveToFirst()) {
|
||||
if(cursor != null)
|
||||
cursor.close();
|
||||
return null;
|
||||
} else {
|
||||
String path = cursor.getString(
|
||||
cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_IMG_PATH));
|
||||
cursor.close();
|
||||
return path;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void getMoviesWithoutNetwork(int page) {
|
||||
long startRow = page * 25;
|
||||
long endRow = (page + 1) * 25;
|
||||
|
||||
String sort = Utility.getSort(mContext);
|
||||
|
||||
if (sort.equalsIgnoreCase(mContext.getString(R.string.pref_sort_rating_value))) {
|
||||
sort = MovieContract.MovieEntry.COLUMN_RATING + " DESC";
|
||||
} else {
|
||||
sort = MovieContract.MovieEntry.COLUMN_POPULARITY + " DESC";
|
||||
}
|
||||
|
||||
Cursor cursor = mContext.getContentResolver().query(
|
||||
MovieContract.MovieEntry.CONTENT_URI,
|
||||
new String[]{MovieContract.MovieEntry._ID, MovieContract.MovieEntry.COLUMN_TMDB_ID,
|
||||
MovieContract.MovieEntry.COLUMN_IMG_PATH},
|
||||
MovieContract.MovieEntry._ID + " >= ? AND " + MovieContract.MovieEntry._ID + " < ?",
|
||||
new String[]{Long.toString(startRow), Long.toString(endRow)},
|
||||
sort
|
||||
);
|
||||
|
||||
if(!(cursor == null || !cursor.moveToFirst())) {
|
||||
int idIndex = cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_TMDB_ID);
|
||||
int imgIndex = cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_IMG_PATH);
|
||||
for(int i = 0; i < cursor.getCount(); i++)
|
||||
{
|
||||
publishProgress(Long.toString(cursor.getLong(idIndex)), cursor.getString(imgIndex));
|
||||
cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,8 @@ public class MainActivity extends AppCompatActivity
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public void onMovieSelected(Integer movieID, String title)
|
||||
@Override
|
||||
public void onMovieSelected(Long movieID)
|
||||
{
|
||||
if(findViewById(R.id.detail_container) != null && details == null)
|
||||
{
|
||||
@@ -78,7 +79,6 @@ public class MainActivity extends AppCompatActivity
|
||||
else
|
||||
{
|
||||
Intent detailIntent = new Intent(this, DetailActivity.class);
|
||||
detailIntent.putExtra("MOVIE_TITLE", title);
|
||||
detailIntent.putExtra("MOVIE_ID", movieID);
|
||||
detailIntent.putExtra("DISPLAY_TITLE", true);
|
||||
this.startActivity(detailIntent);
|
||||
|
||||
@@ -2,16 +2,13 @@ package com.example.android.popularmovies;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.nytegear.android.view.AsyncImage;
|
||||
import com.nytegear.android.view.WebImageView;
|
||||
import com.example.android.popularmovies.data.FileUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -20,22 +17,21 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
|
||||
{
|
||||
private static final String LOG_TAG = MovieAdapter.class.getSimpleName();
|
||||
//Struct-like class for inner use
|
||||
public static class MovieReference {
|
||||
public final Integer id;
|
||||
public final String title;
|
||||
public final AsyncImage poster;
|
||||
private static class MovieReference {
|
||||
public final Long id;
|
||||
public final Bitmap poster;
|
||||
|
||||
public MovieReference(Integer id, String title, AsyncImage poster) {
|
||||
public MovieReference(Long id, Bitmap poster) {
|
||||
this.id = id;
|
||||
this.poster = poster;
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
|
||||
public interface MovieItemClickListener
|
||||
{
|
||||
void movieClicked(Integer movieID, String title);
|
||||
void movieClicked(Long movieID);
|
||||
}
|
||||
|
||||
private ArrayList<MovieReference> dataset;
|
||||
@@ -46,9 +42,10 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
|
||||
dataset = new ArrayList<>();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener, AsyncImage.AsyncImageListener {
|
||||
private String LOG_TAG = ViewHolder.class.getName();
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
|
||||
{
|
||||
private final String LOG_TAG = ViewHolder.class.getName();
|
||||
|
||||
public ImageView imageView;
|
||||
public ViewHolder(ImageView v)
|
||||
{
|
||||
@@ -57,25 +54,11 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
|
||||
imageView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void imageDownloaded(Bitmap bm)
|
||||
{
|
||||
Log.e(LOG_TAG, "IMAGE DOWNLOADED WOOT");
|
||||
imageView.setImageBitmap(bm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadFailed()
|
||||
{
|
||||
imageView.setImageBitmap(
|
||||
BitmapFactory.decodeResource(context.getResources(), R.drawable.noimage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(listener != null) {
|
||||
MovieReference reference = dataset.get(this.getLayoutPosition());
|
||||
listener.movieClicked(reference.id, reference.title);
|
||||
listener.movieClicked(reference.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,7 +71,7 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
|
||||
@Override
|
||||
public MovieAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
|
||||
{
|
||||
WebImageView view = new WebImageView(parent.getContext());
|
||||
ImageView view = new ImageView(parent.getContext());
|
||||
view.setAdjustViewBounds(true);
|
||||
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
|
||||
view.setScaleType(ImageView.ScaleType.FIT_XY);
|
||||
@@ -100,13 +83,14 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
|
||||
{
|
||||
MovieReference movie = dataset.get(position);
|
||||
if(movie != null) {
|
||||
movie.poster.setAsyncImageListener(holder);
|
||||
holder.imageView.setImageBitmap(movie.poster.getImage());
|
||||
holder.imageView.setImageBitmap(movie.poster);
|
||||
}
|
||||
}
|
||||
|
||||
public void addMovie(MovieReference reference)
|
||||
public void addMovie(long movieId, String imagePath)
|
||||
{
|
||||
MovieReference reference =
|
||||
new MovieReference(movieId, FileUtils.getImage(imagePath));
|
||||
dataset.add(reference);
|
||||
notifyItemInserted(dataset.size() - 1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.example.android.popularmovies;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
/**
|
||||
* Created by Aaron Helton on 2/16/2016
|
||||
*/
|
||||
public class Utility
|
||||
{
|
||||
private static String prevSort;
|
||||
private static boolean sortChanged;
|
||||
|
||||
public static String getSort(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String sort = prefs.getString(context.getString(R.string.pref_sort_key),
|
||||
context.getString(R.string.pref_sort_default));
|
||||
if(!sort.equalsIgnoreCase(prevSort)) {
|
||||
prevSort = sort;
|
||||
sortChanged = true;
|
||||
}
|
||||
return sort;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public final class FileUtils
|
||||
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(pictureFile);
|
||||
image.compress(format, 90, fos);
|
||||
image.compress(format, 0, fos);
|
||||
fos.close();
|
||||
return pictureFile.getAbsolutePath();
|
||||
} catch (FileNotFoundException e) {
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.nytegear.android.network;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.util.Log;
|
||||
|
||||
import com.squareup.picasso.Downloader;
|
||||
@@ -11,14 +13,13 @@ import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Created by Aaron Helton on 1/30/2016
|
||||
*/
|
||||
@@ -30,7 +31,7 @@ public final class NetworkUtil
|
||||
|
||||
public static String getURL(String urlString) {
|
||||
long nano = System.nanoTime();
|
||||
String res = getUrlImpl2(urlString);
|
||||
String res = getUrlImpl(urlString);
|
||||
|
||||
//Statistics
|
||||
long time = (System.nanoTime()-nano)/1000000;
|
||||
@@ -137,19 +138,34 @@ public final class NetworkUtil
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getUrlImpl2(String urlString)
|
||||
{
|
||||
try {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder()
|
||||
.url(new URL(urlString))
|
||||
.build();
|
||||
public static boolean isInternetAvailable(Context context) {
|
||||
final ConnectivityManager manager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
final NetworkInfo current = manager.getActiveNetworkInfo();
|
||||
|
||||
Response response = client.newCall(request).execute();
|
||||
return response.body().string();
|
||||
boolean connected = (current != null) && current.isConnected();
|
||||
if(!connected) return false;
|
||||
|
||||
//Check route to make sure we aren't on a closed-off network
|
||||
boolean routeExists;
|
||||
Socket s = null;
|
||||
try {
|
||||
//Check against Google DNS Server
|
||||
InetAddress host = InetAddress.getByName("8.8.8.8");
|
||||
s = new Socket();
|
||||
s.connect(new InetSocketAddress(host, 53), 5000); //5 second timeout. Plenty of time.
|
||||
routeExists = true;
|
||||
s.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e(LOG_TAG, "Error Getting Page: " + ex.getMessage(), ex);
|
||||
return null;
|
||||
routeExists = false;
|
||||
if(s != null && !s.isClosed()) {
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "ERROR CLOSING SOCKET: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return routeExists;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/detailLinear"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<RelativeLayout
|
||||
android:id="@+id/detailRelative"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<string name="pref_sort_rating_value">Rating</string>
|
||||
<string name="pref_sort_release_value">Release</string>
|
||||
<string name="get_move_button_label">Get More Movies</string>
|
||||
<string name="out_of_ten">/10</string>
|
||||
<array name="pref_sort_labels">
|
||||
<item name="pref_sort_popularity_label">Popularity</item>
|
||||
<item name="pref_sort_rating_label">Rating</item>
|
||||
|
||||
Reference in New Issue
Block a user