diff --git a/.gitignore b/.gitignore index a58f683e..6d6970cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Github +.fork/ + # Idea **/*.iml .idea/ diff --git a/build.gradle b/build.gradle index 82b7a730..5a8449c5 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ buildscript { ext { sdk = [ - compileSdk: 30, + compileSdk: 33, targetSdk : 30, minSdk : 21 ] diff --git a/imagepicker/src/main/AndroidManifest.xml b/imagepicker/src/main/AndroidManifest.xml index 09492d3f..d47672f4 100644 --- a/imagepicker/src/main/AndroidManifest.xml +++ b/imagepicker/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + + if (result.resultCode == Activity.RESULT_OK) { + val intent = result.data + // Handle the Intent + if (intent?.extras?.isEmpty == true) { + cameraModule.removeImage(this) + setResult(RESULT_CANCELED) + finish() + } else { + cameraModule.getImage(this, intent) { images -> + finishPickImages(ImagePickerUtils.createResultIntent(images)) + } + } + } else { + cameraModule.removeImage(this) + setResult(RESULT_CANCELED) + finish() + } + } + override fun attachBaseContext(newBase: Context) { super.attachBaseContext(LocaleManager.updateResources(newBase)) } @@ -56,7 +76,7 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener if (isCameraOnly) { val cameraIntent = cameraModule.getCameraIntent(this, cameraOnlyConfig!!) - startActivityForResult(cameraIntent, RC_CAMERA) + startForCameraResult.launch(cameraIntent) return } @@ -121,7 +141,7 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener if (!imagePickerFragment.handleBack()) { super.onBackPressed() } - }else { + } else { super.onBackPressed() } } @@ -142,22 +162,6 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - if (resultCode == Activity.RESULT_CANCELED) { - cameraModule.removeImage(this) - setResult(RESULT_CANCELED) - finish() - return - } - if (requestCode == RC_CAMERA && resultCode == Activity.RESULT_OK) { - cameraModule.getImage(this, data) { images -> - val result = ImagePickerUtils.createResultIntent(images) - finishPickImages(result) - } - } - } - /* --------------------------------------------------- */ /* > ImagePickerInteractionListener Methods */ /* --------------------------------------------------- */ @@ -179,4 +183,4 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener setResult(RESULT_OK, result) finish() } -} \ No newline at end of file +} diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.kt b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.kt index 23563fba..866dda7e 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.kt +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.kt @@ -7,6 +7,7 @@ import android.content.Intent import android.content.pm.PackageManager import android.content.res.Configuration import android.net.Uri +import android.os.Build import android.os.Bundle import android.os.Parcelable import android.provider.Settings @@ -31,7 +32,6 @@ import com.esafirm.imagepicker.helper.IpLogger import com.esafirm.imagepicker.helper.state.fetch import com.esafirm.imagepicker.model.Folder import com.esafirm.imagepicker.model.Image -import java.util.ArrayList class ImagePickerFragment : Fragment() { @@ -46,6 +46,13 @@ class ImagePickerFragment : Fragment() { requireArguments().getParcelable(ImagePickerConfig::class.java.simpleName)!! } + private val permission: String + get() { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + Manifest.permission.READ_MEDIA_IMAGES + } else Manifest.permission.WRITE_EXTERNAL_STORAGE + } + private val requestPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted -> if (isGranted) { @@ -176,7 +183,10 @@ class ImagePickerFragment : Fragment() { resources.configuration.orientation ).apply { val selectListener = { isSelected: Boolean -> selectImage(isSelected) } - val folderClick = { bucket: Folder -> setImageAdapter(bucket.images) } + val folderClick = { bucket: Folder -> + setImageAdapter(bucket.images) + updateTitle() + } setupAdapters(passedSelectedImages, selectListener, folderClick) setImageSelectedListener { selectedImages -> @@ -244,14 +254,11 @@ class ImagePickerFragment : Fragment() { * Check permission */ private fun loadDataWithPermission() { - val rc = ActivityCompat.checkSelfPermission( - requireContext(), - Manifest.permission.WRITE_EXTERNAL_STORAGE - ) + val rc = ActivityCompat.checkSelfPermission(requireContext(), permission) if (rc == PackageManager.PERMISSION_GRANTED) { loadData() } else { - requestWriteExternalPermission() + requestWriteExternalOrReadImagesPermission() } } @@ -262,13 +269,13 @@ class ImagePickerFragment : Fragment() { * If permission denied or app is first launched, request for permission * If permission denied and user choose 'Never Ask Again', show snackbar with an action that navigate to app settings */ - private fun requestWriteExternalPermission() { - IpLogger.w("Write External permission is not granted. Requesting permission") - val permission = Manifest.permission.WRITE_EXTERNAL_STORAGE + private fun requestWriteExternalOrReadImagesPermission() { + IpLogger.w("Write External permission or Read Media Images is not granted. Requesting permission") when { shouldShowRequestPermissionRationale(permission) -> { requestPermissionLauncher.launch(permission) } + else -> { if (!preferences.isPermissionRequested()) { preferences.setPermissionIsRequested() @@ -380,7 +387,6 @@ class ImagePickerFragment : Fragment() { private const val STATE_KEY_SELECTED_IMAGES = "Key.SelectedImages" private const val RC_CAPTURE = 2000 - private const val RC_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 23 fun newInstance(config: ImagePickerConfig): ImagePickerFragment { val args = Bundle().apply { @@ -391,4 +397,4 @@ class ImagePickerFragment : Fragment() { } } } -} \ No newline at end of file +} diff --git a/imagepicker/src/main/res/values-vi/strings.xml b/imagepicker/src/main/res/values-vi/strings.xml new file mode 100644 index 00000000..acdad396 --- /dev/null +++ b/imagepicker/src/main/res/values-vi/strings.xml @@ -0,0 +1,25 @@ + + + Cho phép truy cập bộ nhớ ngoài để chọn hình ảnh + + Đồng Ý + XONG + CAMERA + + Thư mục + Nhấn để chọn hình ảnh + Quyền bị từ chối + + %d đã chọn + %1$d/%2$d đã chọn + + Không tạo được tệp hình ảnh + Không tìm thấy máy ảnh + Rất tiếc, đã xảy ra lỗi! + + Không tìm thấy hình ảnh + Vui lòng cấp quyền lưu trữ để chọn hình ảnh + Giới hạn chọn hình ảnh + + Vui lòng cấp quyền cho máy ảnh để chụp ảnh + diff --git a/imagepicker/src/main/res/values/strings.xml b/imagepicker/src/main/res/values/strings.xml index 74c80b92..4f33fbad 100644 --- a/imagepicker/src/main/res/values/strings.xml +++ b/imagepicker/src/main/res/values/strings.xml @@ -20,6 +20,7 @@ No images found Please grant storage permission to select images Image selection limit + You have to give the app permission to use the camera to be able to take pictures GIF diff --git a/sample/build.gradle b/sample/build.gradle index 16d27fb6..6ead8d61 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -48,7 +48,7 @@ dependencies { /* Development */ implementation project(':imagepicker') - debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.6' + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1' implementation "androidx.core:core-ktx:$core_ktx_version" /* UI Test */ @@ -58,7 +58,7 @@ dependencies { androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion" androidTestImplementation "androidx.test:runner:$runnerVersion" androidTestImplementation "androidx.test:rules:$runnerVersion" - androidTestImplementation('com.schibsted.spain:barista:3.7.0') { + androidTestImplementation('com.adevinta.android:barista:3.10.0') { exclude group: 'org.jetbrains.kotlin' } } diff --git a/sample/src/androidTest/AndroidManifest.xml b/sample/src/androidTest/AndroidManifest.xml index b81f1910..15b85903 100644 --- a/sample/src/androidTest/AndroidManifest.xml +++ b/sample/src/androidTest/AndroidManifest.xml @@ -2,6 +2,6 @@ - + diff --git a/sample/src/androidTest/java/com/esafirm/sample/CameraOnPickerTest.kt b/sample/src/androidTest/java/com/esafirm/sample/CameraOnPickerTest.kt index bc2722e9..89ea64e3 100644 --- a/sample/src/androidTest/java/com/esafirm/sample/CameraOnPickerTest.kt +++ b/sample/src/androidTest/java/com/esafirm/sample/CameraOnPickerTest.kt @@ -11,9 +11,9 @@ import androidx.test.rule.ActivityTestRule import androidx.test.rule.GrantPermissionRule import com.esafirm.sample.utils.ViewAsserts import com.esafirm.sample.utils.Views -import com.schibsted.spain.barista.intents.BaristaIntents.mockAndroidCamera -import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn -import com.schibsted.spain.barista.interaction.BaristaMenuClickInteractions +import com.adevinta.android.barista.intents.BaristaIntents.mockAndroidCamera +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.interaction.BaristaMenuClickInteractions import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith diff --git a/sample/src/androidTest/java/com/esafirm/sample/CameraOnlyTest.kt b/sample/src/androidTest/java/com/esafirm/sample/CameraOnlyTest.kt index 158225f9..58bd5ff1 100644 --- a/sample/src/androidTest/java/com/esafirm/sample/CameraOnlyTest.kt +++ b/sample/src/androidTest/java/com/esafirm/sample/CameraOnlyTest.kt @@ -18,9 +18,9 @@ import androidx.test.runner.AndroidJUnit4 import com.esafirm.sample.matchers.hasDrawable import com.esafirm.sample.utils.ViewAsserts import com.esafirm.sample.utils.Views -import com.schibsted.spain.barista.assertion.BaristaVisibilityAssertions.assertDisplayed -import com.schibsted.spain.barista.intents.BaristaIntents.mockAndroidCamera -import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed +import com.adevinta.android.barista.intents.BaristaIntents.mockAndroidCamera +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith diff --git a/sample/src/androidTest/java/com/esafirm/sample/CustomUiTest.kt b/sample/src/androidTest/java/com/esafirm/sample/CustomUiTest.kt index 7133c6ab..0a63d3d1 100644 --- a/sample/src/androidTest/java/com/esafirm/sample/CustomUiTest.kt +++ b/sample/src/androidTest/java/com/esafirm/sample/CustomUiTest.kt @@ -11,7 +11,7 @@ import androidx.test.rule.GrantPermissionRule import androidx.test.runner.AndroidJUnit4 import com.esafirm.sample.utils.ViewAsserts import com.esafirm.sample.utils.Views -import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith diff --git a/sample/src/androidTest/java/com/esafirm/sample/PickImageFolderMode.kt b/sample/src/androidTest/java/com/esafirm/sample/PickImageFolderMode.kt index 15c8f11f..e3d7a20d 100644 --- a/sample/src/androidTest/java/com/esafirm/sample/PickImageFolderMode.kt +++ b/sample/src/androidTest/java/com/esafirm/sample/PickImageFolderMode.kt @@ -10,7 +10,7 @@ import androidx.test.rule.ActivityTestRule import androidx.test.rule.GrantPermissionRule import com.esafirm.sample.utils.ViewAsserts import com.esafirm.sample.utils.Views -import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith diff --git a/sample/src/androidTest/java/com/esafirm/sample/PickImageFragmentTest.kt b/sample/src/androidTest/java/com/esafirm/sample/PickImageFragmentTest.kt index 1ddac9c4..aa37571e 100644 --- a/sample/src/androidTest/java/com/esafirm/sample/PickImageFragmentTest.kt +++ b/sample/src/androidTest/java/com/esafirm/sample/PickImageFragmentTest.kt @@ -8,9 +8,9 @@ import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner import androidx.test.rule.ActivityTestRule import androidx.test.rule.GrantPermissionRule import com.esafirm.sample.utils.Views -import com.schibsted.spain.barista.assertion.BaristaImageViewAssertions.assertHasAnyDrawable -import com.schibsted.spain.barista.assertion.BaristaVisibilityAssertions.assertDisplayed -import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.assertion.BaristaImageViewAssertions.assertHasAnyDrawable +import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -43,4 +43,4 @@ class PickImageFragmentTest { assertHasAnyDrawable(R.id.img_fragment) } -} \ No newline at end of file +} diff --git a/sample/src/androidTest/java/com/esafirm/sample/PickImageSingleTest.kt b/sample/src/androidTest/java/com/esafirm/sample/PickImageSingleTest.kt index 5168308c..4e199f6f 100644 --- a/sample/src/androidTest/java/com/esafirm/sample/PickImageSingleTest.kt +++ b/sample/src/androidTest/java/com/esafirm/sample/PickImageSingleTest.kt @@ -10,7 +10,7 @@ import androidx.test.rule.ActivityTestRule import androidx.test.rule.GrantPermissionRule import com.esafirm.sample.utils.ViewAsserts import com.esafirm.sample.utils.Views -import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index f3acd351..acec947c 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -8,7 +8,9 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - +