Skip to content

Commit

Permalink
Added scoped storage support
Browse files Browse the repository at this point in the history
Added scoped storage support and removed redundant storage permission.

#29 #75
  • Loading branch information
Dhaval2404 committed Apr 28, 2020
1 parent d26715d commit e6cb1fa
Show file tree
Hide file tree
Showing 23 changed files with 397 additions and 225 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
/.idea/gradle.xml
/.idea/runConfigurations.xml
/.idea/codeStyles
/.idea/dictionaries
/.idea/icon.png
.DS_Store
/build
/captures
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
![Language](https://img.shields.io/badge/language-Kotlin-orange.svg)
[![Android Arsenal]( https://img.shields.io/badge/Android%20Arsenal-ImagePicker-green.svg?style=flat )]( https://android-arsenal.com/details/1/7510 )
[![PRWelcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Dhaval2404/ImagePicker)
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/Dhaval2404)
[![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://opensource.org/licenses/Apache-2.0)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/Dhaval2404/ImagePicker/blob/master/LICENSE)
[![Twitter](https://img.shields.io/twitter/url/https/github.com/Dhaval2404/ImagePicker.svg?style=social)](https://twitter.com/intent/tweet?text=Check+out+an+ImagePicker+library+to+Pick+an+image+from+the+Gallery+or+Capture+an+image+with+Camera.+https%3A%2F%2Fgit.luolix.top%2FDhaval2404%2FImagePicker+%40dhaval2404+%23Android+%23Kotlin+%23AndroidDev)

<div align="center">
Expand Down
7 changes: 4 additions & 3 deletions imagepicker/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ apply plugin: 'kotlin-android-extensions'
apply from: "../ktlint.gradle"

android {
compileSdkVersion 28
compileSdkVersion 29


defaultConfig {
minSdkVersion 19
targetSdkVersion 28
targetSdkVersion 29
versionCode 9
versionName "1.7.1"

Expand Down Expand Up @@ -46,7 +46,8 @@ dependencies {

implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation "androidx.exifinterface:exifinterface:1.1.0"
implementation "androidx.exifinterface:exifinterface:1.2.0"
implementation 'androidx.documentfile:documentfile:1.0.1'

//More Info: https://github.com/Yalantis/uCrop
implementation 'com.github.yalantis:ucrop:2.2.4'
Expand Down
3 changes: 0 additions & 3 deletions imagepicker/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.dhaval2404.imagepicker">

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

<application>

<activity android:name=".ImagePickerActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,21 @@ open class ImagePicker {
/**
* Get File Path from intent
*/
@Deprecated(
message = "Avoid using the File object, It will require storage permission",
replaceWith = ReplaceWith("Consider using Uri Object instead")
)
fun getFilePath(data: Intent?): String? {
return data?.getStringExtra(EXTRA_FILE_PATH)
}

/**
* Get File from intent
*/
@Deprecated(
message = "Avoid using the File object, It will require storage permission",
replaceWith = ReplaceWith("Consider using Uri Object instead")
)
fun getFile(data: Intent?): File? {
val path = getFilePath(data)
if (path != null) {
Expand Down Expand Up @@ -123,7 +131,7 @@ open class ImagePicker {
*
* Camera, Crop, Compress Image Will be store in this directory.
*
* If null, Image will be stored in {@see [Environment.DIRECTORY_DCIM]}
* If null, Image will be stored in "{fileDir}/Images"
*/
private var saveDir: String? = null

Expand Down Expand Up @@ -358,8 +366,12 @@ open class ImagePicker {
}
} catch (e: Exception) {
if (e is ClassNotFoundException) {
Toast.makeText(if (fragment != null) fragment!!.context else activity, "InlineActivityResult library not installed falling back to default method, please install " +
"it from https://github.com/florent37/InlineActivityResult if you want to get inline activity results.", Toast.LENGTH_LONG).show()
Toast.makeText(
if (fragment != null) fragment!!.context else activity,
"InlineActivityResult library not installed falling back to default method, please install " +
"it from https://github.com/florent37/InlineActivityResult if you want to get inline activity results.",
Toast.LENGTH_LONG
).show()
startActivity(REQUEST_CODE)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.github.dhaval2404.imagepicker.provider.CameraProvider
import com.github.dhaval2404.imagepicker.provider.CompressionProvider
import com.github.dhaval2404.imagepicker.provider.CropProvider
import com.github.dhaval2404.imagepicker.provider.GalleryProvider
import java.io.File
import com.github.dhaval2404.imagepicker.util.FileUriUtils

/**
* Pick Image
Expand All @@ -26,11 +26,6 @@ class ImagePickerActivity : AppCompatActivity() {
companion object {
private const val TAG = "image_picker"

/**
* Key to Save/Retrieve Image File state
*/
private const val STATE_IMAGE_FILE = "state.image_file"

internal fun getCancelledIntent(context: Context): Intent {
val intent = Intent()
val message = context.getString(R.string.error_task_cancelled)
Expand All @@ -44,32 +39,15 @@ class ImagePickerActivity : AppCompatActivity() {
private lateinit var mCropProvider: CropProvider
private lateinit var mCompressionProvider: CompressionProvider

/** File provided by GalleryProvider or CameraProvider */
private var mImageFile: File? = null

/** File provided by CropProvider */
private var mCropFile: File? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
restoreInstanceState(savedInstanceState)
loadBundle(savedInstanceState)
}

/**
* Restore saved state
*/
private fun restoreInstanceState(savedInstanceState: Bundle?) {
if (savedInstanceState != null) {
mImageFile = savedInstanceState.getSerializable(STATE_IMAGE_FILE) as File?
}
}

/**
* Save all appropriate activity state.
*/
public override fun onSaveInstanceState(outState: Bundle) {
outState.putSerializable(STATE_IMAGE_FILE, mImageFile)
mCameraProvider?.onSaveInstanceState(outState)
mCropProvider.onSaveInstanceState(outState)
super.onSaveInstanceState(outState)
Expand Down Expand Up @@ -144,14 +122,13 @@ class ImagePickerActivity : AppCompatActivity() {
/**
* {@link CameraProvider} and {@link GalleryProvider} Result will be available here.
*
* @param file Capture/Gallery image file
* @param uri Capture/Gallery image Uri
*/
fun setImage(file: File) {
mImageFile = file
fun setImage(uri: Uri) {
when {
mCropProvider.isCropEnabled() -> mCropProvider.startIntent(file)
mCompressionProvider.isCompressionRequired(file) -> mCompressionProvider.compress(file)
else -> setResult(file)
mCropProvider.isCropEnabled() -> mCropProvider.startIntent(uri)
mCompressionProvider.isCompressionRequired(uri) -> mCompressionProvider.compress(uri)
else -> setResult(uri)
}
}

Expand All @@ -160,54 +137,47 @@ class ImagePickerActivity : AppCompatActivity() {
*
* Check if compression is enable/required. If yes then start compression else return result.
*
* @param file Crop image file
* @param uri Crop image uri
*/
fun setCropImage(file: File) {
mCropFile = file

mCameraProvider?.let {
// Delete Camera file after crop. Else there will be two image for the same action.
// In case of Gallery Provider, we will get original image path, so we will not delete that.
mImageFile?.delete()
mImageFile = null
}
fun setCropImage(uri: Uri) {
// Delete Camera file after crop. Else there will be two image for the same action.
// In case of Gallery Provider, we will get original image path, so we will not delete that.
mCameraProvider?.delete()

if (mCompressionProvider.isCompressionRequired(file)) {
mCompressionProvider.compress(file)
if (mCompressionProvider.isCompressionRequired(uri)) {
mCompressionProvider.compress(uri)
} else {
setResult(file)
setResult(uri)
}
}

/**
* {@link CompressionProvider} Result will be available here.
*
* @param file Compressed image file
* @param uri Compressed image Uri
*/
fun setCompressedImage(file: File) {
fun setCompressedImage(uri: Uri) {
// This is the case when Crop is not enabled
mCameraProvider?.let {
// Delete Camera file after Compress. Else there will be two image for the same action.
// In case of Gallery Provider, we will get original image path, so we will not delete that.
mImageFile?.delete()
}

// Delete Camera file after crop. Else there will be two image for the same action.
// In case of Gallery Provider, we will get original image path, so we will not delete that.
mCameraProvider?.delete()

// If crop file is not null, Delete it after crop
mCropFile?.delete()
mCropFile = null
mCropProvider.delete()

setResult(file)
setResult(uri)
}

/**
* Set Result, Image is successfully capture/picked/cropped/compressed.
*
* @param file final image file
* @param uri final image Uri
*/
private fun setResult(file: File) {
private fun setResult(uri: Uri) {
val intent = Intent()
intent.data = Uri.fromFile(file)
intent.putExtra(ImagePicker.EXTRA_FILE_PATH, file.absolutePath)
intent.data = uri
intent.putExtra(ImagePicker.EXTRA_FILE_PATH, FileUriUtils.getRealPath(this, uri))
setResult(Activity.RESULT_OK, intent)
finish()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.github.dhaval2404.imagepicker;
package com.github.dhaval2404.imagepicker

import androidx.core.content.FileProvider

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package com.github.dhaval2404.imagepicker.provider

import android.content.ContextWrapper
import android.os.Bundle
import android.widget.Toast
import com.github.dhaval2404.imagepicker.ImagePickerActivity
import java.io.File

/**
* Abstract Provider class
Expand All @@ -12,7 +12,13 @@ import com.github.dhaval2404.imagepicker.ImagePickerActivity
* @version 1.0
* @since 04 January 2019
*/
abstract class BaseProvider(protected val activity: ImagePickerActivity) : ContextWrapper(activity) {
abstract class BaseProvider(protected val activity: ImagePickerActivity) :
ContextWrapper(activity) {

fun getFileDir(path: String?): File {
return if (path != null) File(path)
else File(getExternalFilesDir(null), "Images")
}

/**
* Cancel operation and Set Error Message
Expand All @@ -33,15 +39,6 @@ abstract class BaseProvider(protected val activity: ImagePickerActivity) : Conte
setError(getString(errorRes))
}

/**
* Show Short Toast Message
*
* @param messageRes String message resource
*/
protected fun showToast(messageRes: Int) {
Toast.makeText(this, messageRes, Toast.LENGTH_SHORT).show()
}

/**
* Call this method when task is cancel in between the operation.
* E.g. user hit back-press
Expand Down
Loading

0 comments on commit e6cb1fa

Please sign in to comment.