Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.0.0 #171

Closed
wants to merge 13 commits into from
Closed

Release 2.0.0 #171

wants to merge 13 commits into from

Conversation

GuilhE
Copy link

@GuilhE GuilhE commented Feb 24, 2021

Changelog

Fork 2.0.0

  • CompressionProvider.kt logic refactor
  • Removed fun compress(maxSize: Int): Builder since it was comparing the size of the file and not the image (and the resize operation is enough);
  • Image maxResultSize (resize) algorithm refactor: fun maxResultSize(width: Int, height: Int, keepRatio: Boolean = false): Builde;
  • Replaced AsyncTask with coroutines

Fork 1.9.1


Fork 1.9.0

@costular
Copy link

costular commented Apr 16, 2021

@Dhaval2404 could you check this one please? On May 5th Google will start removing apps from Play Store which use legacy storage

@Drjacky
Copy link

Drjacky commented Apr 20, 2021

@GuilhE But in your version (release-2.0.0), the sample app compileSdkVersion and targetSdkVersion are not 30.
And if you set it to 30, even if you add

<queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
</queries>

It still shows the error:

Failed to create Camera image file

@GuilhE
Copy link
Author

GuilhE commented Apr 21, 2021

@GuilhE But in your version (release-2.0.0), the sample app compileSdkVersion and targetSdkVersion are not 30.
And if you set it to 30, even if you add

<queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
</queries>

It still shows the error:

Failed to create Camera image file

I'm using the following configuration in a project and it works with Pixel 3a running Android 11

object AndroidConstants {
    const val minSdkVersion = 24
    const val targetSdkVersion = 30
    const val compileSdkVersion = 30
    const val buildToolsVersion = "30.0.2"
}

But then I've found out that I've a merged manifest with:
<application android:requestLegacyExternalStorage="true">

So that's why it's working... 🤔 I'll dig into it as soon as possible.

@GuilhE
Copy link
Author

GuilhE commented Apr 21, 2021

@Drjacky ok quick update, I've removed that import and now there's no <application android:requestLegacyExternalStorage="true"> and it works... Do you declare any file provider?

    ...
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
    </queries>

    <application>
            ...
            <!--Providers-->
            <provider
                android:name=".utils.AppFileProvider"
                android:authorities="${applicationId}.files.provider"
                android:exported="false"
               android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_paths" />
            </provider>
    </application>

class AppFileProvider : FileProvider()

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_files"
        path="." />
</paths>

@Drjacky
Copy link

Drjacky commented Apr 21, 2021

@GuilhE
library's AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.imagepicker">

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

    <application>

        <activity
            android:name="com.example.imagepicker.ImagePickerActivity"
            android:screenOrientation="unspecified"
            android:theme="@style/Theme.Transparent.ImagePicker" />

        <activity
            android:name="com.yalantis.ucrop.UCropActivity"
            android:screenOrientation="portrait"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar" />

        <provider
            android:name="com.example.imagepicker.ImagePickerFileProvider"
            android:authorities="${applicationId}.imagepicker.provider"
            android:exported="false"
            android:grantUriPermissions="true">

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/image_picker_provider_paths" />

        </provider>

    </application>

</manifest>

Sample app's AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.imagepicker.sample">

    <queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
    </queries>

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

    <application
        android:allowBackup="true"
        android:fullBackupContent="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.example.imagepicker.sample.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Provider paths:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_files"
        path="." />
    <files-path
        name="internal_files"
        path="." />
    <cache-path
        name="cache_files"
        path="." />
</paths>

@Drjacky
Copy link

Drjacky commented Apr 21, 2021

@GuilhE Please use this sample app: https://github.com/GuilhE/ImagePicker/tree/release-2.0.0/sample
And set the targetSdk and compileSdk to 30, and you will see the error.

@GuilhE
Copy link
Author

GuilhE commented Apr 21, 2021

@Drjacky comment this line and it will work. I'll remove it from the sample.

Also, IDE complains about it:

 * @deprecated To improve user privacy, direct access to shared/external
     *             storage devices is deprecated. When an app targets
     *             {@link android.os.Build.VERSION_CODES#Q}, the path returned
     *             from this method is no longer directly accessible to apps.
     *             Apps can continue to access content stored on shared/external
     *             storage by migrating to alternatives such as
     *             {@link Context#getExternalFilesDir(String)},
     *             {@link MediaStore}, or {@link Intent#ACTION_OPEN_DOCUMENT}.
     */

If you import from Camera using the this method it works, again, because no Environment.getExternalStorageDirectory() is used.

@GuilhE
Copy link
Author

GuilhE commented Apr 21, 2021

@Drjacky new PR to avoid this problem.

@Drjacky
Copy link

Drjacky commented Apr 21, 2021

@GuilhE On this PR please try to choose the image from Gallery - On Emulator API 30

@GuilhE
Copy link
Author

GuilhE commented Apr 21, 2021

@GuilhE On this PR please try to choose the image from Gallery - On Emulator API 30

Created a new AVD with API 30, took a picture with camera, and then used the app to import from Gallery, it worked 🤔

Screenshot 2021-04-21 at 18 32 02 Screenshot 2021-04-21 at 18 32 12 Screenshot 2021-04-21 at 18 32 22 Screenshot 2021-04-21 at 18 32 35

@Drjacky
Copy link

Drjacky commented Apr 21, 2021

@GuilhE On this PR please try to choose the image from Gallery - On Emulator API 30

Created a new AVD with API 30, took a picture with camera, and then used the app to import from Gallery, it worked 🤔

Screenshot 2021-04-21 at 18 32 02 Screenshot 2021-04-21 at 18 32 12 Screenshot 2021-04-21 at 18 32 22 Screenshot 2021-04-21 at 18 32 35

You're right. with that scenario, it shows the taken picture.
What I did was, uploading a picture to the emulator in these folders:
sdcard -> DCIM -> HERE, sdcard -> DCIM -> Camera -> HERE, sdcard -> Download -> HERE, sdcard -> Pictures -> HERE, storage -> emulated -> 0 -> DCIM -> HERE, storage -> emulated -> 0 -> DCIM -> Camera -> HERE, storage -> emulated -> 0 -> Download -> HERE, storage -> emulated -> 0 -> Pictures -> HERE, storage -> 19F9-2A14 -> DCIM -> HERE, storage -> 19F9-2A14 -> DCIM -> Camera -> HERE, storage -> 19F9-2A14 -> Download -> HERE, storage -> 19F9-2A14 -> Pictures -> HERE.

And in the app, when I pressed Gallery, none of them had been listed!


Update: After a cold boot, it listed all of those pictures too ;)

@Drjacky
Copy link

Drjacky commented Apr 21, 2021

@GuilhE Same PR, which works perfectly on Android API 30,

It doesn't work on Android API 29 , x86_64,

Camera: Failed to Create camera file image
Gallery: Failed to crop the image
Screen Shot 2021-04-21 at 20 57 46

Screen Shot 2021-04-21 at 20 57 33


Update: It works on Android API 28, x86


Update: It works on Android API 21, x86


Update: It doesn't work on Android API 29, x86 either

@Drjacky
Copy link

Drjacky commented Apr 22, 2021

@GuilhE To fix the camera issue on API 29, I've changed the getCameraDirectory method to:

    private fun getCameraDirectory(context: Context): File {
        val dir =
            context.getExternalFilesDir(Environment.DIRECTORY_DCIM)// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
        return File(dir, "Camera")
    }

Now, the camera works on API 29 but, Gallery has the issue!
The root of the issue is here:

private val galleryLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == Activity.RESULT_OK) {

it.resultCode is 0 while we're waiting for -1(Activity.RESULT_OK)


Update: The root of the Gallery issue on API 29 COULD BE here getImageFile:

java.io.IOException: Permission denied

Sometimes, I'm getting permission denied!

https://developer.android.com/about/versions/11/privacy/storage


Update: with .crop in fun pickGalleryImage(view: View) {m we get resultCode = 0 and if we remove .crop(), we get -1.
Then, the issue is here:
private val galleryLauncher =
...
imgGallery.setLocalImage(file)

The set image's resolution is zero!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants