├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── InstagramPhotoPicker-Android.iml ├── InstagramPhotoPicker.iml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── ly │ │ └── kite │ │ └── sample │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── ly │ │ └── kite │ │ └── sample │ │ └── MainActivity.java │ └── res │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── instagramphotopicker ├── .gitignore ├── InstagramPhotoPicker-Android.iml ├── InstagramPhotoPicker.iml ├── build.gradle ├── gradle.properties ├── instagramphotopicker.iml ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── ly │ │ └── kite │ │ └── instagramphotopicker │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── ly │ │ └── kite │ │ └── instagramphotopicker │ │ ├── InstagramGalleryActivity.java │ │ ├── InstagramLoginActivity.java │ │ ├── InstagramMediaRequest.java │ │ ├── InstagramPhoto.java │ │ ├── InstagramPhotoPicker.java │ │ ├── InstagramPhotoPickerException.java │ │ ├── LoadingView.java │ │ ├── PagingBaseAdapter.java │ │ ├── PagingGridView.java │ │ └── SquareImageView.java │ └── res │ ├── drawable-hdpi │ ├── ic_arrow_back.png │ ├── ic_close_black_24dp.png │ ├── ic_done_black_24dp.png │ └── ic_more_vert_black_24dp.png │ ├── drawable-mdpi │ ├── ic_arrow_back.png │ ├── ic_close_black_24dp.png │ ├── ic_done_black_24dp.png │ └── ic_more_vert_black_24dp.png │ ├── drawable-xhdpi │ ├── ic_arrow_back.png │ ├── ic_close_black_24dp.png │ ├── ic_done_black_24dp.png │ └── ic_more_vert_black_24dp.png │ ├── drawable-xxhdpi │ ├── checkbox_off.png │ ├── checkbox_on.png │ ├── ic_arrow_back.png │ ├── ic_close_black_24dp.png │ ├── ic_done_black_24dp.png │ └── ic_more_vert_black_24dp.png │ ├── drawable-xxxhdpi │ ├── ic_close_black_24dp.png │ ├── ic_done_black_24dp.png │ └── ic_more_vert_black_24dp.png │ ├── layout │ ├── activity_instagram_gallery.xml │ ├── activity_instagram_login.xml │ ├── colours.xml │ ├── loading_view.xml │ └── photo_cell.xml │ ├── menu │ ├── menu_instagram_gallery.xml │ ├── menu_instagram_login.xml │ └── photo_selection_menu.xml │ ├── values-da │ └── strings.xml │ ├── values-de │ └── strings.xml │ ├── values-es │ └── strings.xml │ ├── values-fr │ └── strings.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colours.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── preview.gif ├── screenshot.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | 8 | # Built application files 9 | *.apk 10 | *.ap_ 11 | 12 | # Files for the Dalvik VM 13 | *.dex 14 | 15 | # Java class files 16 | *.class 17 | 18 | # Generated files 19 | bin/ 20 | gen/ 21 | 22 | # Gradle files 23 | .gradle/ 24 | build/ 25 | 26 | # Local configuration file (sdk path, etc) 27 | local.properties 28 | 29 | # Proguard folder generated by Eclipse 30 | proguard/ 31 | 32 | # Log Files 33 | *.log 34 | 35 | # Android Studio Navigation editor temp files 36 | .navigation/ 37 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | InstagramPhotoPicker-Android -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /InstagramPhotoPicker-Android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /InstagramPhotoPicker.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2010-2015 Kite Tech Ltd. https://www.kite.ly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Instagram Photo Picker 2 | 3 | A Instagram image picker providing a simple UI for a user to pick photos from their Instagram account. 4 | 5 | It takes care of all authentication with Instagram as and when necessary. It will automatically renew auth tokens or prompt the user to re-authorize the app if needed. 6 | 7 | ## Video Preview 8 | 9 | [![Preview](https://github.com/OceanLabs/InstagramPhotoPicker-Android/raw/master/screenshot.png)](https://vimeo.com/135676657) 10 | 11 | 12 | ## Requirements 13 | 14 | * Android API Level 14 - Android 4.0 (ICE_CREAM_SANDWICH) 15 | 16 | ## Installation 17 | ### Android Studio / Gradle 18 | 19 | We publish builds of our library to the Maven central repository as an .aar file. This file contains all of the classes, resources, and configurations that you'll need to use the library. To install the library inside Android Studio, you can simply declare it as dependecy in your build.gradle file. 20 | 21 | ```java 22 | dependencies { 23 | compile 'ly.kite:instagram-photo-picker:1.+' 24 | } 25 | ``` 26 | 27 | Once you've updated your build.gradle file, you can force Android Studio to sync with your new configuration by selecting Tools -> Android -> Sync Project with Gradle Files 28 | 29 | This should download the aar dependency at which point you'll have access to the API calls. If it cannot find the dependency, you should make sure you've specified mavenCentral() as a repository in your build.gradle 30 | 31 | ## Usage 32 | 33 | You need to have set up your application correctly to work with Instagram by registering a new Instagram application here: https://instagram.com/developer/ . For the redirect uri use something link `your-app-scheme://instagram-callback`. 34 | 35 | To launch the Instagram Photo Picker: 36 | 37 | ```java 38 | // Somewhere in an Activity: 39 | 40 | import ly.kite.instagramphotopicker.InstagramPhoto; 41 | import ly.kite.instagramphotopicker.InstagramPhotoPicker; 42 | 43 | static final String CLIENT_ID = "YOUR_CLIENT_ID"; 44 | static final String REDIRECT_URI = "YOUR-APP-SCHEME://instagram-callback"; 45 | static final int REQUEST_CODE_INSTAGRAM_PICKER = 1; 46 | 47 | InstagramPhotoPicker.startPhotoPickerForResult(this, CLIENT_ID, REDIRECT_URI, REQUEST_CODE_INSTAGRAM_PICKER); 48 | ``` 49 | 50 | Implement `onActivityResult`: 51 | 52 | ```java 53 | 54 | @Override 55 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 56 | if (requestCode == REQUEST_CODE_INSTAGRAM_PICKER) { 57 | if (resultCode == Activity.RESULT_OK) { 58 | InstagramPhoto[] instagramPhotos = InstagramPhotoPicker.getResultPhotos(data); 59 | Log.i("dbotha", "User selected " + instagramPhotos.length + " Instagram photos"); 60 | for (int i = 0; i < instagramPhotos.length; ++i) { 61 | Log.i("dbotha", "Photo: " + instagramPhotos[i].getFullURL()); 62 | } 63 | 64 | } 65 | } 66 | } 67 | 68 | ``` 69 | 70 | ### Sample Apps 71 | The project is bundled with a Sample App to highlight the libraries usage. 72 | 73 | ## License 74 | This project is available under the MIT license. See the [LICENSE](LICENSE) file for more info. 75 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.2" 6 | 7 | defaultConfig { 8 | applicationId "ly.kite.instagramphotopicker" 9 | minSdkVersion 14 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:24.2.1' 25 | compile project(':instagramphotopicker') 26 | } 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/deon/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/ly/kite/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package ly.kite.sample; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/ly/kite/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package ly.kite.sample; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Parcelable; 6 | import android.support.v7.app.ActionBarActivity; 7 | import android.os.Bundle; 8 | import android.util.Log; 9 | import android.view.View; 10 | import android.widget.Toast; 11 | 12 | import ly.kite.instagramphotopicker.InstagramPhoto; 13 | import ly.kite.instagramphotopicker.InstagramPhotoPicker; 14 | 15 | 16 | public class MainActivity extends ActionBarActivity { 17 | 18 | private static final String CLIENT_ID = "aa314a392fdd4de7aa287a6614ea8897"; 19 | //private static final String REDIRECT_URI = "psapp://instagram-callback"; 20 | private static final String REDIRECT_URI = "http://instagram-callback"; 21 | private static final int REQUEST_CODE_INSTAGRAM_PICKER = 88; 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_main); 27 | } 28 | 29 | public void onButtonLaunchInstagramPickerClicked(View view) { 30 | InstagramPhotoPicker.startPhotoPickerForResult(this, CLIENT_ID, REDIRECT_URI, REQUEST_CODE_INSTAGRAM_PICKER); 31 | } 32 | 33 | @Override 34 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 35 | if (requestCode == REQUEST_CODE_INSTAGRAM_PICKER) { 36 | if (resultCode == Activity.RESULT_OK) { 37 | InstagramPhoto[] instagramPhotos = InstagramPhotoPicker.getResultPhotos(data); 38 | Toast.makeText(this, "User selected " + instagramPhotos.length + " Instagram photos", Toast.LENGTH_SHORT).show(); 39 | for (int i = 0; i < instagramPhotos.length; ++i) { 40 | Log.i("dbotha", "Photo: " + instagramPhotos[i].getFullURL()); 41 | } 42 | 43 | } else if (resultCode == Activity.RESULT_CANCELED) { 44 | Toast.makeText(this, "Instagram Picking Cancelled", Toast.LENGTH_SHORT).show(); 45 | } else { 46 | Log.i("dbotha", "Unknown result code: " + resultCode); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 |