Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Github
.fork/

# Idea
**/*.iml
.idea/
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ buildscript {

ext {
sdk = [
compileSdk: 30,
compileSdk: 33,
targetSdk : 30,
minSdk : 21
]
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

<application>
<activity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import android.graphics.PorterDuff
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.ActionBar
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
Expand All @@ -21,10 +23,6 @@ import com.esafirm.imagepicker.model.Image

class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener {

companion object {
private const val RC_CAMERA = 1011
}

private val cameraModule = ImagePickerComponentsHolder.cameraModule

private var actionBar: ActionBar? = null
Expand All @@ -40,6 +38,28 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener

private val isCameraOnly by lazy { cameraOnlyConfig != null }

private val startForCameraResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
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))
}
Expand All @@ -56,7 +76,7 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener

if (isCameraOnly) {
val cameraIntent = cameraModule.getCameraIntent(this, cameraOnlyConfig!!)
startActivityForResult(cameraIntent, RC_CAMERA)
startForCameraResult.launch(cameraIntent)
return
}

Expand Down Expand Up @@ -121,7 +141,7 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener
if (!imagePickerFragment.handleBack()) {
super.onBackPressed()
}
}else {
} else {
super.onBackPressed()
}
}
Expand All @@ -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 */
/* --------------------------------------------------- */
Expand All @@ -179,4 +183,4 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener
setResult(RESULT_OK, result)
finish()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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() {

Expand All @@ -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) {
Expand Down Expand Up @@ -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 ->
Expand Down Expand Up @@ -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()
}
}

Expand All @@ -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()
Expand Down Expand Up @@ -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 {
Expand All @@ -391,4 +397,4 @@ class ImagePickerFragment : Fragment() {
}
}
}
}
}
25 changes: 25 additions & 0 deletions imagepicker/src/main/res/values-vi/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ef_permission_write_external_rationale">Cho phép truy cập bộ nhớ ngoài để chọn hình ảnh</string>

<string name="ef_ok">Đồng Ý</string>
<string name="ef_done">XONG</string>
<string name="ef_camera">CAMERA</string>

<string name="ef_title_folder">Thư mục</string>
<string name="ef_title_select_image">Nhấn để chọn hình ảnh</string>
<string name="ef_ltitle_permission_denied">Quyền bị từ chối</string>

<string name="ef_selected">%d đã chọn</string>
<string name="ef_selected_with_limit">%1$d/%2$d đã chọn</string>

<string name="ef_error_create_image_file">Không tạo được tệp hình ảnh</string>
<string name="ef_error_no_camera">Không tìm thấy máy ảnh</string>
<string name="ef_error_null_cursor">Rất tiếc, đã xảy ra lỗi!</string>

<string name="ef_msg_empty_images">Không tìm thấy hình ảnh</string>
<string name="ef_msg_no_write_external_permission">Vui lòng cấp quyền lưu trữ để chọn hình ảnh</string>
<string name="ef_msg_limit_images">Giới hạn chọn hình ảnh</string>

<string name = "ef_msg_no_camera_permission">Vui lòng cấp quyền cho máy ảnh để chụp ảnh </string>
</resources>
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<string name="ef_msg_empty_images">No images found</string>
<string name="ef_msg_no_write_external_permission">Please grant storage permission to select images</string>
<string name="ef_msg_limit_images">Image selection limit</string>
<string name="ef_msg_no_camera_permission">You have to give the app permission to use the camera to be able to take pictures</string>

<!--Don't Translate-->
<string name="ef_gif" translatable="false">GIF</string>
Expand Down
4 changes: 2 additions & 2 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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'
}
}
2 changes: 1 addition & 1 deletion sample/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<manifest xmlns:tools="http://schemas.android.com/tools"
package="com.esafirm.sample">

<uses-sdk tools:overrideLibrary="com.schibsted.spain.barista,android_libs.ub_uiautomator" />
<uses-sdk tools:overrideLibrary="com.adevinta.android.barista,android_libs.ub_uiautomator" />

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -43,4 +43,4 @@ class PickImageFragmentTest {
assertHasAnyDrawable(R.id.img_fragment)
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.esafirm.sample.MainActivity">
<activity
android:name="com.esafirm.sample.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand Down