🟨 WebViewExtra - Upload/Download Files with webviewer

WebViewExtra wveicon

An extension for AI2 that extends the features of the native webviewer.

The extension, by default, will provide the following features:

  • allow for uploading of files from within a webviewer. (Developers will need to provide suitable html solutions...)
  • allow for downloading of files from within a webviewer, even from Google Drive shared folders! Files are saved to the Download directory in Shared storage.
  • sets READ and WRITE and MEDIA permissions in the app / aia project, enabling the setting of Legacy as a default filescope for storage of files in Shared directories. This is useful for providing access to files in the ASD (which would need to be copied to a shared directory location for uploading).
  • allow for file access from the webviewer.
  • turns zoom on and off in the webviewer.
  • allow for the use of localStorage and sessionStorage in html/javascript in a webviewer.
  • modifies the userAgent of the webviewer, removing the ; wv, which then enables (for example) Google 0Auth activities, such as authorising web apps with a user's google account.
  • provides choice of download path, the ASD or the Download directory (default)
  • provides choice of upload path, the ASD or Shared Directories (default). You will require a file component.

DETAILS

  • Latest Version: 1.7 release.
  • Tested: This has been tested, companion and compiled, on App Inventor 2 using Android 7, 9, 10 and 13 devices, companion 2.70. It may work on other derivatives....e.g. Kodular/Niotron/etc.
  • Released: 10 Feb 2023.
  • Last Updated: 10 April 2024.
  • Built: Using the Rush Extension Builder by @shreyash.

BLOCKS

  • Supply the SetWebviewer block with the component block from a webviewer component.
  • In the FileType block, provide a filetype filter in mimetype format. The default is "/" (all files). A list of mimetypes is provided in the FileTypes property block. This is intended for uploading files selection.
  • Set ZoomControls block to true or false.
  • The event blocks should be self-explanatory...

1.2release Update

It seems that simply removing ; wv from the default useragentstring is now not enough, and we also need to remove Version/4.0 and Mobile . Also, not all android devices present the same webview useragentString, e.g. Samsung, Asus, Redmi, Motorola..., therefore it may be necessary to modify the useragent presented in those webview, hence the provision of the get and set useragent blocks. A useful link for native browser user agents: Device Atlas. See below from posts 24 - 45 for the workthrough following reports from @TxSolve .

1.3 release update

  • added the three new media permissions (image/audio/video)
  • tidied up zoom controls to one method (although it seems it does not work on all devices?)

1.4 release update

  • added function to set/unset Viewport mode
  • added function to set/unset Overview mode

1.5 release update

  • added Transparent Background property (designer only)

1.6 release update

  • added option to download to either the ASD or Download directory. By default uses the Download directory

1.7 release update

  • added option to upload from either the ASD or Shared directories. By default uses the Shared Directories. You will require a File component to use the helper blocks. See HERE for more details.

EXTENSION

WebViewExtra

MORE INFORMATION

WebViewExtra on AI2 Metricrat

CREDITS

I have @JuanAntonio to thank for creating the basis of this extension, and for additional code, suggestions, bug fixing and testing. It would not have happened without him!
@vknow360 and Luke Gackle for their open sourced extensions on the same subject.
All the Questioners and Answerers on StackOverflow, and howto/tutorial/guide providers on the internet
@Kevinkun for transparent background code
@Kumaraswamy & @ewpatton for listpicker upload from ASD functionality

.
.
Enjoy :smiley: , and all feedback and comments welcome.

Available for use in any MIT AppInventor projects or competitions

#####################################################################
This work by Juan Antonio Villalpando & TIMAI2 & Kevinkun is licensed under a
Creative Commons Attribution-ShareAlike 4.0 Unported License with attribution.
Please use name = Juan Antonio Villalpando & TIMAI2 & Kevinkun and link to this source page when giving credit.
#####################################################################

15 Likes
  • Through this extension we can upload and download files from a web page displayed with the WebViewer component.

UploadDownload.aia (20.1 KB)

- Upload file from a web page.
visorwebextra4

visorwebextra1

In this example the web page is a PHP:

PHP code: upload_file.php
<html><head>
</head>

<body>
<font size="5" face="Arial">- Select file and click Send button. Size max. 10 KB</font>
<br><br><br>
<form action="upload_file.php" method="post" enctype="multipart/form-data">
<input name="filename" type="file" style="font-size:24px; font-family: arial;"><br><br>
<button type="submit" style="font-size:24px; font-family: arial;">Send</button></font>
</form>
<br><br><br>
<?php
$directory = "subidos/"; 
$filename = basename($_FILES['filename']['name']);
$filepath = $directory.$filename;  
$filesize = filesize($_FILES['filename']['tmp_name']);

if($filesize < 10000){
   if(move_uploaded_file($_FILES['filename']['tmp_name'], $filepath)) { 
	 echo "<font size='5' face='Arial'>- The".$filename." file uploaded to the server. <br><br>";                   
echo "<a href='http://kio4.com/appinventor/php/subidos/".$filename."'>http://kio4.com/appinventor/php/subidos/".$filename."</a>";
					} else { 
						echo "------"; 
					} 
} else {
echo "- The ".$filename." cannot upload because it is larger than 10KB. It is ".$filesize," B. ";
}
?> 
</body></html>

- Download file from a web page and Google Drive.

2 Likes

Is it possible to have a DownloadProgress event?

For larger files, you should see an animated arrow in the notifications area.

2 Likes
UploadFile.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  <script>
  function LoadFile(event)  {
    var file = event.target.files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
      var fileData = e.target.result.substr(e.target.result.indexOf(",")+1);
      var mimeTypeStart = e.target.result.indexOf("data:") + 5;
      var mimeTypeEnd = e.target.result.indexOf(";");
      var mimeType = e.target.result.substr(mimeTypeStart, mimeTypeEnd - mimeTypeStart);
      var fileName = file.name;
      document.getElementById("fileData").value = fileData;
      document.getElementById("mimeType").value = mimeType;
      document.getElementById("fileName").value = fileName;
    };    
    reader.readAsDataURL(file);
  }
  </script>
  </head>
  <body>
    <h1>Web App File Loader</h1>
    <?var url = getUrl();?>
    <form method="post" action="<?= url ?>" >
      <table cellpadding="5px">
      <tr>
      <td>File:</td>
      <td><input type="file" name="file" onchange="LoadFile(event)" />
      <input type="hidden" id="fileData" name="fileData" />
      <input type="hidden" id="mimeType" name="mimeType" />
      <input type="hidden" id="fileName" name="fileName" /></td>
      </tr>
      <tr>
      <td colspan="2"><input type="submit" value="Load File" /></td>
      </tr>
      <tr>
      <td colspan="2"><span><?= message ?></span></td>      
    </form>
  </body>
</html>
code.gs
function doGet(e) {
  var htmlOutput =  HtmlService.createTemplateFromFile('UploadFile');
  htmlOutput.message = '';
  return htmlOutput.evaluate();
}

function doPost(e) {
  // Logger.log(JSON.stringify(e));
  
  var destination_id = '1tFhDzSWbcExampleT5Xdd7NZ_r';  // ID OF GOOGLE DRIVE DIRECTORY;
  var destination = DriveApp.getFolderById(destination_id);
  
  var data = Utilities.base64Decode(e.parameter.fileData);
  var blob = Utilities.newBlob(data, e.parameter.mimeType, e.parameter.fileName);
  destination.createFile(blob);
  
   listRecord(e.parameter.username, e.parameter.fileName); 
  
  var htmlOutput =  HtmlService.createTemplateFromFile('UploadFile');
  htmlOutput.message = 'File Uploaded';
  return htmlOutput.evaluate();
  
}

function listRecord(username, filename)
{
  var url = 'https://docs.google.com/spreadsheets/d/18tlBCVwsi2giDcTg7GFvYH-CyvOxKqPkwLHBntrdXRc/edit?usp=sharing';  //URL OF GOOGLE SHEET;
  var ss= SpreadsheetApp.openByUrl(url);
  var recordsSheet = ss.getSheetByName("Sheet1");
  recordsSheet.appendRow([username, filename, new Date()]);
}

function getUrl() {
 var url = ScriptApp.getService().getUrl();
 return url;
}

googledrive31

1 Like

Great extension.local storage support helps but I can't remove zoom control in webview.my blocks are in below image

Are you still able to zoom with two fingers?

The zoom buttons will still be visible.

Zoom button is displaying after set zoom to false.any way to hide zoom button.

Is it your web page (or can you get it edited) ?

If so, add this meta tag:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

Thanks

How ca we upload multiple file ?

Where do you want to upload them? In case you have a server with PHP, you could convert your files to zip and upload it.

https://puravidaapps.com/zip.php

yes but my php look like this.

If you want to upload it via FTP you need an FTP client.

do you have solution just to able multiple file.. just single file is working.. i need multiple file to be uploaded.

You can use a Clock and upload a file automatically every 4 seconds (for example).

how?

Do you want to upload files from the app to a hosting?
Do you have an FTP server in your hosting?
How do you want to upload the files via FTP or via PHP?

i have a php file that is working to upload files but when i use this webview extra extension i can only select 1 file to be uploaded but when i use google chrome i can upload more than one
file

Show the html for the web page you are using to select the files to upload (as in your image above), specifically the <form> structure.