Upload Widget on Android 14 doesn't allow Camera if clientAllowedFormats: 'image'
I am using the Upload Widget in a normal web page (no web-view app or anything like that).
As per title, the Widget on Android 13 and older works fine.
However on Android 14, if I pass clientAllowedFormats: 'image'
to exclude videos, then I do not have the usual Camera option after tapping "My files". I only get a list of images along with a message saying that "This app can only access the pictures you pick":
If I do not pass clientAllowedFormats: 'image'
, then after tapping My files I do get the option of using my Camera directly, but that means I'd be able to upload videos as well, and then get denied by resourceType: 'image
' after server side checks:
How do I limit the upload to images only, but also keep the possibility to take a picture directly with the camera, on Android 14?
Thank you 😊
Comments
-
Hi @Tom ,
thank you a lot, I will wait.
I do have something else to ask: I was trying to find out a list of available releases and the changelog of the Upload Widget, with no luck.
More specifically, so far I've always included something like:
<script src="https://upload-widget.cloudinary.com/2.1.15/………….
Specifying the actual version, rather than using.com/latest/…
That was to avoid breaking changes, anyway a list of the version and a changelog would help me decide when to bump. Is that available somewhere?
Best regards,
Gobbo0 -
Hi @Gobbo,
Thanks for getting back.
I'm afraid there is no release log for the upload widget currently.
One option you can do is periodically check what https://upload-widget.cloudinary.com/latest/global/all.js redirects to set your script to that version.Please let me know if you need anything else.
Kind Regards,
ThomasDeveloper Support Engineer
Customer Success team
Cloudinary UKHelpful Links For You
💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
🧑🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
📰 Check out the Cloudinary blog for the latest company news and insights0 -
Hi there,
It looks like the missing camera option on Android 14 is a result of the introduction of Granular Media Permissions by the Android platform.
This is part of security hardening by Android aiming to limit access to private photos by applications. Previously, once an app got access to photos - all of them were available. Now, by default, it's up to user discretion what to share. The native Android application might request permissions to access all of the images, including camera through the granular permissions framework. In this case - the native app is the browser itself.
The restriction applies only to images, so you may be able to work around that by not limiting the file type to images - then the restriction is not in place.
I hope this helps. If you have any questions, do not hesitate to ask.
Kind regards,
Tia
0 -
Hello Tia,
Thank you for your answer.
I might remove clientAllowedFormats: 'image' from the widget upload settings, and maintain only resourceType: 'image'.
That would allow me to select the camera device, images and videos (that however I do not want to accept in my use case).
Thanks to resourceType: 'image', if someone actually tries to record / select a video, the upload would go through, but eventually the resource will get rejected by the server.The drawback I see with this approach is that uploading videos to Cloudinary could potentially waste a lot of bandwidth quota, just to see the resource getting discarded 🤔
0 -
Hi there,
Could you use an
eval
in an upload preset? You could check for theduration
of the file. If there is a duration, that means it's a video or audio file => abort the upload.
An image would not have a duration, so it would pass the check and the upload would proceed.
You can read abouteval
here:
https://cloudinary.com/documentation/upload_parameters#eventsLet me know what you think.
Kind regards,
Tia
Developer Support Engineer
Cloudinary--
💡 Improve your site's performance by applying optimization features when delivering assets💬 Community Forums | 🧑💻 Discord Server
🧑🎓 Academy Training | 📖 Documentation | 📰 Blog0 -
Could you use an
eval
in an upload preset? You could check for theduration
of the file. If there is a duration, that means it's a video or audio file => abort the upload.I am trying to do so after reading the link you've posted (and also this), but I can't figure out how to "abort" the upload.
The following code is not working, and having access to only upload_options, I don't have other ideas 🤔
if (resource_info.duration){ return false }
0 -
Hi there,
Please try this for the
eval
if (resource_info.duration) { throw new Error("video files cannot be uploaded");}
Let me know how it goes. Of course, if you have any questions, do not hesitate to ask.
Kind regards,
Tia
Developer Support Engineer
Cloudinary--
💡 Improve your site's performance by applying optimization features when delivering assets💬 Community Forums | 🧑💻 Discord Server
🧑🎓 Academy Training | 📖 Documentation | 📰 Blog0 -
Hi Tia,
Thank you, that is indeed working! And it is raising the exception back to the Upload widget before the rejection caused by resourceType: 'image', so initially that made me think it solves my fear of wasting bandwidth quota.
However after checking the dev tools, it does look like it is still actually "uploading" to Cloudinary.
I am not sure then, isn't this still impacting on bandwidth / credit usage?
Ty
0 -
Hi there,
Can you share what you see in dev tools that makes you think the asset is being uploaded to Cloudinary? When I did testing on my account, I got a 400 response and the backend logs confirmed that as well.
No storage is charged because the asset was not uploaded. And no transformations were applied, again because the asset was not uploaded.
Bandwidth only comes into play for delivery. Only bandwidth used to deliver assets in response to requests is counted, so there's no cost implication for a failed request.Kind regards,
Tia
Developer Support Engineer
Cloudinary--
💡 Improve your site's performance by applying optimization features when delivering assets💬 Community Forums | 🧑💻 Discord Server
🧑🎓 Academy Training | 📖 Documentation | 📰 Blog0 -
Hello,
Bandwidth only comes into play for delivery. Only bandwidth used to deliver assets in response to requests is counted, so there's no cost implication for a failed request.
Okay, this statement alone solves the issue. It has been a while since I've read the docs and for some reason I was convinced that also the ingest bandwidth Cloudinary uses to receive assets counts.
To clarify the rest, for posterity:
Can you share what you see in dev tools that makes you think the asset is being uploaded to Cloudinary?
Sure. Maybe I've expressed myself wrongly, but with "uploaded" I don't mean "saved/stored".
I simply refer to the process of transferring the resource to Cloudinary:When I did testing on my account, I got a 400 response
Same for me: I see the total byte size of the video resource being transferred to Cloudinary, and eventually getting rejected because the resource has a "duration".
Beside the custom error message that I can set in the Error I throw in the eval, this is in my eyes the same behavior I noticed by simply having
resourceType: 'image'
in my Upload Widget configuration. Correct me if that's wrong.
I voiced my concern of wasting bandwidth quota by only using resourceType: 'image', and you proposed the usage of eval in the next message. Hence the confusion… I expected something different from the usage of eval (e.g. the user doesn't need to wait for the transfer completion), but from what I see it's basically the same. POST req and 400 res:- Only having
resourceType: 'image'
- After adding the expression in the upload preset eval field:
If my assumption is correct, I think I will nonetheless keep the eval because I like the possibility to return a customized error message.
Thanks
0 - Only having
-
Hi there,
My apologies. I misunderstood your message when I replied suggesting
eval
Your assumption is correct 😊Kind regards,
Tia
Developer Support Engineer
Cloudinary--
💡 Improve your site's performance by applying optimization features when delivering assets💬 Community Forums | 🧑💻 Discord Server
🧑🎓 Academy Training | 📖 Documentation | 📰 Blog0 -
Hi,
No worries and thank you for your support!
0