Image to CloudDB

Can someone explain to me how to store the string into tiny DB or into a file?
I want to send it to Cloud DB and send it into another phone





this is my relevant blocks, which I think is kinda wrong

You can store binary files (up to 5mb in size) directly to cloudDB

Make sure you use a full path to the file, and only store the file under the tag.

1 Like

Hi

Like this:
ImageToCloudDB.aia (12.2 KB)

blocks

Edit: This code gives the illusion that it is working but in fact it does not - see TimAI2's notes below.

This is wrong (unless something has changed upstream since I lasted tested)
image

it has to be a full path to the file:

file://storage/emulated/0/Android/data/<packagename>/files/Pictures/CupCake.png
1 Like

You forget to create AppInventor Binaries folder in Asd

or as a minimum, check its existence, in the correct location :wink:

1 Like

Well, I'm open to advice, but I have posted the file and it works?

Not really, all you are doing is saving "//CupCake.jpg" to the tag value, and when this is returned, it is a valid path to the asset, so the asset image is displayed :slight_smile:

image

Working for me:

Working on Android 9, 11 (companion and built app), and the Memu emulator.

3 Likes

@Gordon_Lu

what is the value of Image1.Picture?

image

Output:

3 Likes

Ah ha - so the documentation requires a spruce-up - though I would have designed the blocks differently and had dedicated ones for uploading/downloading images.

1 Like

I didn't forget anything - the documentation has no mention of it. In my opinion, it should not be necessary for the App developer to jump through that hoop, but if you don't even tell her/him there is a hoop......... ?

I must have referred to the need for a full path @ 20 times in the last couple of years

I referred to the issue with the AppInventorBinaries folder in two previous topics about uploading/downloading an image to/from cloudDB. 'tis a problem that arose when @jis fixed the upload part of the process.

1 Like

I don't use CloudDB so I was unaware - but then so are the majority of App Inventor Users! The way it actually works though - I think it should be far more simple.

There is this thing called "search", but no-one uses it :wink:

1 Like

The OP did, hence his valiant attempt to use Base 64 encoding.

When you store an image in CloudDB, the CloudDB component takes care of base64 encoding the content of the image and storing it with an internal tag that gives the file's extension. You need to get the StoreValue() call the filename that contains the image. Normally, if you fetch an image from the Camera or the Android image gallery app, Android returns a special filename which you can then hand to CloudDB. You should never need to create AppInventorBinaries.

When you read an image from CloudDB, the component has to put it in a file, so it can give back a reference to it (filename) which can then be used with other components to display or store the content. GetValue() is not handed the filename to use, so it generates a random one and puts the file in AppInventorBinaries.

In general, Android wants you to manipulate images via various content managers. Think of the returned filename from the Camera as an opaque thing, and not attempt to do anything with it other than imagey things.

When you attempt to explicitly use files in Android, things get messy because where files live and what files your app is allowed to touch varies based on the version of Android running on the device and the "targetSdk" of the application. Then there are situations where you have to prompt the user for permission, even after including the permission in the manifest.

App Inventor's handling of files was first written years ago when there were two places you could work with files, an application private directory, or the "sdcard" which was readable/writable to all apps. In the earliest phones, the "sdcard" location only worked if the phone had a physical SDCARD installed. Later phones emulated the SDCARD if the phone didn't physically have one.

Well, you can image that sdcard access was abused, so Google has been changing how these directories are access, what permissions you need, etc. All of this is to prevent apps from messing with each other, i.e., making the App sandbox stronger.

At MIT, we have been attempting to shield the App Inventor developer from a lot of this complexity, with limited success! And each year we have to jump through new hoops. For example, if you package an App on ai2 today, is targetSdk is 30, which corresponds to Android 10 (which was a big change when it comes to file handling vs. 29). Soon we will release a version of App Inventor that targets sdk 31. We have to because Google will not let new apps into the Google Play Store unless they target sdk 31!

When I get some free time, I'm going to see if I can come up with some simple advice which should work with most version. It will likely result in storing files in the App private directory.

-Jeff

6 Likes

Thanks for the explanation!

It is Android 11 (API 30). On Android 10 it works as before, because AI2 decided to declare
requestLegacyExternalStorage=true in the Manifest.