Get or Download a Private Image from Google Drive
This question was asked on the forum. The issue is authentication, only the owner, or those people the item is shared with, have access to view/download the file with their google accounts. To do this in AI2, you have to use an intermediate google web app, authorised by the google account owner, but for anyone, even anonymous to use. Assuming the google account owner is also the AI2 app developer, this person can then have complete control over what users can access, view and download as "private files". I guess there are many other ways to achieve the same thing, but this method seemed the most simple and straightforward.
Because the enquiry was for an image file, I chose to use the base64 encoding facility in google apps script, because the string generated can then be easily displayed as an image in a webviewer (also as requested). A second technique, using Juan Antonio's base64 extension, allows for the saving of the file to the device.
App developers will need to decide how to provide the file IDs to users. They could run another web app script that will collect the file ID and filename for a collection of files in a folder, which users can then select from using a listview/picker
In the aia examples, I have used an image of "the fallen madonna with the big boobies" famous from the TV series 'Allo 'Allo. Hope you are not offended ;)
GOOGLE APPS SCRIPT
Simple stuff, relies on the user making a get request with the File ID of the image on google drive. I have both the doGet and the doPost, one allows AI2 access, the other works in a computer browser (for testing)
function doGet(e) {
var imgID = e.parameter.imgID;
var bytes = DriveApp.getFileById(imgID).getBlob().getBytes();
return ContentService.createTextOutput(Utilities.base64Encode(bytes));
}
function doPost(e) {
var imgID = e.parameter.imgID;
var bytes = DriveApp.getFileById(imgID).getBlob().getBytes();
return ContentService.createTextOutput(Utilities.base64Encode(bytes));
}
BLOCKS
On button click, the web component is set to the url of the apps script, with the parameter of the file ID.
On return, we set the base64 string to the webviewstring, and then open a static html file which manages the webviewstring for display
HTML
The html file uses a short piece of javascript to combine the text and the webviewstring, then sets the src of the image tag. The image is then displayed
<!DOCTYPE html>
<html>
<head>
<title>Show Image</title>
</head>
<body>
<img style='display:block; width:200px;' id='base64image' src="" />
</body>
<script>
var myImg = "data:image/jpeg;base64," + window.AppInventor.getWebViewString();
document.getElementById("base64image").src = myImg;
</script>
</html>
The second example, requires Juan's base64 extension to convert the base64 string to a file which is saved to the virtual sdcard of the device. This can then be displayed in the app in any of the ways you can display an image. The aia example simply shows an image component and webviewer (again using the fallen madonna !)
This uses the same google web app as the first example.
BLOCKS
Again we get the base64 string of the image file created by the web app, after a get request using the file ID. We then convert the base64 string back to a file, give it a name, then display in an image component. At the same time we create an html file on the sdcard with the image info, and then display this html file in a webviewer
HTML
The full html for the file created looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Private Image</title>
</head>
<body>
<img src=" [filepath]+[filename]" width="200px">
</body>
</html>
CREDITS:
Juan Antonio for the base64 extension
Taifun for the Tools extension (PathToAssets)
StackOverflow for inspiration