I think Android 11 devices does not use the WRITE_EXTERNAL_STORAGE permission! Use the MANAGE_EXTERNAL_STORAGE permission.
I may have seen that same problem in the new release notes in the forum.
See this:
I think Android 11 devices does not use the WRITE_EXTERNAL_STORAGE permission! Use the MANAGE_EXTERNAL_STORAGE permission.
I may have seen that same problem in the new release notes in the forum.
See this:
Indeed WRITE_EXTERNAL_STORAGE doesn't exist for API 30+. What I don't understand is why taking a picture using the camera needs write permissions. Because there are folders which don't need write permissions (ASD, media folders, perhaps more).
I guess the camera component is outdated.
Maybe ask a mod or a file expert, e.g. @Taifun. Did the camera save files to the device external storage?
Indeed a blank project with just a camera component, says write permissions are needed, and doesn't work. it's definitely a problem of outdated camera component.
yep, I am having exactly the same problem, but I couldn't figure out if it is the camera at fault or the canvas, but looking at your post it does seem to be the camera component. hopefully a fix is devised for this asap
Yes, this is another bug. → @ewpatton
cameraSdk30.aia (1.7 KB)
The Camera
component saves the picture in the ASD
for devices with Android > 9. This doesn't require WRITE
permission, which by the way is no longer available under Android 11.
But as a work-around, the problem can be bypassed if → DefaultFileScope
is set to Legacy in the Designer:
Through this READ
and WRITE
are declared in the Manifest
for all Android versions. WRITE
permission for Android 11 actually makes no sense, however, because as I said, it is no longer available under Android 11. But the (wrong) logic of the Camera component requests this permission incorrectly.
So you have to grant this permission (also on devices with Android 10+, which of course should not be the case):
There is a camera extension that works perfectly now.
To take a picture, just do something like this:
Note that you have to use /Pictures or /DCIM folder because of the new API storage access limitations. This example works perfectly.
Also the extension has a ton of features to work with cameras.
The camera component, the camera intent, and Small Camera Extension don't work right now.
Dear all,
I am so happy to have found this community.
I have changed, as @Anke said, the Screen1 to Legacy and it works great.
of course I need to change a few settings to show it better and to add a button that turns the picture if it is not displayed the right way up. but that should be no proble
Thanks all!
If your App is for your use only, all is well. If you want to distribute your App via Google Play Store, the App is likely to be rejected because of the use of Legacy.
What do you mean by that?
DefaultFileScope = Legacy
changes the storage permissions that are declared in the Manifest.
However, this does not affect whether the app is rejected in the Play Store or not.
this is the wrong advice, because usually apps, which use that permission are rejected by Google, see here, there are a few exceptions...
I change the category of the thread to Bugs and Other Issues
thank you @Anke
Taifun
@ChrisWard @Anke So is there any downside to using DefaultFileScope:Legacy
? What should devs watch for, when using this option?
So is there any downside to using
DefaultFileScope:Legacy
? What should devs watch for, when using this option?
Well, I believe there is because it is effectively circumventing Google's security measures (Android 11), but Anke thinks there is not. Anke is the expert Power User in file handling/paths. The help says that Legacy will not work on Android 11 +.(via App Inventor).
http://ai2.appinventor.mit.edu/reference/components/storage.html#File
Your work-around Topic is a great help to everyone. It would be good if App Inventor had a switch that everyone could understand e.g. 'For Android 10 and below' and 'For Android 11 and up'.
API 30 workarounds by anonwins:
API 30 introduced some new limitations. These limitations have not yet been completely implemented in AI2, so many components/extensions don't work as expected, or at all. Contents: API 30 doesn't support WRITE_EXTERNAL_STORAGE permission. If you need to write to the external storage, you must use a shared folder. Affected components/extensions: Camera component: doesn't work (relies on WRITE_EXTERNAL_STORAGE). File component: doesn't work for writing to external storage (same reason). …
You can not make a switch for the relevant android versions. We remember that Apps are not created under a given version of Android. Apps must be universal and work the same under every version of Android.
It's best to move your thinking, towards Android 11, and forget that in older versions it was possible to save files in any folder. Create all new Apps by using Android's behavior 11. Even when we create and test APP on Android 9 or older. So we use ASD and shared folders.
So is there any downside to using
DefaultFileScope:Legacy
?
if in doubt, let's take a look together into the App Inventor sources
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2021 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.components.common;
import java.util.HashMap;
import java.util.Map;
/**
* The FileScope enum identifies the set of scopes that App Inventor understands. Not all scopes
* are relevant to every platform version App Inventor may run on.
*
* @author ewpatton@mit.edu (Evan W. Patton)
*/
public enum FileScope implements OptionList<String> {
/**
* Operations should occur in the app-specific directory on the "external" storage. This is the
* default. Since app-specific storage is only supported on SDK 8 and later, this should behave
This file has been truncated. show original
Legacy: Operations should occur using legacy logic (pre-nb186). This may break on newer Android
versions and make apps incompatible with Google Play Store guidelines.
Taifun
That has always been the aim Patryk but the new rules on external directories have made it impossible for Android 11 Apps to support their own external paths and those who are sticking with Android 10 and below wish to continue with that capability. I'd like to see the world-wide figures on Android 11, I'm guessing that much lower versions completely out weigh it as there are whole countries where most of the population cannot afford the current super-expensive phones.
You can continue older behavior for older android versions, but only if we use such an app on our phone or for educational purposes. But I think that science no already supported methods is not a good idea, if we provide this app in the Play store, it will be rejected because it would be impossible to use it on the new Android. I think we should bring everyone on using new methods, regardless of the Android version so that it does not make a greater mess than it is.
Good morning all,
So if I understand correctly, using the defaultfilescope in legacy mode will prevent me from putting it on google play due to it going against security or regulation standards?
What would be a reliable solution? because I will have a LOT of savable blocks in this app and before I start expanding it I would like to have a usable solution which will work 100% on older and newer versions of android.
Going with the legacy mode though is great if you don't plan to distribute it over google play!!
Thanks all and I will will wait patiently if someone has a solution.
Thanks!
You could check my guide: (take a look at section 1-2: using the camera)
API 30 introduced some new limitations. These limitations have not yet been completely implemented in AI2, so many components/extensions don't work as expected, or at all. Contents: API 30 doesn't support WRITE_EXTERNAL_STORAGE permission. If you need to write to the external storage, you must use a shared folder. Affected components/extensions: Camera component: doesn't work (relies on WRITE_EXTERNAL_STORAGE). File component: doesn't work for writing to external storage (same reason). …
In the guide I mention that a proper way to save to external is to use shared folders. This is future-proof. If you follow my guide, you won't have problems with write permissions, and also you don't need to change the project's file scope. What I propose is to use the Pro Camera extension, which doesn't rely on write_permissions. Still you'll have to save the photos either in the ASD, or a shared folder (/Pictures or /DCIM). Writing to those directories does not require WRITE_EXTERNAL_STORAGE and is recommended by Android.
I first mentioned it here in this thread.
There is a camera extension that works perfectly now. To take a picture, just do something like this: [blocks(5)] Note that you have to use /Pictures or /DCIM folder because of the new API storage access limitations. This example works perfectly. Also the extension has a ton of features to work with cameras. The camera component, the camera intent, and Small Camera Extension don't work right now.
What I didn't mention though is that it's future-proof. It doesn't rely on outdated permissions or legacy mode. It's pure API 30+ compatible protocol/method.
Please let me summarize one more time:
The camera component is broken: you can replace it with Pro Camera extension.
The file component is broken: you can replace it with TaifunFile extension.Done! API 30 is yours.
You're future-proof. No manifest editing, no flags setting, nothing.
You write into the shared folders, and that's what android wants you to do.
Final disclaimer: I really don't know what "legacy mode" is. I'm not sure it's an outdated thing. The opinions vary.
From the AI2 reference page we get this:
Legacy: Files will be read from and written to the file system using the App Inventor rules prior to release nb187. That is, file names starting with a single
/
will be read from and written to the root of the external storage directory, e.g.,/sdcard/
. Legacy functionality will not work on Android 11 or later.
But, I'm asking, /Pictures
(for example) is not a valid shared folder path? In my understanding, it probably is. But maybe I'm wrong, and the only up-to-date way is to use full path (/storage/emulated/0/Pictures
). I know full path works (without legacy mode). But not on the built-in components.
What is a full path anyway? (I'm getting philosophical here). There are just mount points. And what we call "file scope" sounds like "mount point" to me. But back on track, /storage/emulated/0/Pictures/myphoto.jpg
is considered a full path and works well with components/extensions that don't rely on write_external permission.