From 43b2bf62db2a34fb24ca819b6633c0addda1b59d Mon Sep 17 00:00:00 2001 From: Abhishek Ippakayal Date: Tue, 4 May 2021 19:23:07 +0530 Subject: [PATCH] fix/ fragment support --- README.md | 30 ++++++---- .../com/ssimagepicker/app/MainActivity.kt | 5 +- buildSrc/src/main/kotlin/App.kt | 2 +- .../ImagePickerActivityClass.kt | 55 +++++++++++++++---- .../ImagePickerBottomsheet.kt | 9 +-- .../src/main/res/values/strings.xml | 2 + 6 files changed, 73 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index e5ccd6e..9538095 100644 --- a/README.md +++ b/README.md @@ -76,22 +76,28 @@ Easy to use and configurable library to **Pick an image from the Gallery or Capt ```groovy dependencies { - implementation 'com.github.SimformSolutionsPvtLtd:SSImagePicker:1.5' + implementation 'com.github.SimformSolutionsPvtLtd:SSImagePicker:1.6' } ``` -2. Use ImagePicker Bottomsheet To Choose Option For Pick Image From Gallery Or Camera +2. Implement ImagePickerBottomsheet.ItemClickListener, ImagePickerActivityClass.OnResult interface in your activity or fragment + +3. Use ImagePicker Bottomsheet To Choose Option For Pick Image From Gallery Or Camera ```kotlin val fragment = ImagePickerBottomsheet() fragment.show(FragmentManager, String) ``` -3. Call ImagePickerActivityClass in your onCreate() To Handle Camera, Gallery Click And Permission Result. Pass Context, Activity , Request Permission Result Callback And activityResultRegistry : +4. Call ImagePickerActivityClass in your onCreate() To Handle Camera, Gallery Click And Permission Result. Pass Context, Request Permission Result Callback And activityResultRegistry, Activity or Fragment. : ```kotlin - var imagePicker = ImagePickerActivityClass(context,activity,onResult_Callback,activityResultRegistry) + //From activity + var imagePicker = ImagePickerActivityClass(context,onResult_Callback,activityResultRegistry,activity = this) + + //From fragment + var imagePicker = ImagePickerActivityClass(context,onResult_Callback,activityResultRegistry,fragment = this) ``` -4. To Enable All Features(crop,rotate,zoomIn,zoomOut) call cropOptions(isAllCropFeaturesRequired: Boolean) And Pass true. By Default It's Set To False And Provides Only Crop Feature. +5. To Enable All Features(crop,rotate,zoomIn,zoomOut) call cropOptions(isAllCropFeaturesRequired: Boolean) And Pass true. By Default It's Set To False And Provides Only Crop Feature. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { @@ -100,24 +106,24 @@ Easy to use and configurable library to **Pick an image from the Gallery or Capt } ``` -5. Allow Camera And Storage Permission To Pick Image And Send Your onRequestPermissionsResult To ImagePickerActivity +6. Allow Camera And Storage Permission To Pick Image And Send Your onRequestPermissionsResult To ImagePickerActivity ```kotlin override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { - imagePicker.onRequestPermissionsResult(requestCode, permissions, grantResults) + super.onRequestPermissionsResult(requestCode, permissions, grantResults) (required) } ``` -6. To Capture Image From Camera Use takePhotoFromCamera() +7. To Capture Image From Camera Use takePhotoFromCamera() ```kotlin imagePicker.takePhotoFromCamera() ``` -7. To Pick Image From Gallery Use choosePhotoFromGallary() +8. To Pick Image From Gallery Use choosePhotoFromGallary() ```kotlin imagePicker.choosePhotoFromGallary() ``` -8. Send Your onActivityResult to ImagePickerActivity +9. Send Your onActivityResult to ImagePickerActivity ```kotlin override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -125,14 +131,14 @@ Easy to use and configurable library to **Pick an image from the Gallery or Capt imagePicker.onActivityResult(requestCode, resultCode, data) } ``` -9. You Will Get Image Result In Uri Format In returnString() And Customize It To Upload +10. You Will Get Image Result In Uri Format In returnString() And Customize It To Upload ```kotlin override fun returnString(item: Uri?) { **Here You Will Get Your Image Result In Uri Format** } ``` -10. You can load image in your imageview using loadImage() func. (If you want to apply circleCrop() then pass isCircle = true, by default it's false) +11. You can load image in your imageview using loadImage() func. (If you want to apply circleCrop() then pass isCircle = true, by default it's false) ```kotlin override fun returnString(item: Uri?) { diff --git a/app/src/main/java/com/ssimagepicker/app/MainActivity.kt b/app/src/main/java/com/ssimagepicker/app/MainActivity.kt index f88613b..e02cf39 100644 --- a/app/src/main/java/com/ssimagepicker/app/MainActivity.kt +++ b/app/src/main/java/com/ssimagepicker/app/MainActivity.kt @@ -21,7 +21,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, ImagePickerBotto override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - imagePicker = ImagePickerActivityClass(this, this, this, activityResultRegistry) + imagePicker = ImagePickerActivityClass(this, this, activityResultRegistry, activity = this) //set to true if you want all features(crop,rotate,zoomIn,zoomOut) //by Default it's value is set to false (only crop feature is enabled) imagePicker.cropOptions(true) @@ -66,9 +66,8 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, ImagePickerBotto } } - @SuppressLint("MissingSuperCall") override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { - imagePicker.onRequestPermissionsResult(requestCode, permissions, grantResults) + super.onRequestPermissionsResult(requestCode, permissions, grantResults) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { diff --git a/buildSrc/src/main/kotlin/App.kt b/buildSrc/src/main/kotlin/App.kt index 9392132..bffc5d5 100644 --- a/buildSrc/src/main/kotlin/App.kt +++ b/buildSrc/src/main/kotlin/App.kt @@ -4,7 +4,7 @@ object App { object Version { const val CODE = 1 - const val NAME = "1.4" + const val NAME = "1.6" } object Dimension { diff --git a/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerActivityClass.kt b/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerActivityClass.kt index a65caa5..c8936c5 100644 --- a/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerActivityClass.kt +++ b/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerActivityClass.kt @@ -1,5 +1,6 @@ package com.app.imagepickerlibrary +import android.Manifest import android.annotation.SuppressLint import android.app.Activity import android.app.Activity.RESULT_OK @@ -12,17 +13,24 @@ import android.widget.Toast import androidx.activity.result.ActivityResultRegistry import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat +import androidx.fragment.app.Fragment import com.yalantis.ucrop.UCrop import java.text.SimpleDateFormat import java.util.Date import java.util.Locale -class ImagePickerActivityClass(private val context: Context, private val activity: Activity, private val callback: OnResult, registry: ActivityResultRegistry) { +class ImagePickerActivityClass(private val context: Context, private val callback: OnResult, private val registry: ActivityResultRegistry, private val activity: Activity? = null, private val fragment: Fragment? = null) { private var functionSelection = FunctionProvider.NONE private var fileUri: Uri? = null private var isCropAllFeaturesRequired: Boolean? = false + init { + if(activity == null && fragment == null) { + throw IllegalArgumentException(context.getString(R.string.error_exception_message)) + } + } + private fun checkForPermission(): Boolean { return checkPermissionForUploadImage(context) } @@ -30,9 +38,9 @@ class ImagePickerActivityClass(private val context: Context, private val activit fun takePhotoFromCamera() { functionSelection = FunctionProvider.CAMERA if (checkForPermission()) { - fileUri = activity.dispatchTakePictureIntent(onGetImageFromCameraActivityResult) + fileUri = activity?.dispatchTakePictureIntent(onGetImageFromCameraActivityResult) ?: fragment?.activity?.dispatchTakePictureIntent(onGetImageFromCameraActivityResult) } else { - askPermissionForUploadImage(activity) + askPermission() } } @@ -42,7 +50,7 @@ class ImagePickerActivityClass(private val context: Context, private val activit val galleryIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) onGetImageFromGalleryActivityResult.launch(galleryIntent) } else { - askPermissionForUploadImage(activity) + askPermission() } } @@ -71,9 +79,14 @@ class ImagePickerActivityClass(private val context: Context, private val activit } private fun startCrop(imageUri: Uri?) { - val imageFile = activity.createImageFile(SimpleDateFormat(dateFormatForTakePicture, Locale.getDefault()).format(Date())) + val imageFile = activity?.createImageFile(SimpleDateFormat(dateFormatForTakePicture, Locale.getDefault()).format(Date())) + ?: fragment?.activity?.createImageFile(SimpleDateFormat(dateFormatForTakePicture, Locale.getDefault()).format(Date())) imageUri?.let { - UCrop.of(imageUri, Uri.fromFile(imageFile)).withOptions(getUCropOptions()).start(activity) + if (activity != null) { + UCrop.of(imageUri, Uri.fromFile(imageFile)).withOptions(getUCropOptions()).start(activity) + } else if (fragment != null) { + UCrop.of(imageUri, Uri.fromFile(imageFile)).withOptions(getUCropOptions()).start(context, fragment) + } } } @@ -87,10 +100,10 @@ class ImagePickerActivityClass(private val context: Context, private val activit if (isCropAllFeaturesRequired != true) { setHideBottomControls(true) } - setToolbarColor(ContextCompat.getColor(activity, R.color.colorPrimary)) - setStatusBarColor(ContextCompat.getColor(activity, R.color.colorPrimaryDark)) - setToolbarWidgetColor(ContextCompat.getColor(activity, R.color.design_default_color_on_primary)) - setActiveControlsWidgetColor(ContextCompat.getColor(activity, R.color.colorAccent)) + setToolbarColor(ContextCompat.getColor(context, R.color.colorPrimary)) + setStatusBarColor(ContextCompat.getColor(context, R.color.colorPrimaryDark)) + setToolbarWidgetColor(ContextCompat.getColor(context, R.color.design_default_color_on_primary)) + setActiveControlsWidgetColor(ContextCompat.getColor(context, R.color.colorAccent)) } } @@ -124,4 +137,26 @@ class ImagePickerActivityClass(private val context: Context, private val activit } } } + + private fun askPermission() { + permissionResult.launch(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)) + } + + private val permissionResult = registry.register("permission", ActivityResultContracts.RequestMultiplePermissions()) { result -> + result?.let { mutableMap -> + if(mutableMap.entries.all { entry -> entry.value == true }) { + when(functionSelection) { + FunctionProvider.CAMERA -> { + takePhotoFromCamera() + } + FunctionProvider.GALLERY -> { + choosePhotoFromGallery() + } + else -> { + // + } + } + } + } + } } \ No newline at end of file diff --git a/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerBottomsheet.kt b/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerBottomsheet.kt index 1879937..266cbd0 100644 --- a/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerBottomsheet.kt +++ b/imagepickerlibrary/src/main/java/com/app/imagepickerlibrary/ImagePickerBottomsheet.kt @@ -18,6 +18,7 @@ import com.app.imagepickerlibrary.databinding.BottomsheetLayoutUploadImageOption import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import java.lang.IllegalStateException class ImagePickerBottomsheet(@LayoutRes val layoutId: Int = R.layout.bottomsheet_layout_upload_image_options) : BottomSheetDialogFragment(), View.OnClickListener { @@ -58,10 +59,10 @@ class ImagePickerBottomsheet(@LayoutRes val layoutId: Int = R.layout.bottomsheet override fun onAttach(context: Context) { super.onAttach(context) - mListener = if (context is ItemClickListener) { - context - } else { - throw RuntimeException("$context") + parentFragment?.let { fragment -> + mListener = if(fragment is ItemClickListener) fragment else throw IllegalStateException(getString(R.string.error_invalid_context_message)) + } ?: kotlin.run { + mListener = if(context is ItemClickListener) context else throw IllegalStateException(getString(R.string.error_invalid_context_message)) } } diff --git a/imagepickerlibrary/src/main/res/values/strings.xml b/imagepickerlibrary/src/main/res/values/strings.xml index 4a61691..a88aa16 100644 --- a/imagepickerlibrary/src/main/res/values/strings.xml +++ b/imagepickerlibrary/src/main/res/values/strings.xml @@ -5,4 +5,6 @@ "Camera" "Gallery" Cancel + Pass activity or fragment. + Invalid context \ No newline at end of file