Skip to content

Commit f2fdedc

Browse files
Merge pull request #23 from NicosNicolaou16/version2.5.0
Version2.5.0
2 parents 11dd02c + 29a51ec commit f2fdedc

10 files changed

Lines changed: 204 additions & 57 deletions

File tree

ImagePickerAndroid/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ android {
1919
testOptions.targetSdk = 36
2020
buildFeatures {
2121
compose = true
22+
buildConfig = true
2223
}
2324

2425
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@@ -86,7 +87,7 @@ afterEvaluate {
8687
register<MavenPublication>("release") {
8788
groupId = "com.github.NicosNicolaou16"
8889
artifactId = "ImagePickerAndroid"
89-
version = "2.4.5"
90+
version = "2.5.0"
9091
from(components["release"])
9192
}
9293
}

ImagePickerAndroid/src/main/java/com/nicos/imagepickerandroid/image_picker/ImagePicker.kt

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import androidx.annotation.IntRange
1515
import androidx.core.app.ActivityCompat
1616
import androidx.fragment.app.Fragment
1717
import androidx.fragment.app.FragmentActivity
18+
import com.nicos.imagepickerandroid.utils.constants.Constants.imagePickerNotAvailableLogs
1819
import com.nicos.imagepickerandroid.utils.image_helper_methods.ImageHelperMethods
1920
import com.nicos.imagepickerandroid.utils.image_helper_methods.ScaleBitmapModel
2021
import com.nicos.imagepickerandroid.utils.permissions.PermissionsHelper
@@ -68,18 +69,28 @@ data class ImagePicker(
6869
* */
6970
fun pickSingleImageFromGallery() {
7071
fragmentActivity?.let {
71-
pickImageFromGalleryResultLauncher?.launch(
72-
PickVisualMediaRequest(
73-
ActivityResultContracts.PickVisualMedia.ImageOnly
72+
if (imageHelperMethods.isImagePickerAvailable(context = it)) {
73+
pickImageFromGalleryResultLauncher?.launch(
74+
PickVisualMediaRequest(
75+
ActivityResultContracts.PickVisualMedia.ImageOnly
76+
)
7477
)
75-
)
78+
} else {
79+
imagePickerNotAvailableLogs()
80+
imagePickerInterface?.onImagePickerNotAvailable()
81+
}
7682
}
7783
fragment?.let {
78-
pickImageFromGalleryResultLauncher?.launch(
79-
PickVisualMediaRequest(
80-
ActivityResultContracts.PickVisualMedia.ImageOnly
84+
if (imageHelperMethods.isImagePickerAvailable(context = it.requireContext())) {
85+
pickImageFromGalleryResultLauncher?.launch(
86+
PickVisualMediaRequest(
87+
ActivityResultContracts.PickVisualMedia.ImageOnly
88+
)
8189
)
82-
)
90+
} else {
91+
imagePickerNotAvailableLogs()
92+
imagePickerInterface?.onImagePickerNotAvailable()
93+
}
8394
}
8495
}
8596

@@ -170,18 +181,28 @@ data class ImagePicker(
170181
* */
171182
fun pickMultipleImagesFromGallery() {
172183
fragmentActivity?.let {
173-
pickMultipleImageFromGalleryResultLauncher?.launch(
174-
PickVisualMediaRequest(
175-
ActivityResultContracts.PickVisualMedia.ImageOnly
184+
if (imageHelperMethods.isImagePickerAvailable(context = it)) {
185+
pickMultipleImageFromGalleryResultLauncher?.launch(
186+
PickVisualMediaRequest(
187+
ActivityResultContracts.PickVisualMedia.ImageOnly
188+
)
176189
)
177-
)
190+
} else {
191+
imagePickerNotAvailableLogs()
192+
imagePickerInterface?.onImagePickerNotAvailable()
193+
}
178194
}
179195
fragment?.let {
180-
pickMultipleImageFromGalleryResultLauncher?.launch(
181-
PickVisualMediaRequest(
182-
ActivityResultContracts.PickVisualMedia.ImageOnly
196+
if (imageHelperMethods.isImagePickerAvailable(context = it.requireContext())) {
197+
pickMultipleImageFromGalleryResultLauncher?.launch(
198+
PickVisualMediaRequest(
199+
ActivityResultContracts.PickVisualMedia.ImageOnly
200+
)
183201
)
184-
)
202+
} else {
203+
imagePickerNotAvailableLogs()
204+
imagePickerInterface?.onImagePickerNotAvailable()
205+
}
185206
}
186207
}
187208

ImagePickerAndroid/src/main/java/com/nicos/imagepickerandroid/image_picker/ImagePickerCompose.kt

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import androidx.compose.runtime.rememberCoroutineScope
1919
import androidx.compose.runtime.setValue
2020
import androidx.compose.ui.platform.LocalContext
2121
import androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale
22+
import com.nicos.imagepickerandroid.utils.constants.Constants.imagePickerNotAvailableLogs
2223
import com.nicos.imagepickerandroid.utils.enums.TakeImageType
2324
import com.nicos.imagepickerandroid.utils.extensions.getUriWithFileProvider
2425
import com.nicos.imagepickerandroid.utils.image_helper_methods.ImageHelperMethods
@@ -111,9 +112,19 @@ fun PickSingleImage(
111112

112113
/**
113114
* This method is calling from listener to pick single image
115+
* @param context pass context
116+
* @param onImagePickerNotAvailable callback for image picker not available
114117
* */
115-
fun pickSingleImage() {
116-
pickSingleImage?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
118+
fun pickSingleImage(
119+
context: Context,
120+
onImagePickerNotAvailable: (() -> Unit)? = null
121+
) {
122+
if (imageHelperMethods.isImagePickerAvailable(context = context)) {
123+
pickSingleImage?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
124+
} else {
125+
imagePickerNotAvailableLogs()
126+
onImagePickerNotAvailable?.invoke()
127+
}
117128
}
118129

119130
/**
@@ -166,9 +177,19 @@ fun PickSingleImageWithBase64Value(
166177

167178
/**
168179
* This method is calling from listener to pick single image with base64 value
180+
* @param context pass context
181+
* @param onImagePickerNotAvailable callback for image picker not available
169182
* */
170-
fun pickSingleImageWithBase64Value() {
171-
pickSingleImageWithBase64Value?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
183+
fun pickSingleImageWithBase64Value(
184+
context: Context,
185+
onImagePickerNotAvailable: (() -> Unit)? = null
186+
) {
187+
if (imageHelperMethods.isImagePickerAvailable(context = context)) {
188+
pickSingleImageWithBase64Value?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
189+
} else {
190+
imagePickerNotAvailableLogs()
191+
onImagePickerNotAvailable?.invoke()
192+
}
172193
}
173194

174195
/**
@@ -221,9 +242,19 @@ fun PickMultipleImages(
221242

222243
/**
223244
* This method is calling from listener to pick multiple images
245+
* @param context pass context
246+
* @param onImagePickerNotAvailable callback for image picker not available
224247
* */
225-
fun pickMultipleImages() {
226-
pickMultipleImages?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
248+
fun pickMultipleImages(
249+
context: Context,
250+
onImagePickerNotAvailable: (() -> Unit)? = null
251+
) {
252+
if (imageHelperMethods.isImagePickerAvailable(context = context)) {
253+
pickMultipleImages?.launch(input = PickVisualMediaRequest(mediaType = ActivityResultContracts.PickVisualMedia.ImageOnly))
254+
} else {
255+
imagePickerNotAvailableLogs()
256+
onImagePickerNotAvailable?.invoke()
257+
}
227258
}
228259

229260
/**
@@ -287,9 +318,19 @@ fun PickMultipleImagesWithBase64Values(
287318

288319
/**
289320
* This method is calling from listener to pick multiple images with base64 values
321+
* @param context pass context
322+
* @param onImagePickerNotAvailable callback for image picker not available
290323
* */
291-
fun pickMultipleImagesWithBase64Values() {
292-
pickMultipleImagesWithBase64Values?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
324+
fun pickMultipleImagesWithBase64Values(
325+
context: Context,
326+
onImagePickerNotAvailable: (() -> Unit)? = null
327+
) {
328+
if (imageHelperMethods.isImagePickerAvailable(context = context)) {
329+
pickMultipleImagesWithBase64Values?.launch(input = PickVisualMediaRequest(mediaType = ActivityResultContracts.PickVisualMedia.ImageOnly))
330+
} else {
331+
imagePickerNotAvailableLogs()
332+
onImagePickerNotAvailable?.invoke()
333+
}
293334
}
294335

295336
/**
@@ -309,11 +350,14 @@ fun TakeSingleCameraImage(
309350
val composableScope = rememberCoroutineScope()
310351
if (takeImageType == TakeImageType.TAKE_IMAGE) {
311352
takeCameraImage =
312-
rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { success ->
353+
rememberLauncherForActivityResult(contract = ActivityResultContracts.TakePicture()) { success ->
313354
if (success) {
314355
if (photoUri != null) {
315356
val bitmap =
316-
imageHelperMethods.convertUriToBitmap(context.contentResolver, photoUri)
357+
imageHelperMethods.convertUriToBitmap(
358+
contentResolver = context.contentResolver,
359+
photoUri
360+
)
317361
if (scaleBitmapModel != null) {
318362
composableScope.launch(Dispatchers.Default) {
319363
imageHelperMethods.scaleBitmap(
@@ -333,7 +377,7 @@ fun TakeSingleCameraImage(
333377
}
334378
} else {
335379
takeCameraImagePreview =
336-
rememberLauncherForActivityResult(ActivityResultContracts.TakePicturePreview()) { bitmap ->
380+
rememberLauncherForActivityResult(contract = ActivityResultContracts.TakePicturePreview()) { bitmap ->
337381
if (bitmap != null) {
338382
val uri = imageHelperMethods.getUriFromBitmap(bitmap)
339383
if (scaleBitmapModel != null) {
@@ -363,7 +407,7 @@ private fun CameraPermission(takeImageType: TakeImageType) {
363407
val context = LocalContext.current
364408
if (takeImageType == TakeImageType.TAKE_IMAGE) {
365409
takeCameraImage =
366-
rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { success ->
410+
rememberLauncherForActivityResult(contract = ActivityResultContracts.TakePicture()) { success ->
367411
if (!success) {
368412
photoUri = null
369413
}
@@ -378,9 +422,9 @@ private fun CameraPermission(takeImageType: TakeImageType) {
378422
val photoFile = imageHelperMethods.createImageFile(context)
379423
val uri = photoFile.getUriWithFileProvider(context)
380424
photoUri = uri
381-
takeCameraImage?.launch(uri)
425+
takeCameraImage?.launch(input = uri)
382426
} else {
383-
takeCameraImagePreview?.launch(null)
427+
takeCameraImagePreview?.launch(input = null)
384428
}
385429
}
386430
}
@@ -435,7 +479,7 @@ fun TakeSingleCameraImageWithBase64Value(
435479
if (success) {
436480
if (photoUriWithBase64 != null) {
437481
if (scaleBitmapModel != null) {
438-
composableScope.launch(Dispatchers.Default) {
482+
composableScope.launch(context = Dispatchers.Default) {
439483
val bitmap = imageHelperMethods.convertUriToBitmap(
440484
contentResolver = context.contentResolver,
441485
uri = photoUriWithBase64
@@ -481,7 +525,7 @@ fun TakeSingleCameraImageWithBase64Value(
481525
).collect { scaledBitmap ->
482526
imageHelperMethods.convertBitmapToBase64(bitmap = bitmap)
483527
.collect { base64 ->
484-
composableScope.launch(Dispatchers.Main) {
528+
composableScope.launch(context = Dispatchers.Main) {
485529
listener(scaledBitmap, base64)
486530
}
487531
}
@@ -510,24 +554,24 @@ private fun CameraPermissionForBase64(takeImageType: TakeImageType) {
510554
val context = LocalContext.current
511555
if (takeImageType == TakeImageType.TAKE_IMAGE) {
512556
takeCameraImageWithBase64Value =
513-
rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { success ->
557+
rememberLauncherForActivityResult(contract = ActivityResultContracts.TakePicture()) { success ->
514558
if (!success) {
515559
photoUri = null
516560
}
517561
}
518562
}
519563

520564
permissionCameraImageWithBase64Launcher = rememberLauncherForActivityResult(
521-
ActivityResultContracts.RequestPermission()
565+
contract = ActivityResultContracts.RequestPermission()
522566
) { isGranted ->
523567
if (isGranted) {
524568
if (takeImageType == TakeImageType.TAKE_IMAGE) {
525569
val photoFile = imageHelperMethods.createImageFile(context)
526570
val uri = photoFile.getUriWithFileProvider(context)
527571
photoUriWithBase64 = uri
528-
takeCameraImageWithBase64Value?.launch(uri)
572+
takeCameraImageWithBase64Value?.launch(input = uri)
529573
} else {
530-
takeCameraImagePreviewWithBase64Value?.launch(null)
574+
takeCameraImagePreviewWithBase64Value?.launch(input = null)
531575
}
532576
}
533577
}
@@ -569,7 +613,7 @@ fun PickSingleVideo(
569613
listener: (Uri?) -> Unit
570614
) {
571615
pickVideo =
572-
rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
616+
rememberLauncherForActivityResult(contract = ActivityResultContracts.PickVisualMedia()) { uri ->
573617
if (uri != null) {
574618
listener(uri)
575619
}
@@ -580,5 +624,5 @@ fun PickSingleVideo(
580624
* This method is calling from listener to pick single video from gallery
581625
* */
582626
fun pickSingleVideo() {
583-
pickVideo?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.VideoOnly))
627+
pickVideo?.launch(input = PickVisualMediaRequest(mediaType = ActivityResultContracts.PickVisualMedia.VideoOnly))
584628
}

ImagePickerAndroid/src/main/java/com/nicos/imagepickerandroid/image_picker/ImagePickerInterface.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ interface ImagePickerInterface {
2424
}
2525

2626
fun onPermanentCameraPermissionDenied() {}
27+
fun onImagePickerNotAvailable() {}
2728
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.nicos.imagepickerandroid.utils.constants
2+
3+
import android.util.Log
4+
import com.nick.imagepickerandroid.BuildConfig
5+
6+
internal object Constants {
7+
internal const val TAG = "ImagePickerAndroid"
8+
9+
@JvmStatic
10+
internal fun imagePickerNotAvailableLogs() {
11+
if (BuildConfig.DEBUG) {
12+
Log.w(TAG, "Image Picker is not available")
13+
}
14+
}
15+
}

ImagePickerAndroid/src/main/java/com/nicos/imagepickerandroid/utils/image_helper_methods/ImageHelperMethods.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import android.net.Uri
99
import android.os.Build
1010
import android.provider.MediaStore
1111
import android.util.Base64
12+
import androidx.activity.result.contract.ActivityResultContracts
1213
import androidx.core.graphics.scale
1314
import kotlinx.coroutines.Dispatchers
1415
import kotlinx.coroutines.flow.flow
@@ -156,4 +157,7 @@ internal class ImageHelperMethods {
156157
val fileName = "${timestamp}.jpg"
157158
return File(context.cacheDir, fileName)
158159
}
160+
161+
internal fun isImagePickerAvailable(context: Context): Boolean =
162+
ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(context)
159163
}

0 commit comments

Comments
 (0)