diff --git a/app/app.iml b/app/app.iml index d350fa2..f67d9e0 100644 --- a/app/app.iml +++ b/app/app.iml @@ -1,5 +1,5 @@ - + @@ -71,6 +71,8 @@ + + @@ -94,6 +96,7 @@ + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 25e262b..eaeaaa8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,4 +25,6 @@ dependencies { compile 'com.jakewharton:disklrucache:2.0.2' compile 'com.google.code.gson:gson:2.3.1' compile 'com.googlecode.flickrj-android:flickrj-android:2.1.0' + compile 'com.github.bumptech.glide:glide:3.6.0' + compile 'com.android.support:support-v4:19.1.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4cbcb6f..0eca3a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,11 +2,46 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/gstv/androidcodingexercise/controller/adapter/FlickrPictureAdapter.java b/app/src/main/java/com/gstv/androidcodingexercise/controller/adapter/FlickrPictureAdapter.java index 7c0df30..0b58e78 100644 --- a/app/src/main/java/com/gstv/androidcodingexercise/controller/adapter/FlickrPictureAdapter.java +++ b/app/src/main/java/com/gstv/androidcodingexercise/controller/adapter/FlickrPictureAdapter.java @@ -43,7 +43,7 @@ public FlickrPictureAdapter(Context context, PhotoList photos) { } @Override public View getView(int position, View convertView, ViewGroup parent) { - View cellView; - return cellView; +// return cellView; + return null; } } diff --git a/app/src/main/java/com/gstv/androidcodingexercise/controller/fragment/LargePictureFragment.java b/app/src/main/java/com/gstv/androidcodingexercise/controller/fragment/LargePictureFragment.java index 5d922a8..493f4cf 100644 --- a/app/src/main/java/com/gstv/androidcodingexercise/controller/fragment/LargePictureFragment.java +++ b/app/src/main/java/com/gstv/androidcodingexercise/controller/fragment/LargePictureFragment.java @@ -27,5 +27,6 @@ public class LargePictureFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstance) { //TODO: implement method + return null; } } diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/Mutex.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/Mutex.java new file mode 100644 index 0000000..d2e2c12 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/Mutex.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel; + +import java.util.concurrent.Semaphore; +/** + * + * @author user + */ +public class Mutex { + private final Semaphore lock; + + public Mutex() { + lock = new Semaphore(1); + } + + public boolean lock() { + boolean ret = false; + + try { + lock.acquire(); + ret = true; + } catch(InterruptedException _e) { + } + + return ret; + } + + public void unlock() { + lock.release(); + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/FullSizeImageDisplay.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/FullSizeImageDisplay.java new file mode 100644 index 0000000..6292217 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/FullSizeImageDisplay.java @@ -0,0 +1,126 @@ +package com.gstv.androidcodingexercise.joel.activities; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.graphics.Bitmap; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.widget.ImageView; +import com.bumptech.glide.Glide; +import com.gstv.androidcodingexercise.R; +import com.gstv.androidcodingexercise.joel.activities.data_types.ImageDisplayArrayAdapterData; + +/** + * Created by user on 8/16/15. + */ +public class FullSizeImageDisplay extends Activity { + private ImageView imageView; + private ImageDisplayArrayAdapterData imageData; + private GetFullSizeUserPhotoAsyncTask getFullSizeUserPhotoAsyncTask; + + @Override + protected void onCreate(Bundle _bundle) { + super.onCreate(_bundle); + setContentView(R.layout.activity_full_size_image_display); + imageView = (ImageView) findViewById(R.id.full_size_image_view); + imageData = (ImageDisplayArrayAdapterData)getIntent() + .getParcelableExtra("ImageDisplayArrayAdapterData"); + } + + @Override + public void onResume() { + super.onResume(); + getFullSizeUserPhotoAsyncTask = new GetFullSizeUserPhotoAsyncTask(); + getFullSizeUserPhotoAsyncTask.execute(); + } + + @Override + public void onPause() { + super.onPause(); + getFullSizeUserPhotoAsyncTask.cancel(true); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + + private Handler loadFullSizeBitmapIntoImageView = new Handler() { + @Override + public void handleMessage(Message _message) { + if(_message == null) { + } else if(_message.obj == null) { + } else if(_message.arg1 == 100) { + imageView.setImageBitmap((Bitmap) _message.obj); + } + } + }; + + + // generic types are Params, Progress, and Result + private class GetFullSizeUserPhotoAsyncTask extends AsyncTask { + private Context asyncContext; + private Handler asyncHandler; + private ImageDisplayArrayAdapterData asyncImageData; + private ProgressDialog progressDialog; + + public GetFullSizeUserPhotoAsyncTask() { + progressDialog = new ProgressDialog(FullSizeImageDisplay.this); + } + + @Override + public void onCancelled() { + + } + + @Override + public void onPreExecute() { + asyncContext = getApplicationContext(); + asyncHandler = loadFullSizeBitmapIntoImageView; + asyncImageData = imageData; + progressDialog.setMessage("Please Wait..."); + progressDialog.show(); + } + + @Override + public Void doInBackground(String[] params) { + int photoWidth = Integer.valueOf(asyncImageData.fullSizeImageWidth); + int photoHeight = Integer.valueOf(asyncImageData.fullSizeImageHeight); + try { + Bitmap bitmap = Glide + .with(asyncContext) + .load(asyncImageData.fullSizeImageUrl) + .asBitmap() + .into(photoWidth, photoHeight) + .get(); + sendBitmapToHandler(bitmap); + } catch (java.lang.InterruptedException _e) { + } catch (java.util.concurrent.ExecutionException _e) { + } + + return null; + } + + private void sendBitmapToHandler(Bitmap _bitmap) { + Message message = asyncHandler.obtainMessage(); + message.arg1 = 100; + message.obj = _bitmap; + asyncHandler.sendMessage(message); + } + + @Override + public void onProgressUpdate(String[] progress) { + } + + @Override + public void onPostExecute(Void _v) { + if(progressDialog.isShowing()) { + progressDialog.dismiss(); + } + } + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageDisplayArrayAdapter.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageDisplayArrayAdapter.java new file mode 100644 index 0000000..4ff97bb --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageDisplayArrayAdapter.java @@ -0,0 +1,76 @@ +package com.gstv.androidcodingexercise.joel.activities; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.app.Activity; +import android.widget.ImageView; +import android.widget.TextView; + +import com.gstv.androidcodingexercise.joel.activities.data_types.ImageDisplayArrayAdapterData; + +import com.gstv.androidcodingexercise.R; + +import java.util.ArrayList; + +/** + * Created by user on 8/16/15. + */ +public class ImageDisplayArrayAdapter extends ArrayAdapter { + private final Activity context; + private final ArrayList bitmapData; + + public ImageDisplayArrayAdapter(Activity _context, ArrayList _bitmapData) { + super(_context, R.layout.joel_thumbnail_list_item, _bitmapData); + this.context = _context; + this.bitmapData = _bitmapData; + } + + @Override + public View getView(int _position, View _view, ViewGroup _parent) { + View rowView = _view; + + if(rowView != null) { + } else { + LayoutInflater layoutInflater = context.getLayoutInflater(); + rowView = layoutInflater.inflate(R.layout.joel_thumbnail_list_item, null); + ImageView imageView = (ImageView) rowView.findViewById(R.id.image_list_main_image); + TextView textView = (TextView) rowView.findViewById(R.id.image_list_image_name); + imageView.setImageBitmap(bitmapData.get(_position).bitmap); + textView.setText(bitmapData.get(_position).imageName); + rowView.setTag(_position); + setUpRowViewOnClickListener(rowView, _position); + } + + return rowView; + } + + private void setUpRowViewOnClickListener(View _rowView, int _position) { + _rowView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(context, FullSizeImageDisplay.class); + Bundle bundle = new Bundle(); + bundle.putParcelable("ImageDisplayArrayAdapterData", bitmapData.get((int) v.getTag())); + intent.putExtras(bundle); + context.startActivity(intent); + } + }); + } + + @Override + public void add(ImageDisplayArrayAdapterData _data) { + bitmapData.add(_data); + notifyDataSetChanged(); + } + + @Override + public void clear() { + bitmapData.clear(); + notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageListDisplay.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageListDisplay.java new file mode 100644 index 0000000..f96316f --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageListDisplay.java @@ -0,0 +1,106 @@ +package com.gstv.androidcodingexercise.joel.activities; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import com.gstv.androidcodingexercise.R; +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import android.os.Handler; +import android.os.Message; +import android.widget.ListView; +import android.widget.TextView; +import com.gstv.androidcodingexercise.joel.activities.data_types.ImageDisplayArrayAdapterData; +import java.util.ArrayList; + +public class ImageListDisplay extends Activity { + private ListView listView; + private ImageDisplayArrayAdapter arrayAdapter; + private ArrayList bitmapData; + private ImageListDisplayAsyncTask imageListDisplayAsyncTask; + private EditText searchText; + private Button searchButton; + private TextView notificationTextView; + private ProgressDialog progressDialog; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.joel_activity_image_display); + notificationTextView = (TextView)findViewById(R.id.text_view_for_thumbnails_results); + progressDialog = new ProgressDialog(ImageListDisplay.this); + setUpListViewAndAdapter(); + setUpSearchValues(); + } + + @Override + public void onResume() { + super.onResume(); + setUpNewAsyncTask(); + } + + @Override + public void onPause() { + super.onPause(); + imageListDisplayAsyncTask.cancel(true); + arrayAdapter.clear(); + notificationTextView.setText(""); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + + private void setUpListViewAndAdapter() { + listView = (ListView) findViewById(R.id.list_view_for_thumbnails); + bitmapData = new ArrayList(); + arrayAdapter = new ImageDisplayArrayAdapter(this, bitmapData); + listView.setAdapter(arrayAdapter); + } + + private void setUpSearchValues() { + searchText = (EditText)findViewById(R.id.image_list_search_edittext); + searchButton = (Button)findViewById(R.id.image_list_search_button); + searchButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + arrayAdapter.clear(); + notificationTextView.setText(""); + setUpNewAsyncTask(); + } + }); + } + + private void setUpNewAsyncTask() { + if(imageListDisplayAsyncTask != null) { + imageListDisplayAsyncTask.cancel(true); + } + imageListDisplayAsyncTask = new ImageListDisplayAsyncTask( + getApplicationContext(), listViewHandler); + imageListDisplayAsyncTask.execute(searchText.getText().toString()); + } + + private Handler listViewHandler = new Handler() { + @Override + public void handleMessage(Message _message) { + if(_message == null) { + } else if(_message.arg1 == Defines.activityStartProgressDialog) { + progressDialog.setMessage("Please Wait..."); + progressDialog.show(); + } else if(_message.arg1 == Defines.activityStopProgressDialog) { + if(progressDialog.isShowing()) { + progressDialog.dismiss(); + } + } else if(_message.obj == null) { + } else if(_message.arg1 == Defines.imageListDisplayAddDataToAdapter) { + arrayAdapter.add((ImageDisplayArrayAdapterData)_message.obj); + } else if(_message.arg1 == Defines.imageListDisplaySetResults) { + notificationTextView.setText((String)_message.obj); + } + } + }; +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageListDisplayAsyncTask.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageListDisplayAsyncTask.java new file mode 100644 index 0000000..f473cd7 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/ImageListDisplayAsyncTask.java @@ -0,0 +1,180 @@ +package com.gstv.androidcodingexercise.joel.activities; + +import android.content.Context; +import android.graphics.Bitmap; +import android.os.AsyncTask; +import android.os.Handler; +import android.os.Message; +import android.app.Activity; +import com.bumptech.glide.Glide; +import com.gstv.androidcodingexercise.joel.activities.data_types.ImageDisplayArrayAdapterData; +import com.gstv.androidcodingexercise.joel.web_api.DataManagerSingleton; +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.web_api.get_user_photo_list.GetUserPhotoList; +import com.gstv.androidcodingexercise.joel.web_api.get_user_photo_list.GetUserPhotoListResponseData; +import com.gstv.androidcodingexercise.joel.web_api.data_types.Photo; +import com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords.SearchPhotosByKeywords; +import com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords.SearchPhotosByKeywordsResponseData; + +/** + * Created by user on 8/16/15. + */ + +// generic types are Params, Progress, and Result +public class ImageListDisplayAsyncTask extends AsyncTask { + private Context asyncContext; + private Activity activity; + private Handler asyncHandler; + private GetUserPhotoList getUserPhotoList; + private SearchPhotosByKeywords searchPhotosByKeywords; + + public ImageListDisplayAsyncTask(Context _context, Handler _handler) { + asyncContext = _context; + asyncHandler = _handler; + getUserPhotoList = null; + searchPhotosByKeywords = null; + } + + @Override + public void onCancelled() { + if(getUserPhotoList != null) { + getUserPhotoList.stop(); + } + if(searchPhotosByKeywords != null) { + searchPhotosByKeywords.stop(); + } + } + + @Override + public void onPreExecute() { + super.onPreExecute(); + tellHandlerToStartProgressDialog(); + } + + @Override + public Void doInBackground(String[] params) { + Photo[] photos; + if(params == null || params.length < 1 || params[0].compareTo("") == 0) { + photos = getListOfUserPhotos(); + } else { + photos = getListOfUserPhotosFromKeywords(Defines.apiKey, Defines.nsid, params[0]); + } + + if(photos == null) { + System.out.println("error loading photos in AsyncTask"); + tellHandlerToStopProgressDialog(); + } else if(photos.length < 1) { + tellHandlerToSetResultsTextView("No results available"); + tellHandlerToStopProgressDialog(); + } else { + doInBackgroundMainLoop(photos); + } + + return null; + } + + private Photo[] getListOfUserPhotos() { + Photo[] ret = null; + + getUserPhotoList = new GetUserPhotoList(); + GetUserPhotoListResponseData getUserPhotoListResponseData = + getUserPhotoList.getUserPhotoList(DataManagerSingleton.getNsid(), 1); + if(getUserPhotoListResponseData.dataError != null) { + } else if(getUserPhotoListResponseData.dataSuccess != null) { + ret = getUserPhotoListResponseData.dataSuccess.photos.photo; + } + + return ret; + } + + private Photo[] getListOfUserPhotosFromKeywords(String _apiKey, String _nsid, String _keywords) { + Photo[] ret = null; + + searchPhotosByKeywords = new SearchPhotosByKeywords(); + SearchPhotosByKeywordsResponseData searchPhotosByKeywordsResponseData = + searchPhotosByKeywords.getUserPhotoList(_apiKey, _nsid, _keywords); + if(searchPhotosByKeywordsResponseData.dataError != null) { + } else if(searchPhotosByKeywordsResponseData.dataSuccess != null) { + ret = searchPhotosByKeywordsResponseData.dataSuccess.photos.photo; + } + + return ret; + } + + private void doInBackgroundMainLoop(Photo[] _photos) { + for(int i = 0; i < _photos.length; i++) { + if(isCancelled()) { + break; + } else { + Bitmap bitmapToLoad = loadBitmapFromUrl(_photos[i]); + if(bitmapToLoad == null) { + System.out.println("error with bitmapToLoad"); + } else { + sendBitmapToHandler(prepareDataForHandler(bitmapToLoad, _photos[i])); + tellHandlerToStopProgressDialog(); + } + } + } + } + + private Bitmap loadBitmapFromUrl(Photo _photo) { + Bitmap ret = null; + + try { + ret = Glide + .with(asyncContext) + .load(_photo.url_t) + .asBitmap() + .into(Integer.valueOf(_photo.width_t), Integer.valueOf(_photo.height_t)) + .get(); + } catch (java.lang.InterruptedException _e) { + } catch (java.util.concurrent.ExecutionException _e) { + } + + return ret; + } + + private ImageDisplayArrayAdapterData prepareDataForHandler(Bitmap _bitmap, Photo _photo) { + ImageDisplayArrayAdapterData ret = new ImageDisplayArrayAdapterData(); + ret.bitmap = _bitmap; + ret.imageName = _photo.title; + ret.fullSizeImageUrl = _photo.url_o; + ret.fullSizeImageHeight = _photo.height_o; + ret.fullSizeImageWidth = _photo.width_o; + return ret; + } + + private void sendBitmapToHandler(ImageDisplayArrayAdapterData _data) { + Message message = asyncHandler.obtainMessage(); + message.arg1 = Defines.imageListDisplayAddDataToAdapter; + message.obj = _data; + asyncHandler.sendMessage(message); + } + + private void tellHandlerToSetResultsTextView(String _results) { + Message message = asyncHandler.obtainMessage(); + message.arg1 = Defines.imageListDisplaySetResults; + message.obj = (Object)_results; + asyncHandler.sendMessage(message); + } + + private void tellHandlerToStartProgressDialog() { + Message message = asyncHandler.obtainMessage(); + message.arg1 = Defines.activityStartProgressDialog; + asyncHandler.sendMessage(message); + } + + private void tellHandlerToStopProgressDialog() { + Message message = asyncHandler.obtainMessage(); + message.arg1 = Defines.activityStopProgressDialog; + asyncHandler.sendMessage(message); + } + + @Override + public void onProgressUpdate(String[] progress) { + } + + @Override + public void onPostExecute(Void _v) { + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/Main.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/Main.java new file mode 100644 index 0000000..65db646 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/Main.java @@ -0,0 +1,130 @@ +package com.gstv.androidcodingexercise.joel.activities; + +import android.app.Activity; +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; +import android.content.Intent; +import android.app.ProgressDialog; + +import com.gstv.androidcodingexercise.R; +import com.gstv.androidcodingexercise.joel.activities.data_types.ImageDisplayArrayAdapterData; +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.web_api.find_by_username.*; +import com.gstv.androidcodingexercise.joel.web_api.DataManagerSingleton; + +/** + * Created by user on 8/12/15. + */ +public class Main extends Activity { + private MainAsyncTask mainAsyncTask; + private Button loginButton; + private EditText username; + private Context thisContextForAsyncTask; + + @Override + protected void onCreate(Bundle _savedInstanceState) { + super.onCreate(_savedInstanceState); + setContentView(R.layout.joel_main_activity); + setGlobalsForAsyncTask(); + setUpLoginButton(); + } + + @Override + public void onResume() { + super.onResume(); + mainAsyncTask = null; + } + + @Override + public void onPause() { + super.onPause(); + if(mainAsyncTask != null) { + mainAsyncTask.cancel(true); + } + } + + private void setGlobalsForAsyncTask() { + username = (EditText)findViewById(R.id.username); + thisContextForAsyncTask = this; + } + + private void setUpLoginButton() { + loginButton = (Button) findViewById(R.id.username_get_photos_button); + loginButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View _view) { + if(mainAsyncTask == null) { + mainAsyncTask = new MainAsyncTask(); + mainAsyncTask.execute(); + } + } + }); + } + + // generic types are Params, Progress, and Result + private class MainAsyncTask extends AsyncTask { + private FindPersonByUsername findPersonByUsername; + private String asyncUsername; + private Context context; + private ProgressDialog progressDialog; + + public MainAsyncTask() { + progressDialog = new ProgressDialog(Main.this); + } + + @Override + public void onCancelled() { + findPersonByUsername.stop(); + } + + @Override + public void onPreExecute() { + findPersonByUsername = null; + asyncUsername = username.getText().toString(); + context = thisContextForAsyncTask; + progressDialog.setMessage("Please Wait..."); + progressDialog.show(); + } + + @Override + public FindPersonResponseData doInBackground(String[] params) { + findPersonByUsername = new FindPersonByUsername(); + FindPersonResponseData responseData = findPersonByUsername.findPersonByUsername(asyncUsername); + return responseData; + } + + @Override + public void onProgressUpdate(String[] progress) { + } + + @Override + public void onPostExecute(FindPersonResponseData _result) { + if(progressDialog.isShowing()) { + progressDialog.dismiss(); + } + + if(_result.errorData != null) { + Toast.makeText(getApplicationContext(), _result.errorData.message, Toast.LENGTH_LONG).show(); + } else if(_result.jsonData != null) { + processAsyncSuccess(_result); + } else { + Toast.makeText(getApplicationContext(), "Unspecified error", Toast.LENGTH_LONG).show(); + } + } + + private void processAsyncSuccess(FindPersonResponseData _result) { + DataManagerSingleton.setUsername(_result.jsonData.user.username._content); + DataManagerSingleton.setNsid(_result.jsonData.user.nsid); + //Toast.makeText(getApplicationContext(), _result.jsonData.stat, Toast.LENGTH_LONG).show(); + Intent intent = new Intent(context, ImageListDisplay.class); + startActivity(intent); + } + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/data_types/ImageDisplayArrayAdapterData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/data_types/ImageDisplayArrayAdapterData.java new file mode 100644 index 0000000..7d17bdb --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/activities/data_types/ImageDisplayArrayAdapterData.java @@ -0,0 +1,57 @@ +package com.gstv.androidcodingexercise.joel.activities.data_types; + +import android.graphics.Bitmap; +import android.os.Parcel; +import android.os.Parcelable; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.Photo; +import java.io.Serializable; +/** + * Created by user on 8/16/15. + */ +public class ImageDisplayArrayAdapterData implements Parcelable { + public Bitmap bitmap; + public String imageName; + public String fullSizeImageUrl; + public String fullSizeImageHeight; + public String fullSizeImageWidth; + + public ImageDisplayArrayAdapterData() { + bitmap = null; + imageName = ""; + fullSizeImageUrl = ""; + fullSizeImageHeight = ""; + fullSizeImageWidth = ""; + } + + public static final Parcelable.Creator CREATOR = + new Creator() { + public ImageDisplayArrayAdapterData createFromParcel(Parcel _source) { + ImageDisplayArrayAdapterData data = new ImageDisplayArrayAdapterData(); + data.bitmap = (Bitmap)_source.readValue(Bitmap.class.getClassLoader()); + data.imageName = (String)_source.readString(); + data.fullSizeImageUrl = (String)_source.readString(); + data.fullSizeImageHeight = (String)_source.readString(); + data.fullSizeImageWidth = (String)_source.readString(); + return data; + } + + public ImageDisplayArrayAdapterData[] newArray(int _size) { + return new ImageDisplayArrayAdapterData[_size]; + } + }; + + @Override + public void writeToParcel(Parcel _parcel, int _int) { + _parcel.writeValue(bitmap); + _parcel.writeString(imageName); + _parcel.writeString(fullSizeImageUrl); + _parcel.writeString(fullSizeImageHeight); + _parcel.writeString(fullSizeImageWidth); + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/DataManagerSingleton.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/DataManagerSingleton.java new file mode 100644 index 0000000..d40cd26 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/DataManagerSingleton.java @@ -0,0 +1,69 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api; + +import com.gstv.androidcodingexercise.joel.Mutex; +/** + * + * @author user + */ +public class DataManagerSingleton { + private static final Mutex mutex = new Mutex(); + private static String username = ""; + private static String nsid = ""; + + public static boolean setUsername(String _username) { + boolean ret = false; + + if(!mutex.lock()) { + } else { + if(_username == null || _username.length() < 50) { + username = _username; + } + mutex.unlock(); + } + + return ret; + } + + public static String getUsername() { + String ret = ""; + + if(!mutex.lock()) { + } else { + ret = new String(username); + mutex.unlock(); + } + + return ret; + } + + public static boolean setNsid(String _nsid) { + boolean ret = false; + + if(!mutex.lock()) { + } else { + if(_nsid == null || _nsid.length() < 50) { + nsid = _nsid; + } + mutex.unlock(); + } + + return ret; + } + + public static String getNsid() { + String ret = ""; + + if(!mutex.lock()) { + } else { + ret = new String(nsid); + mutex.unlock(); + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/Defines.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/Defines.java new file mode 100644 index 0000000..28410de --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/Defines.java @@ -0,0 +1,44 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.math.BigInteger; +/** + * + * @author user + */ +public class Defines { + public static final String flickrBaseUrl = "https://api.flickr.com/services/rest/?method="; + public static final String apiKey = "c34fb9679eadf5d5e30187fcd1a633f1"; + public static final String nsid = "135341216@N03"; + + public static final String getPeopleByUsernameMethod = "flickr.people.findByUsername"; + public static final String getUserPhotoListMethod = "flickr.people.getPublicPhotos"; + public static final String getPhotosByKeywordMethod = "flickr.photos.search"; + + public static final int mainStartImageListDisplayActivity = 100; + + public static final int imageListDisplayAddDataToAdapter = 200; + public static final int imageListDisplaySetResults = 201; + + public static final int activityStartProgressDialog = 300; + public static final int activityStopProgressDialog = 301; + + public static String removeFlickrApiFromJson(String _flickrResponse) { + String ret = null; + int startPosition = _flickrResponse.indexOf("{"); + int endPosition = _flickrResponse.lastIndexOf("}"); + + if(startPosition < 0 || endPosition < 0) { + } else { + ret = _flickrResponse.substring(startPosition, endPosition + 1); + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/FlickrErrorJsonData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/FlickrErrorJsonData.java new file mode 100644 index 0000000..ac9c65f --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/FlickrErrorJsonData.java @@ -0,0 +1,22 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.data_types; + +/** + * + * @author user + */ +public class FlickrErrorJsonData { + public String stat; + public int code; + public String message; + + public FlickrErrorJsonData() { + stat = ""; + code = -1; + message = ""; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/HttpResponseData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/HttpResponseData.java new file mode 100644 index 0000000..2e029fb --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/HttpResponseData.java @@ -0,0 +1,22 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.data_types; + +/** + * + * @author user + */ +public class HttpResponseData { + public int error; + public int httpResponse; + public String httpResponseBody; + + public HttpResponseData() { + error = -1; + httpResponse = 0; + httpResponseBody = ""; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/Photo.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/Photo.java new file mode 100644 index 0000000..cb0d892 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/Photo.java @@ -0,0 +1,46 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.data_types; + +/** + * + * @author user + */ +public class Photo { + public String id; + public String owner; + public String secret; + public String server; + public int farm; + public String title; + public int ispublic; + public int isfriend; + public int isfamily; + public String url_t; + public String height_t; + public String width_t; + public String url_o; + public String height_o; + public String width_o; + + public Photo() { + id = ""; + owner = ""; + secret = ""; + server = ""; + farm = -1; + title = ""; + ispublic = -1; + isfriend = -1; + isfamily = -1; + url_t = ""; + height_t = ""; + width_t = ""; + url_o = ""; + height_o = ""; + width_o = ""; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/Photos.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/Photos.java new file mode 100644 index 0000000..6906fec --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/data_types/Photos.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.data_types; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.Photo; + +/** + * + * @author user + */ +public class Photos { + public int page; + public int pages; + public int perPage; + public String total; + public Photo[] photo; + + public Photos() { + page = -1; + pages = -1; + perPage = -1; + total = "-1"; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsername.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsername.java new file mode 100644 index 0000000..8ae4fee --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsername.java @@ -0,0 +1,38 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.find_by_username; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.HttpResponseData; +/** + * + * @author user + */ +public class FindPersonByUsername { + FindPersonByUsernameHttp http; + FindPersonByUsernameParser parser; + HttpResponseData data; + + public FindPersonByUsername() { + http = new FindPersonByUsernameHttp(); + parser = new FindPersonByUsernameParser(); + } + + public FindPersonResponseData findPersonByUsername(String _username) { + FindPersonResponseData ret = new FindPersonResponseData(); + + if(!http.setUpConnection(_username)) { + } else if((data = http.getPersonByUsername()).error < 0) { + } else { + ret = parser.parseJsonIntoObject(data.httpResponseBody); + } + + return ret; + } + + public void stop() { + http.shutDownConnection(); + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsernameHttp.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsernameHttp.java new file mode 100644 index 0000000..56dd0f2 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsernameHttp.java @@ -0,0 +1,129 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.find_by_username; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; + +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.Mutex; +import com.gstv.androidcodingexercise.joel.web_api.data_types.HttpResponseData; + +/** + * + * @author user + */ +public class FindPersonByUsernameHttp { + private HttpURLConnection connection; + private final Mutex mutex; + private String username; + + public FindPersonByUsernameHttp() { + connection = null; + mutex = new Mutex(); + username = null; + } + + public boolean setUpConnection(String _username) { + boolean ret = false; + + if(!mutex.lock()) { + } else { + username = _username; + if(setUpConnectionCriticalSection()) { + ret = true; + } + mutex.unlock(); + } + + return ret; + } + + public HttpResponseData getPersonByUsername() { + HttpResponseData ret = new HttpResponseData(); + + if((ret.httpResponse = getPersonByUsernameGetResponseCode()) + != HttpURLConnection.HTTP_OK) { + } else if((ret.httpResponseBody = readResponse()) == null) { + } else { + ret.error = 0; + } + connection.disconnect(); + + return ret; + } + + public boolean shutDownConnection() { + boolean ret = false; + + if(!mutex.lock()) { + } else { + connection.disconnect(); + connection = null; + mutex.unlock(); + } + + return ret; + } + + + private boolean setUpConnectionCriticalSection() { + boolean ret = false; + + try { + URL url = new URL(getPersonByUsernameUrl()); + connection = (HttpURLConnection)url.openConnection(); + connection.setRequestMethod("GET"); + ret = true; + } catch(IOException _e) { + } + + return ret; + } + + private String getPersonByUsernameUrl() { + return Defines.flickrBaseUrl + + Defines.getPeopleByUsernameMethod + + "&api_key=" + + Defines.apiKey + + "&username=" + + username + + "&format=json"; + } + + private String readResponse() { + String ret = null; + String temp = ""; + + try { + String line; + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(connection.getInputStream())); + while((line = bufferedReader.readLine()) != null) { + temp += line; + } + bufferedReader.close(); + ret = temp; + } catch(IOException _e) { + } + + return ret; + } + + private int getPersonByUsernameGetResponseCode() { + int ret = -1; + + try { + ret = connection.getResponseCode(); + } catch(IOException _e) { + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsernameParser.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsernameParser.java new file mode 100644 index 0000000..ccc0b8a --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonByUsernameParser.java @@ -0,0 +1,61 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.find_by_username; + +import com.google.gson.Gson; +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.web_api.data_types.FlickrErrorJsonData; + +/** + * + * @author user + */ +public class FindPersonByUsernameParser { + + public FindPersonByUsernameParser() { + } + + public FindPersonResponseData parseJsonIntoObject(String _json) { + FindPersonResponseData ret = new FindPersonResponseData(); + FindPersonJsonData dataSuccess; + FlickrErrorJsonData dataError; + + String json = Defines.removeFlickrApiFromJson(_json); + if(json == null) { + } else if((dataSuccess = parseValidResponse(json)) != null + && dataSuccess.stat.compareTo("ok") == 0) { + ret.jsonData = dataSuccess; + } else if((dataError = parseErrorResponse(json)) != null) { + ret.errorData = dataError; + } + + return ret; + } + + private FindPersonJsonData parseValidResponse(String _json) { + FindPersonJsonData ret = null; + + try { + Gson gson = new Gson(); + ret = gson.fromJson(_json, FindPersonJsonData.class); + } catch(Exception _e) { + } + + return ret; + } + + private FlickrErrorJsonData parseErrorResponse(String _json) { + FlickrErrorJsonData ret = null; + + try { + Gson gson = new Gson(); + ret = gson.fromJson(_json, FlickrErrorJsonData.class); + } catch(Exception _e) { + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonJsonData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonJsonData.java new file mode 100644 index 0000000..49dec9b --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonJsonData.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.find_by_username; + +import com.google.gson.annotations.SerializedName; +/** + * + * @author user + */ +public class FindPersonJsonData { + public User user; + public String stat; + + public FindPersonJsonData() { + } + + public class User { + public String id; + public String nsid; + public Username username; + } + + public class Username { + public String _content; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonResponseData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonResponseData.java new file mode 100644 index 0000000..525b160 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/find_by_username/FindPersonResponseData.java @@ -0,0 +1,21 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.find_by_username; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.FlickrErrorJsonData; +/** + * + * @author user + */ +public class FindPersonResponseData { + public FindPersonJsonData jsonData; + public FlickrErrorJsonData errorData; + + public FindPersonResponseData() { + jsonData = null; + errorData = null; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoList.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoList.java new file mode 100644 index 0000000..a1aafff --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoList.java @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.get_user_photo_list; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.HttpResponseData; +import com.gstv.androidcodingexercise.joel.web_api.find_by_username.FindPersonByUsernameHttp; +import com.gstv.androidcodingexercise.joel.web_api.find_by_username.FindPersonByUsernameParser; +import com.gstv.androidcodingexercise.joel.web_api.find_by_username.FindPersonResponseData; + +/** + * + * @author user + */ +public class GetUserPhotoList { + GetUserPhotoListHttp http; + GetUserPhotoListParser parser; + HttpResponseData data; + + public GetUserPhotoList() { + http = new GetUserPhotoListHttp(); + parser = new GetUserPhotoListParser(); + } + + public GetUserPhotoListResponseData getUserPhotoList( + String _nsid, int _startingPageNumber) { + GetUserPhotoListResponseData ret = new GetUserPhotoListResponseData(); + + if(!http.setUpConnection(_nsid, _startingPageNumber)) { + } else if((data = http.getUserPhotos()).error < 0) { + } else { + ret = parser.parseJsonIntoObject(data.httpResponseBody); + } + + return ret; + } + + public void stop() { + + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListHttp.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListHttp.java new file mode 100644 index 0000000..bc2e404 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListHttp.java @@ -0,0 +1,138 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.get_user_photo_list; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; + +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.Mutex; +import com.gstv.androidcodingexercise.joel.web_api.data_types.HttpResponseData; + +/** + * + * @author user + */ +public class GetUserPhotoListHttp { + private HttpURLConnection connection; + private final Mutex mutex; + private String nsid; + private int startingPageNumber; + + public GetUserPhotoListHttp() { + connection = null; + mutex = new Mutex(); + nsid = null; + startingPageNumber = 1; + } + + public boolean setUpConnection(String _nsid, int _startingPageNumber) { + boolean ret = false; + + if(!mutex.lock()) { + } else { + nsid = _nsid; + startingPageNumber = _startingPageNumber; + if(setUpConnectionCriticalSection()) { + ret = true; + } + mutex.unlock(); + } + + return ret; + } + + public HttpResponseData getUserPhotos() { + HttpResponseData ret = new HttpResponseData(); + + if((ret.httpResponse = getUserPhotosGetResponseCode()) + != HttpURLConnection.HTTP_OK) { + } else if((ret.httpResponseBody = readResponse()) == null) { + } else { + ret.error = 0; + } + connection.disconnect(); + + return ret; + } + + public boolean shutDownConnection() { + boolean ret = false; + + if(!mutex.lock()) { + } else { + connection.disconnect(); + connection = null; + mutex.unlock(); + } + + return ret; + } + + + private boolean setUpConnectionCriticalSection() { + boolean ret = false; + + try { +System.out.println("url : ||" + getUserPhotosByUsernameUrl() + "||"); + URL url = new URL(getUserPhotosByUsernameUrl()); + connection = (HttpURLConnection)url.openConnection(); + connection.setRequestMethod("GET"); + ret = true; + } catch(IOException _e) { + } + + return ret; + } + + // this url gets the thumbnail url + // and original size photo url so we can use them + private String getUserPhotosByUsernameUrl() { + return Defines.flickrBaseUrl + + Defines.getUserPhotoListMethod + + "&api_key=" + + Defines.apiKey + + "&user_id=" + + nsid + + "&page=" + + startingPageNumber + + "&extras=url_t,url_o" + + "&format=json"; + } + + private String readResponse() { + String ret = null; + String temp = ""; + + try { + String line; + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(connection.getInputStream())); + while((line = bufferedReader.readLine()) != null) { + temp += line; + } + bufferedReader.close(); + ret = temp; + } catch(IOException _e) { + } + + return ret; + } + + private int getUserPhotosGetResponseCode() { + int ret = -1; + + try { + ret = connection.getResponseCode(); + } catch(IOException _e) { + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListJsonData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListJsonData.java new file mode 100644 index 0000000..9d2a1d9 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListJsonData.java @@ -0,0 +1,19 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.get_user_photo_list; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.Photos; +/** + * + * @author user + */ +public class GetUserPhotoListJsonData { + public Photos photos; + public String stat; + + public GetUserPhotoListJsonData() { + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListParser.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListParser.java new file mode 100644 index 0000000..5ac4897 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListParser.java @@ -0,0 +1,60 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.get_user_photo_list; + +import com.google.gson.Gson; +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.web_api.data_types.FlickrErrorJsonData; +/** + * + * @author user + */ +public class GetUserPhotoListParser { + + public GetUserPhotoListParser() { + } + + public GetUserPhotoListResponseData parseJsonIntoObject(String _json) { + GetUserPhotoListResponseData ret = new GetUserPhotoListResponseData(); + GetUserPhotoListJsonData dataSuccess; + FlickrErrorJsonData dataError; + + String json = Defines.removeFlickrApiFromJson(_json); + if(json == null) { + } else if((dataSuccess = parseValidResponse(json)) != null + && dataSuccess.stat.compareTo("ok") == 0) { + ret.dataSuccess = dataSuccess; + } else if((dataError = parseErrorResponse(json)) != null) { + ret.dataError = dataError; + } + + return ret; + } + + private GetUserPhotoListJsonData parseValidResponse(String _json) { + GetUserPhotoListJsonData ret = null; + + try { + Gson gson = new Gson(); + ret = gson.fromJson(_json, GetUserPhotoListJsonData.class); + } catch(Exception _e) { + } + + return ret; + } + + private FlickrErrorJsonData parseErrorResponse(String _json) { + FlickrErrorJsonData ret = null; + + try { + Gson gson = new Gson(); + ret = gson.fromJson(_json, FlickrErrorJsonData.class); + } catch(Exception _e) { + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListResponseData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListResponseData.java new file mode 100644 index 0000000..5dae6b6 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/get_user_photo_list/GetUserPhotoListResponseData.java @@ -0,0 +1,21 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.get_user_photo_list; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.FlickrErrorJsonData; +/** + * + * @author user + */ +public class GetUserPhotoListResponseData { + public GetUserPhotoListJsonData dataSuccess; + public FlickrErrorJsonData dataError; + + public GetUserPhotoListResponseData() { + dataSuccess = null; + dataError = null; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywords.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywords.java new file mode 100644 index 0000000..2fa02bb --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywords.java @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.HttpResponseData; +import com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords.SearchPhotosByKeywordsHttp; +import com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords.SearchPhotosByKeywordsParser; +import com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords.SearchPhotosByKeywordsResponseData; + +/** + * + * @author user + */ +public class SearchPhotosByKeywords { + SearchPhotosByKeywordsHttp http; + SearchPhotosByKeywordsParser parser; + HttpResponseData data; + + public SearchPhotosByKeywords() { + http = new SearchPhotosByKeywordsHttp(); + parser = new SearchPhotosByKeywordsParser(); + } + + public SearchPhotosByKeywordsResponseData getUserPhotoList( + String _apiKey, String _nsid, String _keywords) { + SearchPhotosByKeywordsResponseData ret = new SearchPhotosByKeywordsResponseData(); + + if(!http.setUpConnection(_apiKey, _nsid, _keywords)) { + } else if((data = http.searchForPhotos()).error < 0) { + } else { + ret = parser.parseJsonIntoObject(data.httpResponseBody); + } + + return ret; + } + + public void stop() { + http.shutDownConnection(); + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsHttp.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsHttp.java new file mode 100644 index 0000000..d672569 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsHttp.java @@ -0,0 +1,139 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import com.gstv.androidcodingexercise.joel.Mutex; +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.web_api.data_types.HttpResponseData; + +/** + * + * @author user + */ +public class SearchPhotosByKeywordsHttp { + private HttpURLConnection connection; + private final Mutex mutex; + private String apiKey; + private String nsid; + private String keywords; + + public SearchPhotosByKeywordsHttp() { + connection = null; + mutex = new Mutex(); + apiKey = null; + nsid = null; + keywords = null; + } + + public boolean setUpConnection(String _apiKey, String _nsid, String _keywords) { + boolean ret = false; + + if(!mutex.lock()) { + } else { + apiKey = _apiKey; + nsid = _nsid; + keywords = _keywords; + if(setUpConnectionCriticalSection()) { + ret = true; + } + mutex.unlock(); + } + + return ret; + } + + public HttpResponseData searchForPhotos() { + HttpResponseData ret = new HttpResponseData(); + + if((ret.httpResponse = getUserPhotosGetResponseCode()) + != HttpURLConnection.HTTP_OK) { + } else if((ret.httpResponseBody = readResponse()) == null) { + } else { + ret.error = 0; + } + connection.disconnect(); + + return ret; + } + + public boolean shutDownConnection() { + boolean ret = false; + + if(!mutex.lock()) { + } else { + connection.disconnect(); + connection = null; + mutex.unlock(); + } + + return ret; + } + + + private boolean setUpConnectionCriticalSection() { + boolean ret = false; +System.out.println("url : ||" + getSearchPhotosByKeywordsUrl() + "||"); + try { + URL url = new URL(getSearchPhotosByKeywordsUrl()); + connection = (HttpURLConnection)url.openConnection(); + connection.setRequestMethod("GET"); + ret = true; + } catch(IOException _e) { + } + + return ret; + } + + // this url gets the thumbnail url + // and original size photo url so we can use them + private String getSearchPhotosByKeywordsUrl() { + return Defines.flickrBaseUrl + + Defines.getPhotosByKeywordMethod + + "&api_key=" + + apiKey + + "&user_id=" + + nsid + + "&text=" + + keywords + + "&extras=url_t,url_o" + + "&format=json"; + } + + private String readResponse() { + String ret = null; + String temp = ""; + + try { + String line; + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(connection.getInputStream())); + while((line = bufferedReader.readLine()) != null) { + temp += line; + } + bufferedReader.close(); + ret = temp; + } catch(IOException _e) { + } + + return ret; + } + + private int getUserPhotosGetResponseCode() { + int ret = -1; + + try { + ret = connection.getResponseCode(); + } catch(IOException _e) { + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsJsonData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsJsonData.java new file mode 100644 index 0000000..f43ea90 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsJsonData.java @@ -0,0 +1,19 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.Photos; +/** + * + * @author user + */ +public class SearchPhotosByKeywordsJsonData { + public Photos photos; + public String stat; + + public SearchPhotosByKeywordsJsonData() { + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsParser.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsParser.java new file mode 100644 index 0000000..cf713d2 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsParser.java @@ -0,0 +1,61 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords; + +import com.google.gson.Gson; +import com.gstv.androidcodingexercise.joel.web_api.Defines; +import com.gstv.androidcodingexercise.joel.web_api.data_types.FlickrErrorJsonData; + +/** + * + * @author user + */ +public class SearchPhotosByKeywordsParser { + + public SearchPhotosByKeywordsParser() { + } + + public SearchPhotosByKeywordsResponseData parseJsonIntoObject(String _json) { + SearchPhotosByKeywordsResponseData ret = new SearchPhotosByKeywordsResponseData(); + SearchPhotosByKeywordsJsonData dataSuccess; + FlickrErrorJsonData dataError; + + String json = Defines.removeFlickrApiFromJson(_json); + if(json == null) { + } else if((dataSuccess = parseValidResponse(json)) != null + && dataSuccess.stat.compareTo("ok") == 0) { + ret.dataSuccess = dataSuccess; + } else if((dataError = parseErrorResponse(json)) != null) { + ret.dataError = dataError; + } + + return ret; + } + + private SearchPhotosByKeywordsJsonData parseValidResponse(String _json) { + SearchPhotosByKeywordsJsonData ret = null; + + try { + Gson gson = new Gson(); + ret = gson.fromJson(_json, SearchPhotosByKeywordsJsonData.class); + } catch(Exception _e) { + } + + return ret; + } + + private FlickrErrorJsonData parseErrorResponse(String _json) { + FlickrErrorJsonData ret = null; + + try { + Gson gson = new Gson(); + ret = gson.fromJson(_json, FlickrErrorJsonData.class); + } catch(Exception _e) { + } + + return ret; + } +} diff --git a/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsResponseData.java b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsResponseData.java new file mode 100644 index 0000000..17e1051 --- /dev/null +++ b/app/src/main/java/com/gstv/androidcodingexercise/joel/web_api/search_photos_by_keywords/SearchPhotosByKeywordsResponseData.java @@ -0,0 +1,22 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.gstv.androidcodingexercise.joel.web_api.search_photos_by_keywords; + +import com.gstv.androidcodingexercise.joel.web_api.data_types.FlickrErrorJsonData; + +/** + * + * @author user + */ +public class SearchPhotosByKeywordsResponseData { + public SearchPhotosByKeywordsJsonData dataSuccess; + public FlickrErrorJsonData dataError; + + public SearchPhotosByKeywordsResponseData() { + dataSuccess = null; + dataError = null; + } +} diff --git a/app/src/main/res/layout/activity_full_size_image_display.xml b/app/src/main/res/layout/activity_full_size_image_display.xml new file mode 100644 index 0000000..dbf8860 --- /dev/null +++ b/app/src/main/res/layout/activity_full_size_image_display.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/app/src/main/res/layout/joel_activity_image_display.xml b/app/src/main/res/layout/joel_activity_image_display.xml new file mode 100644 index 0000000..aac63eb --- /dev/null +++ b/app/src/main/res/layout/joel_activity_image_display.xml @@ -0,0 +1,40 @@ + + + + +