[Free] Image Convertor: extension to convert image format jpg / png / webp (and much much more)

@TIMAI2
Testing in companion
DefaultFileScope: App
Android version 8.0.0

In this way my app works

My questions:
1 - without "Ask for permission" my app works...will this appen when I will deploy it as APK?
2 - will my blocks work when I will deploy it as APK? (I refer to path, dependence on Android version >10, <10, permission, etc...) Do you think I have to integrate some blocks in order to recognize Android version and work in different way?
3 - is it right the procedure to always use "image picker - selection" in all my blocks?
4 - my original picture in the gallery of my phone is unchanged (it is ok for me). My curiosity : does image picker create a copy and my app makes resizing in that?

I'll come back to questions 1 & 2, requires some revision/research on my part...and I will have to dig out an old device that uses the shared storage file path.

We should now understand how the ImagePicker works. When you make an image selection from the "gallery" with ImagePicker, it makes a copy of the file to shared storage (earlier android versions) or to the ASD (later android versions), and gives it a different file name. You can store up to 10 images in this way, try to store an 11th, and the 1st image will be removed. If you want to work on the imagePicker image, any modifications will be made to that copy, not the original.

An alternative to this, and to overcome the 10 image limit, or to work directly with the picked file, you can use the activityStarter. This is covered many times on the community, but I can show you how.

  1. Yes, this provides a valid absolute path to the copied file. You may wish to store the value/filepath to a variable though, and use that instead.

  2. As you can see from the above, yes, the imagePicker makes a copy, and your blocks are working on that copy, not the original image, which will remain untouched.

Much may depend on what you intend to do with the modified image file...

Thank you @TIMAI2 for your answer.
I'm in standby mode for questions 1 and 2
:slight_smile:

To keep this chugging along as I test.

On Android 7 ( early android version) you need to ask for WriteExternalStorage permission for the compiled apk:

image

The user will get a one time notification to set this. They need to say yes.

Now if memory serves me correctly, from Android 10 you still need WRITEEXTERNALSTORAGE permission, because the imagepicker is still working in shared storage. But from Android 13 onwards, imagepicker uses the ASD, so no write permission should be needed, however you will probably need READ_MEDIA_IMAGES permission to get images from shared storage.

( I am sure I will be corrected if I have this wrong :wink: )

Glad you started ?

Me, I generally do not bother with any of this, and either work with files in the ASD or use the SAF extensions to give me read / write access to files in shared storage without having to worry about permissions.

Thank you @TIMAI2 for this introduction to the theme of file storage... This is school for me!
What can I do to make my app ready to work with all Android configuration?
If your answer will be ASD, could you kindly share info (or blocks) relating to how correctly use ASD in MIT App Inventor? I have not well understood what ASD is.

and also with the files in shared storage.

What is your aim for users to be doing in your app?

If we understand this then we can move forward from there.

Hi @TIMAI2
My app will allow users to select an image from smartphone and store it (after downscaling) in Firebase Storage by using your web component as in discussion

Probably this:

image

but see here:

especially the very last section.

If you want to know how to use SAF:

Or, if you are not intending to publish to Google Play:

There are several non-numeric Android versions:
Android 4.0.1 – 4.0.2 (API 14)
Android 4.0.3 – 4.0.4 (API 15)
Android 4.4W (API 20)
Android 12L (API 32)

and WRITE_EXTERNAL_STORAGE no longer exists on Android 11 and 12 (Android 11+).

1 Like

@Anke tanks for your contribution.
I'm not an expert, so I try to do my best... but this topic is a bit too complicated...

Considering that

what are the blocks I have to use in order to deploy my app and be sure it will work on all Android version?

Do I have to set different scope in designer, or use filescope blocks, or use permission blocks...?

When I read Android documents I found this
"Direct access to media files (except audio files) using READ_MEDIA_IMAGES and/or READ_MEDIA_VIDEO (on Android 13+) will no longer be permitted for apps in the Play Store starting May 28, 2025 (at least not without an explicit review of the app and its core functionality by Google)."
What do you think about?

I haven't followed the entire thread regarding your problem/question. So please post all relevant blocks, and ideally also the AIA. Please also explain the exact goal of the app and which steps should be performed in which order. Also, let us know whether your app should be published on the Play Store.

Hi @Anke
In the same app I woud like to use these blocks

And these

Steps are

FIRST SET OF BLOCKS
1 users use image picker to select an image
2 image is resized

SECOND SET OF BLOCKS
3 resized image is stored in Firebase storage by using web component
4 other users can access to Firebase storage to open the resized image

My questions

My app will be published in Google Play

It will get complicated in sdk 35...
I asked Gemini

To publish an app in Google Play targeting sdk 35, which should run also on older devices, which permissions have to be requested depending on the API versions of the devices to pick an image from the gallery?

Below is the response
Do we already have a photo picker?
EDIT: probably the file picker component can help here?

Taifun


The recommended and most privacy-friendly way to pick an image from the gallery, especially when targeting SDK 35 (Android 15), is to use the Android Photo Picker.

The crucial point is that by using the Photo Picker, you do not need to request any storage permissions from the user, regardless of the device's API version, as long as the Photo Picker is available.

Here is a breakdown of the requirements for your app to pick an image while ensuring compatibility with older devices:

  1. Primary Recommendation: Use the Photo Picker API
    The best strategy is to use the Photo Picker via the ActivityResultContracts.PickVisualMedia() contract. This is Google's preferred method for one-time or infrequent media selection because it significantly enhances user privacy and is required for compliance with Google Play policies for many use cases.
Device API Version Permissions Required in AndroidManifest.xml Key Notes
API 33 (Android 13) and later None The Photo Picker is available natively on these devices.
API 19 (Android 4.4) up to API 32 (Android 12) None The Photo Picker is available via backport through Google Play Services. You need to ensure the backported module is triggered (usually by adding a specific service declaration in your Manifest).

Crucial Steps for Photo Picker:

  • Use the isPhotoPickerAvailable() method to check if the Photo Picker is supported on the device.
  • Launch the picker using PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly).
  • If the Photo Picker is not available (e.g., very old devices or devices without Google Play Services), you must fall back to the older method (see Section 2).
  1. Fallback for Devices Without Photo Picker
    For older devices where the Photo Picker is unavailable, you will have to use the traditional ACTION_GET_CONTENT or ACTION_PICK Intent, which requires different permissions based on the Android version.
Device API Version Permission Required in AndroidManifest.xml Key Notes
API 33 (Android 13) READ_MEDIA_IMAGES (Runtime permission) READ_EXTERNAL_STORAGE is ignored for apps targeting API 33+. You must request READ_MEDIA_IMAGES for full gallery access.
API 23 (Android 6.0) to API 32 (Android 12) READ_EXTERNAL_STORAGE (Runtime permission) This is the required permission for reading media files from the shared storage.
API 22 (Android 5.1) and lower READ_EXTERNAL_STORAGE (Install-time permission) Permissions are granted at install time; no runtime request is necessary.

To implement the fallback correctly in your Manifest, you would declare the necessary permissions and use the maxSdkVersion attribute to prevent the deprecated ones from being required on newer systems:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:maxSdkVersion="33"/>

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

By targeting SDK 35, you'll need to handle the logic in your code to check the API level and the availability of the Photo Picker to determine which approach to use and which permission to request at runtime (if any).


If you must avoid the Photo Picker entirely, you have to use the traditional Intent approach (like ACTION_GET_CONTENT or ACTION_PICK) and manage permissions based on the device's API level.

Be aware: Google strongly recommends the Photo Picker for most applications and may reject apps on Google Play that request broad media access permissions (READ_MEDIA_IMAGES, READ_EXTERNAL_STORAGE) for infrequent or non-core use cases.
When targeting SDK 35, you must implement logic to request the appropriate permission at runtime, depending on the device's Android version:

Permissions in AndroidManifest.xml
You must declare all three relevant permissions in your manifest. The maxSdkVersion attribute is crucial to indicate which permissions apply to which maximum OS version, allowing the newest granular permissions to take over on modern devices.

Permission Purpose maxSdkVersion
READ_MEDIA_IMAGES Read images on Android 13 (API 33) and Android 14 (API 34) 34
READ_MEDIA_VISUAL_USER_SELECTED Required for reselection on Android 14 (API 34) and higher when using a custom picker, allowing temporary access to selected media. (Not strictly limited, but primarily for API 34+)
READ_EXTERNAL_STORAGE Read media on Android 12 (API 32) and earlier. 32
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:maxSdkVersion="34"/>
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>

Runtime Permission Logic by API Version
Your app must check the device's current API level and request the appropriate permission before launching the image selection Intent.

Device API Version Permission to Request at Runtime Image Picking Intent
API 34+ (Android 14+) READ_MEDIA_IMAGES (or READ_MEDIA_VISUAL_USER_SELECTED for temporary access) Intent.ACTION_GET_CONTENT or Intent.ACTION_PICK
API 33 (Android 13) READ_MEDIA_IMAGES Intent.ACTION_GET_CONTENT or Intent.ACTION_PICK
API 23-32 (Android 6.0 - 12) READ_EXTERNAL_STORAGE Intent.ACTION_GET_CONTENT or Intent.ACTION_PICK
API < 23 (Android < 6.0) None (Permission granted at install time) Intent.ACTION_GET_CONTENT or Intent.ACTION_PICK

Best Practice for Intent:
For picking a single image, use Intent.ACTION_GET_CONTENT with setType("image/*"). This action is often preferred as it allows the system to determine the best available data provider (e.g., Photos, Gallery, Drive), and it automatically grants temporary read access to the returned Uri.

@Taifun thanks for your contribution
As I said, I'm not an expert so this topic form me is not easy to understand.
I ask for easier way to solve my compatibility question.
Is it possible to directly share the blocks I can use to make an app working with all Android version?
Alternatively a guide step by step is appreciated.

This

Is probably as close as you can get.

Try this on all Android versions:

To avoid storage permission issues, use ActivityStarter instead of ImagePicker (see my blocks below). Also, use Sunny's Picasso extension instead of the Image component. This allows you to display the image without READ permission by accessing the source image's contentUri. This works not only on Android 11+, but also on Android < 11.

On Android 11+, you can also copy the selected image to /Pictures/ using its contentUri under a new name, giving you full access to this file via the app and requiring neither storage permissions nor SAF.

On Android < 11, of course, WRITE permission is required to modify/compress the image, etc. That's it. It couldn't be simpler.

Blocks


In summary:
On Android 11+, no permissions are required for this at all (not even for modifying/compressing the image). On Android 6-10 it must be explicitly requested. Below it is granted automatically at install-time.

1 Like

This approach picks an image, makes a copy, resizes, uploads to FirebaseStorage and returns uploaded image to image component...assumes open rules on firebase and a folder to store the images.

pickResizeUploadImage_blank.aia (39.3 KB)

Uses SimpleSaf & ImageConvertor extensions. No permissions should be required.
.
.
I have also just tested, and it seems one can use the FilePicker component for this as well:

Tank you so much to all of you.
You are all great. your help and your info sharing is a noble work.
I will test all the answers and will give you my feedback.
Thanks!!