├── .gitignore ├── .travis.yml ├── README.md ├── app ├── build.gradle ├── libs │ └── universal-image-loader-1.8.4.jar └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── codepath │ │ └── apps │ │ └── restclienttemplate │ │ ├── FlickrClient.java │ │ ├── FlickrClientApp.java │ │ ├── LoginActivity.java │ │ ├── MyDatabase.java │ │ ├── PhotoArrayAdapter.java │ │ ├── PhotosActivity.java │ │ └── models │ │ └── FlickrPhoto.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ ├── activity_login.xml │ ├── activity_photos.xml │ └── photo_item.xml │ ├── menu │ ├── login.xml │ └── photos.xml │ ├── values-sw600dp │ └── dimens.xml │ ├── values-sw720dp-land │ └── dimens.xml │ ├── values-v11 │ └── styles.xml │ ├── values-v14 │ └── styles.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Source: https://gist.github.com/nesquena/5617544/raw/53710b374e7df3302df43b552488d876040ada3d/.gitignore 2 | 3 | # built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # files for the dex VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # generated files 14 | bin/ 15 | gen/ 16 | 17 | # Local configuration file (sdk path, etc) 18 | local.properties 19 | 20 | # Eclipse project files 21 | .classpath 22 | .project 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | 27 | # Intellij project files 28 | *.iml 29 | *.ipr 30 | *.iws 31 | .idea/ 32 | 33 | *.pydevproject 34 | .project 35 | .metadata 36 | bin/** 37 | tmp/** 38 | tmp/**/* 39 | *.tmp 40 | *.bak 41 | *.swp 42 | *~.nib 43 | local.properties 44 | .classpath 45 | .settings/ 46 | .loadpath 47 | 48 | # External tool builders 49 | .externalToolBuilders/ 50 | 51 | # Locally stored "Eclipse launch configurations" 52 | *.launch 53 | 54 | # CDT-specific 55 | .cproject 56 | 57 | # PDT-specific 58 | .buildpath 59 | 60 | # Android Studio project files 61 | *.iml 62 | .gradle 63 | .idea 64 | build 65 | import-summary.txt 66 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: 3 | - oraclejdk8 4 | sudo: false 5 | android: 6 | components: 7 | - tools 8 | - platform-tools 9 | - build-tools-24.0.0 10 | - android-23 11 | - extra-android-m2repository 12 | - extra-google-m2repository 13 | licenses: 14 | - android-sdk-license-.+ 15 | script: 16 | - "./gradlew build check --daemon" 17 | after_failure: "cat $TRAVIS_BUILD_DIR/app/build/outputs/lint-results-debug.xml" 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | android-oauth-flicker-demo 2 | ========================== 3 | 4 | Android App Using [RestClientTemplate](https://github.com/codepath/android-rest-client-template) for Flickr 5 | 6 | Flickr 7 | 8 | ## Setup 9 | 10 | 1. To get an Flickr API key, visit [https://www.flickr.com/services/apps/create/apply/](https://www.flickr.com/services/apps/create/apply/). 11 | 12 | 13 | 14 | 2. Click on Apply for Non-Commercial Key. 15 | 16 | 3. Fill out a name and description of the app. Make sure to accept terms of use and click Submit. 17 | 18 | 4. You should see `Done! Here's the API key and secret for your new app:`. 19 | * Set the key value to be the `REST_CONSUMER_KEY`. 20 | * Set the secret value to be the `REST_CONSUMER_SECRET`. 21 | 22 | Check the [source files in this repo](https://github.com/codepath/android-oauth-flickr-demo/tree/master/app/src/main/java/com/codepath/apps/restclienttemplate) for a simple example of how to build an authenticated client. 23 | 24 | You can review a detailed guide for using the RestClientTemplate to build OAuth based REST applications in the [android-rest-client-template README](https://github.com/codepath/android-rest-client-template/blob/master/README.md). 25 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.codepath.apps.restclienttemplate" 9 | minSdkVersion 10 10 | targetSdkVersion 23 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 17 | } 18 | } 19 | } 20 | 21 | def dbflow_version = "3.1.1" 22 | apply plugin: 'com.neenbedankt.android-apt' 23 | 24 | dependencies { 25 | compile 'com.android.support:appcompat-v7:23.2.0' 26 | compile 'com.codepath.libraries:android-oauth-handler:1.1.0' 27 | compile files('libs/universal-image-loader-1.8.4.jar') 28 | apt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}" 29 | compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}" 30 | compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}" 31 | } 32 | -------------------------------------------------------------------------------- /app/libs/universal-image-loader-1.8.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-oauth-flickr-demo/024a3df0ebd6cd0109393c68ca306dc17c0f1761/app/libs/universal-image-loader-1.8.4.jar -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/apps/restclienttemplate/FlickrClient.java: -------------------------------------------------------------------------------- 1 | package com.codepath.apps.restclienttemplate; 2 | 3 | import com.codepath.oauth.OAuthBaseClient; 4 | import com.loopj.android.http.AsyncHttpResponseHandler; 5 | 6 | import org.scribe.builder.api.Api; 7 | import org.scribe.builder.api.FlickrApi; 8 | 9 | import android.content.Context; 10 | import android.util.Log; 11 | 12 | public class FlickrClient extends OAuthBaseClient { 13 | 14 | public static final Class REST_API_CLASS = FlickrApi.class; 15 | 16 | public static final String REST_URL = "https://www.flickr.com/services"; 17 | 18 | public static final String REST_CONSUMER_KEY = "57ac210e2e82195e071f9a761d763ca0"; 19 | 20 | public static final String REST_CONSUMER_SECRET = "7d359e4f4149545b"; 21 | 22 | public static final String REST_CALLBACK_URL = "oauth://cprest"; 23 | 24 | public FlickrClient(Context context) { 25 | super(context, REST_API_CLASS, REST_URL, REST_CONSUMER_KEY, REST_CONSUMER_SECRET, 26 | REST_CALLBACK_URL); 27 | setBaseUrl("https://api.flickr.com/services/rest"); 28 | } 29 | 30 | public void getInterestingnessList(AsyncHttpResponseHandler handler) { 31 | String apiUrl = getApiUrl("?format=json&nojsoncallback=1&method=flickr.interestingness.getList"); 32 | Log.d("DEBUG", "Sending API call to " + apiUrl); 33 | client.get(apiUrl, null, handler); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/apps/restclienttemplate/FlickrClientApp.java: -------------------------------------------------------------------------------- 1 | package com.codepath.apps.restclienttemplate; 2 | 3 | import com.nostra13.universalimageloader.core.DisplayImageOptions; 4 | import com.nostra13.universalimageloader.core.ImageLoader; 5 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; 6 | import com.raizlabs.android.dbflow.config.FlowConfig; 7 | import com.raizlabs.android.dbflow.config.FlowLog; 8 | import com.raizlabs.android.dbflow.config.FlowManager; 9 | 10 | import android.app.Application; 11 | import android.content.Context; 12 | 13 | public class FlickrClientApp extends Application { 14 | private static Context context; 15 | 16 | @Override 17 | public void onCreate() { 18 | super.onCreate(); 19 | FlickrClientApp.context = this; 20 | 21 | FlowManager.init(new FlowConfig.Builder(this).build()); 22 | FlowLog.setMinimumLoggingLevel(FlowLog.Level.V); 23 | 24 | // Create global configuration and initialize ImageLoader with this configuration 25 | DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder(). 26 | cacheInMemory().cacheOnDisc().build(); 27 | ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()) 28 | .defaultDisplayImageOptions(defaultOptions) 29 | .build(); 30 | ImageLoader.getInstance().init(config); 31 | } 32 | 33 | public static FlickrClient getRestClient() { 34 | return (FlickrClient) FlickrClient.getInstance(FlickrClient.class, FlickrClientApp.context); 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/apps/restclienttemplate/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package com.codepath.apps.restclienttemplate; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.view.Menu; 6 | import android.view.View; 7 | 8 | import com.codepath.oauth.OAuthLoginActivity; 9 | 10 | public class LoginActivity extends OAuthLoginActivity { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_login); 16 | } 17 | 18 | @Override 19 | public boolean onCreateOptionsMenu(Menu menu) { 20 | // Inflate the menu; this adds items to the action bar if it is present. 21 | getMenuInflater().inflate(R.menu.login, menu); 22 | return true; 23 | } 24 | 25 | @Override 26 | public void onLoginSuccess() { 27 | Intent i = new Intent(this, PhotosActivity.class); 28 | startActivity(i); 29 | } 30 | 31 | @Override 32 | public void onLoginFailure(Exception e) { 33 | e.printStackTrace(); 34 | } 35 | 36 | public void loginToRest(View view) { 37 | getClient().connect(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/apps/restclienttemplate/MyDatabase.java: -------------------------------------------------------------------------------- 1 | package com.codepath.apps.restclienttemplate; 2 | 3 | import com.raizlabs.android.dbflow.annotation.Database; 4 | 5 | @Database(name = MyDatabase.NAME, version = MyDatabase.VERSION) 6 | public class MyDatabase { 7 | 8 | public static final String NAME = "RestClientDatabase"; 9 | 10 | public static final int VERSION = 1; 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/apps/restclienttemplate/PhotoArrayAdapter.java: -------------------------------------------------------------------------------- 1 | package com.codepath.apps.restclienttemplate; 2 | 3 | import java.util.List; 4 | 5 | import com.codepath.apps.restclienttemplate.models.FlickrPhoto; 6 | import com.nostra13.universalimageloader.core.ImageLoader; 7 | 8 | import android.content.Context; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.ArrayAdapter; 13 | import android.widget.ImageView; 14 | import android.widget.LinearLayout; 15 | 16 | public class PhotoArrayAdapter extends ArrayAdapter { 17 | public PhotoArrayAdapter(Context context, List photoList) { 18 | super(context, R.layout.photo_item, photoList); 19 | } 20 | 21 | @Override 22 | public View getView(int position, View convertView, ViewGroup parent) { 23 | FlickrPhoto photo = this.getItem(position); 24 | LinearLayout itemView; 25 | ImageView ivImage; 26 | ImageLoader imageLoader = ImageLoader.getInstance(); 27 | if (convertView == null) { 28 | LayoutInflater inflator = LayoutInflater.from(getContext()); 29 | itemView = (LinearLayout) inflator.inflate(R.layout.photo_item, parent, false); 30 | } else { 31 | itemView = (LinearLayout) convertView; 32 | } 33 | ivImage = (ImageView) itemView.findViewById(R.id.ivPhoto); 34 | ivImage.setImageResource(android.R.color.transparent); 35 | imageLoader.displayImage(photo.getUrl(), ivImage); 36 | return itemView; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/apps/restclienttemplate/PhotosActivity.java: -------------------------------------------------------------------------------- 1 | package com.codepath.apps.restclienttemplate; 2 | 3 | import com.codepath.apps.restclienttemplate.models.FlickrPhoto; 4 | import com.loopj.android.http.JsonHttpResponseHandler; 5 | 6 | import org.json.JSONArray; 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | 10 | import android.app.Activity; 11 | import android.os.Bundle; 12 | import android.util.Log; 13 | import android.view.Menu; 14 | import android.widget.GridView; 15 | 16 | import java.util.ArrayList; 17 | 18 | import cz.msebera.android.httpclient.Header; 19 | 20 | public class PhotosActivity extends Activity { 21 | 22 | FlickrClient client; 23 | 24 | ArrayList photoItems; 25 | 26 | GridView gvPhotos; 27 | 28 | PhotoArrayAdapter adapter; 29 | 30 | @Override 31 | protected void onCreate(Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | setContentView(R.layout.activity_photos); 34 | client = FlickrClientApp.getRestClient(); 35 | photoItems = new ArrayList(); 36 | gvPhotos = (GridView) findViewById(R.id.gvPhotos); 37 | adapter = new PhotoArrayAdapter(this, photoItems); 38 | gvPhotos.setAdapter(adapter); 39 | loadPhotos(); 40 | } 41 | 42 | @Override 43 | public boolean onCreateOptionsMenu(Menu menu) { 44 | // Inflate the menu; this adds items to the action bar if it is present. 45 | getMenuInflater().inflate(R.menu.photos, menu); 46 | return true; 47 | } 48 | 49 | public void loadPhotos() { 50 | client.getInterestingnessList(new JsonHttpResponseHandler() { 51 | @Override 52 | public void onSuccess(int statusCode, Header[] headers, 53 | JSONObject json) { 54 | Log.d("DEBUG", "result: " + json.toString()); 55 | // Add new photos to SQLite 56 | try { 57 | JSONArray photos = json.getJSONObject("photos").getJSONArray("photo"); 58 | for (int x = 0; x < photos.length(); x++) { 59 | String uid = photos.getJSONObject(x).getString("id"); 60 | FlickrPhoto p = FlickrPhoto.byPhotoUid(uid); 61 | if (p == null) { 62 | p = new FlickrPhoto(photos.getJSONObject(x)); 63 | } 64 | 65 | p.save(); 66 | } 67 | } catch (JSONException e) { 68 | e.printStackTrace(); 69 | Log.e("debug", e.toString()); 70 | } 71 | 72 | // Load into GridView from DB 73 | for (FlickrPhoto p : FlickrPhoto.recentItems()) { 74 | adapter.add(p); 75 | } 76 | Log.d("DEBUG", "Total: " + photoItems.size()); 77 | } 78 | }); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/apps/restclienttemplate/models/FlickrPhoto.java: -------------------------------------------------------------------------------- 1 | package com.codepath.apps.restclienttemplate.models; 2 | 3 | import com.codepath.apps.restclienttemplate.MyDatabase; 4 | import com.raizlabs.android.dbflow.annotation.Column; 5 | import com.raizlabs.android.dbflow.annotation.PrimaryKey; 6 | import com.raizlabs.android.dbflow.annotation.Table; 7 | import com.raizlabs.android.dbflow.sql.language.Select; 8 | import com.raizlabs.android.dbflow.structure.BaseModel; 9 | 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | import java.util.List; 14 | 15 | @Table(database = MyDatabase.class) 16 | public class FlickrPhoto extends BaseModel { 17 | 18 | @PrimaryKey 19 | @Column(name = "uid") 20 | private String uid; 21 | 22 | @Column(name = "name") 23 | private String name; 24 | 25 | @Column(name = "url") 26 | private String url; 27 | 28 | public FlickrPhoto() { 29 | super(); 30 | } 31 | 32 | public FlickrPhoto(JSONObject object) { 33 | super(); 34 | 35 | try { 36 | this.uid = object.getString("id"); 37 | this.name = object.getString("title"); 38 | // http://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}.jpg 39 | this.url = "http://farm" + object.getInt("farm") + ".staticflickr.com/" + object 40 | .getInt("server") + 41 | "/" + uid + "_" + object.getString("secret") + ".jpg"; 42 | } catch (JSONException e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | 47 | public static FlickrPhoto byPhotoUid(String uid) { 48 | return new Select().from(FlickrPhoto.class).where(FlickrPhoto_Table.uid.eq(uid)) 49 | .querySingle(); 50 | } 51 | 52 | public static List recentItems() { 53 | return new Select().from(FlickrPhoto.class).orderBy(FlickrPhoto_Table.uid, false) 54 | .limit(300).queryList(); 55 | } 56 | 57 | public String getUid() { 58 | return uid; 59 | } 60 | 61 | public String getUrl() { 62 | return url; 63 | } 64 | 65 | public String getName() { 66 | return name; 67 | } 68 | 69 | public void setUid(String uid) { 70 | this.uid = uid; 71 | } 72 | 73 | public void setName(String name) { 74 | this.name = name; 75 | } 76 | 77 | public void setUrl(String url) { 78 | this.url = url; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-oauth-flickr-demo/024a3df0ebd6cd0109393c68ca306dc17c0f1761/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-oauth-flickr-demo/024a3df0ebd6cd0109393c68ca306dc17c0f1761/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-oauth-flickr-demo/024a3df0ebd6cd0109393c68ca306dc17c0f1761/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-oauth-flickr-demo/024a3df0ebd6cd0109393c68ca306dc17c0f1761/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 |