Skip to content

Commit 81feb11

Browse files
committed
1. Added image picker for selecting image from gallery or from camera with crop and compress support.
1 parent 12a61f3 commit 81feb11

26 files changed

+1754
-9
lines changed

.idea/caches/build_file_checksums.ser

0 Bytes
Binary file not shown.

.idea/caches/gradle_models.ser

0 Bytes
Binary file not shown.

.idea/gradle.xml

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
apply plugin: 'com.android.library'
2+
3+
apply plugin: 'kotlin-android'
4+
5+
apply plugin: 'kotlin-android-extensions'
6+
27
apply plugin: 'com.github.dcendents.android-maven'
38

49
group = 'com.github.amitjangid80'
@@ -35,10 +40,6 @@ repositories {
3540
mavenCentral()
3641
}
3742

38-
ext {
39-
supportLibraryVersion = '28.0.0'
40-
}
41-
4243
dependencies {
4344
implementation fileTree(include: ['*.jar'], dir: 'libs')
4445

@@ -49,4 +50,10 @@ dependencies {
4950

5051
// RxJava dependencies
5152
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
53+
54+
// kotlin dependencies
55+
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
56+
57+
// More Info: https://github.com/Yalantis/uCrop
58+
implementation 'com.github.yalantis:ucrop:2.2.2'
5259
}

app/src/main/AndroidManifest.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,34 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
22
package="com.amit">
33

4+
<uses-permission android:name="android.permission.CAMERA" />
45
<uses-permission android:name="android.permission.INTERNET" />
56
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
67
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
78
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
9+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
10+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
811
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
912

13+
<application>
14+
15+
<activity android:name="com.amit.img_picker.ImagePickerActivity" />
16+
17+
<activity
18+
android:name="com.yalantis.ucrop.UCropActivity"
19+
android:screenOrientation="portrait"
20+
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
21+
22+
<provider
23+
android:name="android.support.v4.content.FileProvider"
24+
android:authorities="${applicationId}.provider"
25+
android:exported="false"
26+
android:grantUriPermissions="true">
27+
28+
<meta-data
29+
android:name="android.support.FILE_PROVIDER_PATHS"
30+
android:resource="@xml/image_picker_provider_paths" />
31+
32+
</provider>
33+
</application>
1034
</manifest>
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
package com.amit.img_picker
2+
3+
import android.app.Activity
4+
import android.content.Intent
5+
import android.os.Bundle
6+
import android.support.v4.app.Fragment
7+
import com.amit.img_picker.constant.ImageProvider
8+
import com.amit.img_picker.listener.ResultListener
9+
import com.amit.img_picker.util.DialogHelper
10+
import java.io.File
11+
12+
/**
13+
* Created by AMIT JANGID on 18/02/2019.
14+
**/
15+
class ImagePicker
16+
{
17+
companion object
18+
{
19+
// default Request Code to Pick Image
20+
const val RESULT_ERROR = 64
21+
const val REQUEST_CODE = 2404
22+
23+
internal const val EXTRA_ERROR = "extra.error"
24+
internal const val EXTRA_CROP_X = "extra.crop_x"
25+
internal const val EXTRA_CROP_Y = "extra.crop_y"
26+
27+
internal const val EXTRA_FILE_PATH = "extra.file_path"
28+
internal const val EXTRA_MAX_WIDTH = "extra.max_width"
29+
internal const val EXTRA_MAX_HEIGHT = "extra.max_height"
30+
31+
internal const val EXTRA_IMAGE_PROVIDER = "extra.image_provider"
32+
internal const val EXTRA_IMAGE_MAX_SIZE = "extra.image_max_size"
33+
34+
/**
35+
* Use this to use ImagePicker in Activity Class
36+
*
37+
* @param activity Activity Instance
38+
**/
39+
fun with(activity: Activity): Builder
40+
{
41+
return Builder(activity)
42+
}
43+
44+
/**
45+
* Use this to use ImagePicker in Fragment Class
46+
*
47+
* @param fragment Fragment Instance
48+
**/
49+
fun with(fragment: Fragment): Builder
50+
{
51+
return Builder(fragment)
52+
}
53+
54+
/**
55+
* Get error message from intent
56+
**/
57+
fun getError(data: Intent?): String
58+
{
59+
val error = data?.getStringExtra(EXTRA_ERROR)
60+
61+
if (error != null)
62+
{
63+
return error
64+
}
65+
else
66+
{
67+
return "Unknown Error!"
68+
}
69+
}
70+
71+
/**
72+
* Get File Path from intent
73+
**/
74+
fun getFilePath(data: Intent?): String?
75+
{
76+
return data?.getStringExtra(EXTRA_FILE_PATH)
77+
}
78+
79+
/**
80+
* Get File from intent
81+
**/
82+
fun getFile(data: Intent?): File?
83+
{
84+
val path = getFilePath(data)
85+
86+
if (path != null)
87+
{
88+
return File(path)
89+
}
90+
91+
return null
92+
}
93+
94+
}
95+
96+
class Builder(private val activity: Activity)
97+
{
98+
private var fragment: Fragment? = null
99+
100+
// image Provider
101+
private var imageProvider = ImageProvider.BOTH
102+
103+
/*
104+
* crop Parameters
105+
*/
106+
private var cropX: Float = 0f
107+
private var cropY: Float = 0f
108+
109+
/*
110+
* Resize Parameters
111+
*/
112+
private var maxWidth: Int = 0
113+
private var maxHeight: Int = 0
114+
115+
/*
116+
* Max File Size
117+
*/
118+
private var maxSize: Long = 0
119+
120+
/**
121+
* Call this while picking image for fragment.
122+
**/
123+
constructor(fragment: Fragment) : this(fragment.activity!!)
124+
{
125+
this.fragment = fragment
126+
}
127+
128+
/**
129+
* Only Capture image using Camera
130+
**/
131+
fun cameraOnly(): Builder
132+
{
133+
imageProvider = ImageProvider.CAMERA
134+
return this
135+
}
136+
137+
/**
138+
* Only Pick image from gallery
139+
**/
140+
fun galleryOnly(): Builder
141+
{
142+
imageProvider = ImageProvider.GALLERY
143+
return this
144+
}
145+
146+
/**
147+
* Set an aspect ratio for crop bounds.
148+
* User won't see the menu with other ratios options.
149+
*
150+
* @param x aspect ratio X
151+
* @param y aspect ratio Y
152+
**/
153+
fun crop(x: Float, y: Float): Builder
154+
{
155+
cropX = x
156+
cropY = y
157+
158+
return this
159+
}
160+
161+
/**
162+
* Crop Square Image, Useful for Profile Image.
163+
*
164+
**/
165+
fun cropSquare(): Builder
166+
{
167+
return crop(1f, 1f)
168+
}
169+
170+
/**
171+
* Max Width and Height of final image
172+
**/
173+
fun maxResultSize(width: Int, height: Int): Builder
174+
{
175+
this.maxWidth = width
176+
this.maxHeight = height
177+
178+
return this
179+
}
180+
181+
/**
182+
* Compress Image so that max image size can be below specified size
183+
*
184+
* @param maxSize Size in KB
185+
**/
186+
fun compress(maxSize: Int): Builder
187+
{
188+
this.maxSize = maxSize * 1024L
189+
return this
190+
}
191+
192+
/**
193+
* Start Image Picker Activity
194+
**/
195+
fun start()
196+
{
197+
start(REQUEST_CODE)
198+
}
199+
200+
/**
201+
* Start Image Picker Activity
202+
**/
203+
fun start(reqCode: Int)
204+
{
205+
if (imageProvider == ImageProvider.BOTH)
206+
{
207+
// Pick Image Provider if not specified
208+
showImageProviderDialog(reqCode)
209+
}
210+
else
211+
{
212+
startActivity(reqCode)
213+
}
214+
}
215+
216+
/**
217+
* Pick Image Provider if not specified
218+
**/
219+
private fun showImageProviderDialog(reqCode: Int)
220+
{
221+
DialogHelper.showChooseAppDialog(activity, object: ResultListener<ImageProvider>
222+
{
223+
override fun onResult(t: ImageProvider)
224+
{
225+
imageProvider = t
226+
startActivity(reqCode)
227+
}
228+
})
229+
}
230+
231+
/**
232+
* Start ImagePickerActivity with given Argument
233+
**/
234+
private fun startActivity(reqCode: Int)
235+
{
236+
val bundle = Bundle()
237+
bundle.putSerializable(EXTRA_IMAGE_PROVIDER, imageProvider)
238+
// bundle.putBoolean(EXTRA_ASK_PERMISSION, askPermission)
239+
240+
bundle.putFloat(EXTRA_CROP_X, cropX)
241+
bundle.putFloat(EXTRA_CROP_Y, cropY)
242+
243+
bundle.putInt(EXTRA_MAX_WIDTH, maxWidth)
244+
bundle.putInt(EXTRA_MAX_HEIGHT, maxHeight)
245+
246+
bundle.putLong(EXTRA_IMAGE_MAX_SIZE, maxSize)
247+
248+
val intent = Intent(activity, ImagePickerActivity::class.java)
249+
intent.putExtras(bundle)
250+
251+
if (fragment != null)
252+
{
253+
fragment?.startActivityForResult(intent, reqCode)
254+
}
255+
else
256+
{
257+
activity.startActivityForResult(intent, reqCode)
258+
}
259+
}
260+
}
261+
}

0 commit comments

Comments
 (0)