Moved DiscoverTask to own class and started using MovieProvider

This commit is contained in:
Aargonian
2016-02-16 08:04:43 -05:00
parent 8aa12527a4
commit aab18e737f
12 changed files with 373 additions and 179 deletions

2
.idea/misc.xml generated
View File

@@ -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">

View File

@@ -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"

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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"

View File

@@ -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>