├── .idea
├── gradle.xml
├── libraries
│ ├── android_arch_core_common_1_0_0_jar.xml
│ ├── android_arch_lifecycle_common_1_0_3_jar.xml
│ ├── android_arch_lifecycle_runtime_1_0_3.xml
│ ├── com_android_databinding_adapters_1_3_1.xml
│ ├── com_android_databinding_baseLibrary_3_0_1_jar.xml
│ ├── com_android_databinding_library_1_3_1.xml
│ ├── com_android_support_animated_vector_drawable_27_0_2.xml
│ ├── com_android_support_appcompat_v7_27_0_2.xml
│ ├── com_android_support_design_27_0_2.xml
│ ├── com_android_support_exifinterface_27_0_2.xml
│ ├── com_android_support_recyclerview_v7_27_0_2.xml
│ ├── com_android_support_support_annotations_27_0_2_jar.xml
│ ├── com_android_support_support_compat_27_0_2.xml
│ ├── com_android_support_support_core_ui_27_0_2.xml
│ ├── com_android_support_support_core_utils_27_0_2.xml
│ ├── com_android_support_support_fragment_27_0_2.xml
│ ├── com_android_support_support_media_compat_27_0_2.xml
│ ├── com_android_support_support_v4_27_0_2.xml
│ ├── com_android_support_support_vector_drawable_27_0_2.xml
│ ├── com_android_support_test_espresso_espresso_core_2_2_2.xml
│ ├── com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml
│ ├── com_android_support_test_exposed_instrumentation_api_publish_0_5.xml
│ ├── com_android_support_test_rules_0_5.xml
│ ├── com_android_support_test_runner_0_5.xml
│ ├── com_android_support_transition_27_0_2.xml
│ ├── com_google_code_findbugs_jsr305_2_0_1_jar.xml
│ ├── com_squareup_javawriter_2_1_1_jar.xml
│ ├── com_theartofdev_edmodo_android_image_cropper_2_6_0.xml
│ ├── javax_annotation_javax_annotation_api_1_2_jar.xml
│ ├── javax_inject_javax_inject_1_jar.xml
│ ├── junit_junit_4_12_jar.xml
│ ├── org_hamcrest_hamcrest_core_1_3_jar.xml
│ ├── org_hamcrest_hamcrest_integration_1_3_jar.xml
│ └── org_hamcrest_hamcrest_library_1_3_jar.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── SmartImagePicker.iml
├── app
├── .gitignore
├── app.iml
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── myhexaville
│ │ └── androidimagepicker
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── myhexaville
│ │ │ └── androidimagepicker
│ │ │ ├── StartActivity.java
│ │ │ ├── activity_example
│ │ │ └── ActivityExample.java
│ │ │ └── fragment_example
│ │ │ ├── FragmentExample.java
│ │ │ └── ImagePickerFragment.java
│ └── res
│ │ ├── layout
│ │ ├── activity_start.xml
│ │ ├── fragment_activity.xml
│ │ └── main_layout.xml
│ │ ├── menu
│ │ └── menu_main.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-v21
│ │ └── styles.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── myhexaville
│ └── androidimagepicker
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── library
├── .gitignore
├── build.gradle
├── library.iml
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── myhexaville
│ │ └── smartimagepicker
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── myhexaville
│ │ │ └── smartimagepicker
│ │ │ ├── CustomFileProvider.java
│ │ │ ├── ImagePicker.java
│ │ │ ├── ImagePickerContract.java
│ │ │ └── OnImagePickedListener.java
│ └── res
│ │ ├── values
│ │ ├── colors.xml
│ │ └── strings.xml
│ │ └── xml
│ │ └── file_paths.xml
│ └── test
│ └── java
│ └── com
│ └── myhexaville
│ └── smartimagepicker
│ └── ExampleUnitTest.java
└── settings.gradle
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/android_arch_core_common_1_0_0_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/android_arch_lifecycle_common_1_0_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/android_arch_lifecycle_runtime_1_0_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_databinding_adapters_1_3_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_databinding_baseLibrary_3_0_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_databinding_library_1_3_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_animated_vector_drawable_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_appcompat_v7_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_design_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_exifinterface_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_recyclerview_v7_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_annotations_27_0_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_compat_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_core_ui_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_core_utils_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_fragment_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_media_compat_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_v4_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_support_vector_drawable_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_espresso_espresso_core_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_exposed_instrumentation_api_publish_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_rules_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_test_runner_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/com_android_support_transition_27_0_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/com_google_code_findbugs_jsr305_2_0_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/com_squareup_javawriter_2_1_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/com_theartofdev_edmodo_android_image_cropper_2_6_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/javax_annotation_javax_annotation_api_1_2_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/javax_inject_javax_inject_1_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/junit_junit_4_12_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/org_hamcrest_hamcrest_core_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/org_hamcrest_hamcrest_integration_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/org_hamcrest_hamcrest_library_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Simplified abstraction over [Android Image Cropper](https://github.com/ArthurHub/Android-Image-Cropper) library to pick images from gallery or camera and crop them if needed.
2 |
3 |
4 |
5 |
6 |
7 | >
8 |
9 | ### Note
10 | This library is currently unsupported because I've switched my focus to Flutter and don't plan fixing any bugs any time soon
11 |
12 |
13 | ## Usage
14 | Add this line to build.gradle
15 | ```groovy
16 | compile 'com.myhexaville:smart-image-picker:1.0.4'
17 | ```
18 |
19 |
20 | ### Create new instance and save it as field
21 | ```java
22 | imagePicker = new ImagePicker(this, /* activity non null*/
23 | null, /* fragment nullable*/
24 | imageUri -> {/*on image picked */
25 | imageView.setImageURI(imageUri);
26 | })
27 | .setWithImageCrop(
28 | 1 /*aspect ratio x*/
29 | 1 /*aspect ratio y*/);
30 | ```
31 |
32 | ### If calling from Activity
33 | Override Activity's methods to delegate permissions to ImagePicker and resulting image
34 | ```java
35 | @Override
36 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
37 | super.onActivityResult(requestCode, resultCode, data);
38 | imagePicker.handleActivityResult(resultCode,requestCode, data);
39 | }
40 | @Override
41 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
42 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
43 | imagePicker.handlePermission(requestCode, grantResults);
44 | }
45 | ```
46 | ### Open Picker
47 | There's two methods available
48 | ```java
49 | imagePicker.openCamera();
50 | imagePicker.choosePicture(true /*show camera intents*/);
51 | ```
52 | First one opens camera directly, second shows an intent picker, where user picks from desired application. You can include/exclude camera intents with boolean.
53 |
54 | That's it, if you don't need to crop image, don't call *setWithImageCrop()* in the chain. By default it's disabled. And if you want to get a file after you picked image, you can get it with this method
55 | ```java
56 | File file = imagePicker.getImageFile();
57 | ```
58 | ### If calling from Fragment
59 | Create instance
60 | ```java
61 | imagePicker = new ImagePicker(getActivity(),
62 | this,
63 | imageUri -> {/*on image picked */
64 | imageView.setImageURI(imageUri);
65 | })
66 | .setWithImageCrop(
67 | 1 /*aspect ratio x*/
68 | 1 /*aspect ratio y*/);
69 | ```
70 |
71 | Overriden methods should be in your Fragment
72 |
73 | ```java
74 | @Override
75 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
76 | super.onActivityResult(requestCode, resultCode, data);
77 | imagePicker.handleActivityResult(resultCode, requestCode, data);
78 | }
79 | @Override
80 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
81 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
82 | imagePicker.handlePermission(requestCode, grantResults);
83 | }
84 | ```
85 | But your fragment won't get activity result callback itself. You need to call it manually. Add this code to activity that hosts your fragment
86 |
87 | ```java
88 | @Override
89 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
90 | super.onActivityResult(requestCode, resultCode, data);
91 | List fragments = getSupportFragmentManager().getFragments();
92 | if (fragments != null) {
93 | for (Fragment f : fragments) {
94 | if (f instanceof YourFragment) {
95 | f.onActivityResult(requestCode, resultCode, data);
96 | }
97 | }
98 | }
99 | }
100 | ```
101 |
102 | ### You can get a sample app [here](https://github.com/IhorKlimov/SmartImagePicker/tree/master/app)
103 | ### You don't need to add any permissions to manifest, everything is merged automatically from library's manifest file
104 |
--------------------------------------------------------------------------------
/SmartImagePicker.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | generateDebugSources
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
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 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | buildscript {
4 | repositories {
5 | mavenCentral()
6 | }
7 | }
8 |
9 | android {
10 | compileOptions {
11 | sourceCompatibility JavaVersion.VERSION_1_8
12 | targetCompatibility JavaVersion.VERSION_1_8
13 | }
14 | compileSdkVersion rootProject.ext.compileSdkVersion
15 | buildToolsVersion rootProject.ext.buildToolsVersion
16 | dataBinding {
17 | enabled true
18 | }
19 | defaultConfig {
20 | vectorDrawables.useSupportLibrary = true
21 | applicationId "com.myhexaville.androidimagepicker"
22 | minSdkVersion rootProject.ext.minSdkVersion
23 | targetSdkVersion rootProject.ext.targetSdkVersion
24 | versionCode 1
25 | versionName "1.0"
26 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
27 | }
28 | buildTypes {
29 | release {
30 | minifyEnabled false
31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
32 | }
33 | }
34 | }
35 |
36 | dependencies {
37 | compile fileTree(include: ['*.jar'], dir: 'libs')
38 | testCompile 'junit:junit:4.12'
39 |
40 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
41 | exclude group: 'com.android.support', module: 'support-annotations'
42 | })
43 |
44 | compile project(':library')
45 |
46 | implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
47 | implementation "com.android.support:design:$supportLibraryVersion"
48 | implementation "com.android.support:support-v4:$supportLibraryVersion"
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/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 C:\Users\Ihor\AppData\Local\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/com/myhexaville/androidimagepicker/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.androidimagepicker;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.myhexaville.androidimagepicker", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
15 |
16 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/myhexaville/androidimagepicker/StartActivity.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.androidimagepicker;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.Snackbar;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.support.v7.widget.Toolbar;
9 | import android.view.View;
10 | import android.databinding.DataBindingUtil;
11 |
12 | import com.myhexaville.androidimagepicker.activity_example.ActivityExample;
13 | import com.myhexaville.androidimagepicker.databinding.ActivityStartBinding;
14 | import com.myhexaville.androidimagepicker.fragment_example.FragmentExample;
15 |
16 |
17 | public class StartActivity extends AppCompatActivity {
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | ActivityStartBinding binding =
23 | DataBindingUtil.setContentView(this, R.layout.activity_start);
24 | setSupportActionBar(binding.toolbar);
25 | }
26 |
27 | public void fragmentExample(View view) {
28 | startActivity(new Intent(this, FragmentExample.class));
29 | }
30 |
31 | public void activityExample(View view) {
32 | startActivity(new Intent(this, ActivityExample.class));
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/myhexaville/androidimagepicker/activity_example/ActivityExample.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.androidimagepicker.activity_example;
2 |
3 | import android.content.Intent;
4 | import android.databinding.DataBindingUtil;
5 | import android.os.Bundle;
6 | import android.support.annotation.NonNull;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.util.Log;
9 | import android.view.View;
10 |
11 | import com.myhexaville.androidimagepicker.R;
12 | import com.myhexaville.androidimagepicker.databinding.MainLayoutBinding;
13 | import com.myhexaville.smartimagepicker.ImagePicker;
14 |
15 |
16 | public class ActivityExample extends AppCompatActivity {
17 | private static final String TAG = "ActivityExample";
18 | private ImagePicker imagePicker;
19 | private MainLayoutBinding binding;
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | binding = DataBindingUtil.setContentView(this, R.layout.main_layout);
25 | setSupportActionBar(binding.toolbar);
26 | }
27 |
28 | @Override
29 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
30 | super.onActivityResult(requestCode, resultCode, data);
31 | imagePicker.handleActivityResult(resultCode,requestCode, data);
32 | }
33 |
34 | @Override
35 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
36 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
37 | imagePicker.handlePermission(requestCode, grantResults);
38 | }
39 |
40 | public void showAll(View view) {
41 | refreshImagePicker();
42 | imagePicker.choosePicture(true);
43 | }
44 |
45 | public void chooseFromGallery(View view) {
46 | refreshImagePicker();
47 | imagePicker.choosePicture(false);
48 | }
49 |
50 | public void openCamera(View view) {
51 | refreshImagePicker();
52 | imagePicker.openCamera();
53 | }
54 |
55 | private void refreshImagePicker() {
56 | imagePicker = new ImagePicker(this,
57 | null,
58 | imageUri -> {
59 | Log.d(TAG, "refreshImagePicker: "+ imageUri);
60 | Log.d(TAG, "refreshImagePicker: "+ imagePicker.getImageFile().getName());
61 | binding.image.setImageURI(imageUri);
62 | });
63 | if (binding.withCrop.isChecked()) {
64 | imagePicker.setWithImageCrop(
65 | Integer.parseInt(binding.aspectRatioX.getText().toString()),
66 | Integer.parseInt(binding.aspectRatioY.getText().toString())
67 | );
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/myhexaville/androidimagepicker/fragment_example/FragmentExample.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.androidimagepicker.fragment_example;
2 |
3 | import android.content.Intent;
4 | import android.databinding.DataBindingUtil;
5 | import android.os.Bundle;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v7.app.AppCompatActivity;
8 |
9 | import com.myhexaville.androidimagepicker.R;
10 | import com.myhexaville.androidimagepicker.databinding.FragmentActivityBinding;
11 |
12 | import java.util.List;
13 |
14 |
15 | public class FragmentExample extends AppCompatActivity {
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 |
21 | FragmentActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.fragment_activity);
22 | }
23 |
24 | @Override
25 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
26 | super.onActivityResult(requestCode, resultCode, data);
27 | List fragments = getSupportFragmentManager().getFragments();
28 | if (fragments != null) {
29 | for (Fragment f : fragments) {
30 | if (f instanceof ImagePickerFragment) {
31 | f.onActivityResult(requestCode, resultCode, data);
32 | }
33 | }
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/myhexaville/androidimagepicker/fragment_example/ImagePickerFragment.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.androidimagepicker.fragment_example;
2 |
3 |
4 | import android.content.Intent;
5 | import android.databinding.DataBindingUtil;
6 | import android.os.Bundle;
7 | import android.support.annotation.NonNull;
8 | import android.support.v4.app.Fragment;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 |
13 | import com.myhexaville.androidimagepicker.R;
14 | import com.myhexaville.androidimagepicker.databinding.MainLayoutBinding;
15 | import com.myhexaville.smartimagepicker.ImagePicker;
16 |
17 | public class ImagePickerFragment extends Fragment {
18 |
19 | private ImagePicker imagePicker;
20 | private MainLayoutBinding binding;
21 |
22 | public ImagePickerFragment() {
23 | // Required empty public constructor
24 | }
25 |
26 | @Override
27 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
28 | Bundle savedInstanceState) {
29 | binding = DataBindingUtil.inflate(inflater, R.layout.main_layout, container, false);
30 |
31 | binding.openCamera.setOnClickListener(v -> openCamera());
32 | binding.showAll.setOnClickListener(v -> showAll());
33 | binding.showGallery.setOnClickListener(v -> chooseFromGallery());
34 |
35 | return binding.getRoot();
36 | }
37 |
38 | @Override
39 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
40 | super.onActivityResult(requestCode, resultCode, data);
41 | imagePicker.handleActivityResult(resultCode, requestCode, data);
42 | }
43 |
44 | @Override
45 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
46 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
47 | imagePicker.handlePermission(requestCode, grantResults);
48 | }
49 |
50 | public void showAll() {
51 | refreshImagePicker();
52 | imagePicker.choosePicture(true);
53 | }
54 |
55 | public void chooseFromGallery() {
56 | refreshImagePicker();
57 | imagePicker.choosePicture(false);
58 | }
59 |
60 | public void openCamera() {
61 | refreshImagePicker();
62 | imagePicker.openCamera();
63 | }
64 |
65 | private void refreshImagePicker() {
66 | imagePicker = new ImagePicker(getActivity(),
67 | this,
68 | imageUri -> {
69 | binding.image.setImageURI(imageUri);
70 | });
71 | if (binding.withCrop.isChecked()) {
72 | imagePicker.setWithImageCrop(
73 | Integer.parseInt(binding.aspectRatioX.getText().toString()),
74 | Integer.parseInt(binding.aspectRatioY.getText().toString())
75 | );
76 | }
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_start.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
23 |
24 |
25 |
26 |
32 |
33 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/main_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
23 |
24 |
25 |
26 |
32 |
33 |
39 |
40 |
46 |
47 |
53 |
54 |
60 |
61 |
62 |
70 |
71 |
76 |
77 |
82 |
83 |
88 |
89 |
93 |
94 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IhorKlimov/SmartImagePicker/6a8bdd124df2eefa333ef06d4d798ea2f452996a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Android Image Picker
3 | Settings
4 | FragmentExample
5 |
6 |
7 | Hello blank fragment
8 | StartActivity
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/com/myhexaville/androidimagepicker/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.androidimagepicker;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.compileSdkVersion = 27
5 | ext.buildToolsVersion = '27.0.2'
6 | ext.minSdkVersion = 16
7 | ext.targetSdkVersion = 27
8 | ext.supportLibraryVersion = '27.1.0'
9 |
10 | repositories {
11 | jcenter()
12 | google()
13 | }
14 | dependencies {
15 | classpath 'com.android.tools.build:gradle:3.0.1'
16 |
17 | // NOTE: Do not place your application dependencies here; they belong
18 | // in the individual module build.gradle files
19 | }
20 | }
21 |
22 | allprojects {
23 | repositories {
24 | jcenter()
25 | google()
26 | }
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jan 18 18:37:19 CET 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | ext {
4 | PUBLISH_GROUP_ID = 'com.myhexaville'
5 | PUBLISH_ARTIFACT_ID = 'smart-image-picker'
6 | PUBLISH_VERSION = '1.0.4'
7 | }
8 |
9 | buildscript {
10 | repositories {
11 | mavenCentral()
12 | }
13 | }
14 |
15 | android {
16 | compileOptions {
17 | sourceCompatibility JavaVersion.VERSION_1_8
18 | targetCompatibility JavaVersion.VERSION_1_8
19 | }
20 | compileSdkVersion rootProject.ext.compileSdkVersion
21 | buildToolsVersion rootProject.ext.buildToolsVersion
22 |
23 | defaultConfig {
24 | vectorDrawables.useSupportLibrary = true
25 | minSdkVersion rootProject.ext.minSdkVersion
26 | targetSdkVersion rootProject.ext.targetSdkVersion
27 | versionCode 5
28 | versionName "1.0.4"
29 |
30 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
31 | }
32 | buildTypes {
33 | release {
34 | minifyEnabled false
35 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
36 | }
37 | }
38 | }
39 |
40 | dependencies {
41 | compile fileTree(dir: 'libs', include: ['*.jar'])
42 | testCompile 'junit:junit:4.12'
43 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
44 | exclude group: 'com.android.support', module: 'support-annotations'
45 | })
46 |
47 | implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
48 | implementation "com.android.support:support-v4:$supportLibraryVersion"
49 | implementation 'com.theartofdev.edmodo:android-image-cropper:2.6.0'
50 |
51 | }
52 | apply from: 'https://raw.githubusercontent.com/blundell/release-android-library/master/android-release-aar.gradle'
--------------------------------------------------------------------------------
/library/library.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | generateDebugSources
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
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 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/library/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 C:\Users\Ihor\AppData\Local\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 |
--------------------------------------------------------------------------------
/library/src/androidTest/java/com/myhexaville/smartimagepicker/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.smartimagepicker;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.myhexaville.smartimagepicker.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
9 |
10 |
14 |
15 |
20 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/library/src/main/java/com/myhexaville/smartimagepicker/CustomFileProvider.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.smartimagepicker;
2 |
3 | import android.support.v4.content.FileProvider;
4 |
5 | public class CustomFileProvider extends FileProvider{
6 | }
7 |
--------------------------------------------------------------------------------
/library/src/main/java/com/myhexaville/smartimagepicker/ImagePicker.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.smartimagepicker;
2 |
3 | import android.Manifest;
4 | import android.annotation.SuppressLint;
5 | import android.app.Activity;
6 | import android.content.Intent;
7 | import android.content.pm.PackageManager;
8 | import android.net.Uri;
9 | import android.os.Parcelable;
10 | import android.provider.MediaStore;
11 | import android.support.annotation.NonNull;
12 | import android.support.annotation.Nullable;
13 | import android.support.v4.app.Fragment;
14 | import android.support.v4.content.ContextCompat;
15 | import android.support.v4.content.FileProvider;
16 | import android.util.Log;
17 | import android.widget.Toast;
18 |
19 | import com.theartofdev.edmodo.cropper.CropImage;
20 | import com.theartofdev.edmodo.cropper.CropImageView;
21 |
22 | import java.io.File;
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.List;
26 |
27 | import static android.app.Activity.RESULT_OK;
28 | import static android.content.pm.PackageManager.PERMISSION_GRANTED;
29 | import static com.theartofdev.edmodo.cropper.CropImage.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE;
30 | import static com.theartofdev.edmodo.cropper.CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE;
31 | import static com.theartofdev.edmodo.cropper.CropImage.getGalleryIntents;
32 |
33 | /**
34 | * Usage: Create new instance, call {@link #choosePicture(boolean)} or {@link #openCamera()}
35 | * override {@link Activity#onActivityResult}, call {@link #handleActivityResult(int, int, Intent)} in it
36 | * override {@link Activity#onRequestPermissionsResult}, call {@link #handlePermission(int, int[])} in it
37 | * get picked file with {@link #getImageFile()}
38 | *
39 | * If calling from Fragment, override {@link Activity#onActivityResult(int, int, Intent)}
40 | * and call {@link Fragment#onActivityResult(int, int, Intent)} for your fragment to delegate result
41 | */
42 | public class ImagePicker implements ImagePickerContract {
43 | private static final String TAG = "ImagePicker";
44 | private static final int CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE_WITH_CAMERA = 100;
45 | private static final int CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE_WITHOUT_CAMERA = 101;
46 |
47 | private static String currentCameraFileName = "";
48 | private OnImagePickedListener listener;
49 | private Activity activity;
50 | private Fragment fragment;
51 |
52 | private File imageFile;
53 | private int aspectRatioX, aspectRatioY;
54 | private boolean withCrop;
55 |
56 | public ImagePicker(Activity activity, @Nullable Fragment fragment, OnImagePickedListener listener) {
57 | this.activity = activity;
58 | this.fragment = fragment;
59 | this.listener = listener;
60 | }
61 |
62 | @SuppressWarnings("UnusedReturnValue")
63 | @Override
64 | public ImagePicker setWithImageCrop(int aspectRatioX, int aspectRatioY) {
65 | withCrop = true;
66 | this.aspectRatioX = aspectRatioX;
67 | this.aspectRatioY = aspectRatioY;
68 | return this;
69 | }
70 |
71 | @SuppressLint("NewApi")
72 | @Override
73 | public void choosePicture(boolean includeCamera) {
74 | if (needToAskPermissions()) {
75 | String[] neededPermissions = getNeededPermissions();
76 | int requestCode = includeCamera
77 | ? CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE_WITH_CAMERA
78 | : CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE_WITHOUT_CAMERA;
79 | if (fragment != null) {
80 | fragment.requestPermissions(neededPermissions, requestCode);
81 | } else {
82 | activity.requestPermissions(neededPermissions, requestCode);
83 | }
84 | } else {
85 | startImagePickerActivity(includeCamera);
86 | }
87 | }
88 |
89 | @SuppressLint("NewApi")
90 | @Override
91 | public void openCamera() {
92 | if (needToAskPermissions()) {
93 | if (fragment != null) {
94 | fragment.requestPermissions(getNeededPermissions(), CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
95 | } else {
96 | activity.requestPermissions(getNeededPermissions(), CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
97 | }
98 | } else {
99 | Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
100 | Intent cameraIntent = getCameraIntent();
101 | if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
102 | activity.startActivityForResult(cameraIntent, PICK_IMAGE_CHOOSER_REQUEST_CODE);
103 | }
104 | }
105 | }
106 |
107 | @SuppressWarnings({"WeakerAccess", "unused"})
108 | @NonNull
109 | @Override
110 | public File getImageFile() {
111 | return imageFile;
112 | }
113 |
114 | @Override
115 | public void handlePermission(int requestCode, int[] grantResults) {
116 | Log.d(TAG, "handlePermission: " + requestCode);
117 | if (requestCode == CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE_WITH_CAMERA) {
118 | if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
119 | startImagePickerActivity(true);
120 | } else {
121 | Toast.makeText(activity, R.string.canceling, Toast.LENGTH_SHORT).show();
122 | }
123 | }
124 | if (requestCode == CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE_WITHOUT_CAMERA) {
125 | if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
126 | startImagePickerActivity(false);
127 | } else {
128 | Toast.makeText(activity, R.string.canceling, Toast.LENGTH_SHORT).show();
129 | }
130 | } else if (requestCode == CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE) {
131 | if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
132 | openCamera();
133 | } else {
134 | Toast.makeText(activity, R.string.canceling, Toast.LENGTH_SHORT).show();
135 | }
136 | }
137 | }
138 |
139 | @Override
140 | public void handleActivityResult(int resultCode, int requestCode, Intent data) {
141 | if (resultCode == RESULT_OK) {
142 | Log.d(TAG, "handleActivityResult: 1");
143 | if (requestCode == PICK_IMAGE_CHOOSER_REQUEST_CODE) {
144 | Log.d(TAG, "handleActivityResult: 2");
145 | handlePickedImageResult(data);
146 | } else {
147 | if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
148 | handleCroppedImageResult(data);
149 | }
150 | }
151 | } else {
152 | Log.d(TAG, "handleActivityResult: " + resultCode);
153 | if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
154 | Log.d(TAG, "onActivityResult: Image picker Error");
155 | }
156 | }
157 | }
158 |
159 | private String[] getNeededPermissions() {
160 | if (withCrop) {
161 | return new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE};
162 | } else {
163 | return new String[]{Manifest.permission.CAMERA};
164 | }
165 | }
166 |
167 | private boolean needToAskPermissions() {
168 | if (withCrop) {
169 | return ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
170 | || ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
171 | } else {
172 | return ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED;
173 | }
174 | }
175 |
176 | private void handleCroppedImageResult(Intent data) {
177 | Log.d(TAG, "handleCroppedImageResult: ");
178 | CropImage.ActivityResult result = CropImage.getActivityResult(data);
179 | Uri croppedImageUri = result.getUri();
180 | deletePreviouslyCroppedFiles(croppedImageUri);
181 | imageFile = new File(croppedImageUri.getPath());
182 | listener.onImagePicked(croppedImageUri);
183 | }
184 |
185 | @SuppressLint("NewApi")
186 | private void handlePickedImageResult(Intent data) {
187 | boolean isCamera = true;
188 | if (data != null && data.getData() != null) {
189 | String action = data.getAction();
190 | isCamera = action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
191 | }
192 | Uri imageUri = isCamera || data.getData() == null ? getCameraFileUri(activity) : data.getData();
193 | if (isCamera) {
194 | deletePreviousCameraFiles();
195 | }
196 | Log.d(TAG, "handlePickedImageResult: " + imageUri);
197 | if (withCrop) {
198 | CropImage.activity(imageUri)
199 | .setGuidelines(CropImageView.Guidelines.ON)
200 | .setAspectRatio(aspectRatioX, aspectRatioY)
201 | .start(activity);
202 | } else {
203 | imageFile = new File(imageUri.getPath());
204 | listener.onImagePicked(imageUri);
205 | }
206 | }
207 |
208 | @SuppressWarnings("ResultOfMethodCallIgnored")
209 | private void deletePreviousCameraFiles() {
210 | File imagePath = new File(activity.getFilesDir(), "images");
211 | if (imagePath.exists() && imagePath.isDirectory()) {
212 | if (imagePath.listFiles().length > 0) {
213 | for (File file : imagePath.listFiles()) {
214 | if (!file.getName().equals(currentCameraFileName)) {
215 | file.delete();
216 | }
217 | }
218 | }
219 | }
220 | }
221 |
222 | @SuppressWarnings("ResultOfMethodCallIgnored")
223 | private void deletePreviouslyCroppedFiles(Uri currentCropImageUri) {
224 | Log.d(TAG, "deletePreviouslyCroppedFiles: " + currentCropImageUri);
225 | String croppedImageName = currentCropImageUri.getLastPathSegment();
226 | File imagePath = activity.getCacheDir();
227 | Log.d(TAG, "deletePreviouslyCroppedFiles: " + imagePath.exists() + " " + imagePath.isDirectory());
228 | if (imagePath.exists() && imagePath.isDirectory()) {
229 | Log.d(TAG, "deletePreviouslyCroppedFiles: " + imagePath.toString());
230 | Log.d(TAG, "deletePreviouslyCroppedFiles: " + imagePath.listFiles().length);
231 | if (imagePath.listFiles().length > 0) {
232 | for (File file : imagePath.listFiles()) {
233 | Log.d(TAG, "deletePreviouslyCroppedFiles: " + file.getName());
234 | if (!file.getName().equals(croppedImageName)) {
235 | file.delete();
236 | }
237 | }
238 | }
239 | }
240 | }
241 |
242 | @SuppressWarnings("ResultOfMethodCallIgnored")
243 | @NonNull
244 | private Intent getCameraIntent() {
245 | currentCameraFileName = "outputImage" + System.currentTimeMillis() + ".jpg";
246 | File imagesDir = new File(activity.getFilesDir(), "images");
247 | imagesDir.mkdirs();
248 | File file = new File(imagesDir, currentCameraFileName);
249 | try {
250 | file.createNewFile();
251 | } catch (IOException e) {
252 | Log.d(TAG, "openCamera: coudln't crate ");
253 | e.printStackTrace();
254 | }
255 | Log.d(TAG, "openCamera: file exists " + file.exists() + " " + file.toURI().toString());
256 | Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
257 |
258 | String authority = activity.getPackageName() + ".smart-image-picket-provider";
259 | final Uri outputUri = FileProvider.getUriForFile(
260 | activity.getApplicationContext(),
261 | authority,
262 | file);
263 | cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
264 | activity.grantUriPermission(
265 | "com.google.android.GoogleCamera",
266 | outputUri,
267 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
268 | );
269 | return cameraIntent;
270 | }
271 |
272 | private Uri getCameraFileUri(Activity activity) {
273 | File imagePath = new File(activity.getFilesDir(), "images/" + currentCameraFileName);
274 | return Uri.fromFile(imagePath);
275 | }
276 |
277 | private void startImagePickerActivity(boolean includeCamera) {
278 | List allIntents = new ArrayList<>();
279 | PackageManager packageManager = activity.getPackageManager();
280 |
281 | List galleryIntents = getGalleryIntents(packageManager, Intent.ACTION_GET_CONTENT, false);
282 | if (galleryIntents.size() == 0) {
283 | // if no intents found for get-content try pick intent action (Huawei P9).
284 | galleryIntents = getGalleryIntents(packageManager, Intent.ACTION_PICK, false);
285 | }
286 |
287 | if (includeCamera) {
288 | allIntents.add(getCameraIntent());
289 | }
290 | allIntents.addAll(galleryIntents);
291 |
292 | Intent target;
293 | if (allIntents.isEmpty()) {
294 | target = new Intent();
295 | } else {
296 | target = allIntents.get(allIntents.size() - 1);
297 | allIntents.remove(allIntents.size() - 1);
298 | }
299 |
300 | // Create a chooser from the main intent
301 | Intent chooserIntent = Intent.createChooser(target, activity.getString(R.string.select_source));
302 |
303 | // Add all other intents
304 | chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));
305 | activity.startActivityForResult(chooserIntent, PICK_IMAGE_CHOOSER_REQUEST_CODE);
306 | }
307 |
308 | }
309 |
--------------------------------------------------------------------------------
/library/src/main/java/com/myhexaville/smartimagepicker/ImagePickerContract.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.smartimagepicker;
2 |
3 | import android.content.Intent;
4 |
5 | import java.io.File;
6 |
7 | public interface ImagePickerContract {
8 | @SuppressWarnings("UnusedReturnValue")
9 | ImagePicker setWithImageCrop(int aspectRatioX, int aspectRatioY);
10 |
11 | // todo add this in v1.1
12 | // ImagePicker setWithImageCrop();
13 | // ImagePicker setWithIntentPickerTitle(String title);
14 | // ImagePicker setWithIntentPickerTitle(@StringRes int title);
15 |
16 |
17 | void choosePicture(boolean includeCamera);
18 |
19 | void openCamera();
20 |
21 | File getImageFile();
22 |
23 | void handlePermission(int requestCode, int[] grantResults);
24 |
25 | void handleActivityResult(int resultCode, int requestCode, Intent data);
26 | }
27 |
--------------------------------------------------------------------------------
/library/src/main/java/com/myhexaville/smartimagepicker/OnImagePickedListener.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.smartimagepicker;
2 |
3 | import android.net.Uri;
4 |
5 | public interface OnImagePickedListener {
6 | void onImagePicked(Uri imageUri);
7 | }
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Smart Image Picker
3 | Select source
4 | Canceling
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/library/src/main/res/xml/file_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/library/src/test/java/com/myhexaville/smartimagepicker/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.myhexaville.smartimagepicker;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library'
2 |
--------------------------------------------------------------------------------