3.- Files in assets.
Until September 2021, the App Inventor assets directory, to be used with the MIT Companion emulator, was at:
/mnt/sdcard/AppInventor/assets/
is the same as...
/storage/emulated/0/AppInventor/assets /
Now they have changed it, if you use Android <10 it will be found in:
/storage/emulated/0/Android/data/edu.mit.appinventor.aicompanion3/files/AppInventor/assets
If you use an Android >= 10 it will be found in:
/storage/emulated/0/Android/data/edu.mit.appinventor.aicompanion3/files/assets
We can check it through these blocks, executing it from the MIT Companion:
If we build the application and run it, we will get this asset address:
file:///android_asset
3 Likes
4.- Creating an application with the extension com.juan.dentro.aix
1 Like
5.- We unzip cadiz.aia with Winrar.
In assets/external_comps/com.juan.dentro/assets
are the files: interno.txt, perro.png and pitagoras.htm
2 Likes
6.- Build and we get cadiz.apk, we decompile it with APK Editor Studio.
We see the root asset with the files: gato.png and saludos.txt, and the subfolder com.juan.dentro that contains: interno.txt, perro.png and pitagoras.htm
1 Like
7.- Comments.
If you look at the blocks of the app, you will see that we can execute a JavaScript (pitagoras) with the htm file inside the extension.
We can also have images in the extension (perro.ng).
Also data in a text file (interno.txt)
Look at the address of these files when you are using the MIT Companion and when the app is installed.
2 Likes
8.- Content of the extension.
C:\rush\exe\win\dentro\src\com\juan\dentro\Dentro.java
The extension contains a block, a function to copy files from the assets to another directory, but it is not necessary to have this block.
package com.juan.dentro;
// Juan Antonio Villalpando
// http://kio4.com/appinventor/146_extension_archivo_rush.htm
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import android.content.Context;
import java.io.*;
public class Dentro extends AndroidNonvisibleComponent {
private Context context;
public Dentro(ComponentContainer container) {
super(container.$form());
context = (Context) container.$context();
}
//////// Copiar archivo desde el Asset a un directorio indicando nombre archivo
@SimpleFunction(description="Copy file from asset (or subfolder asset) to path. " +
"Example with subfolder, fileName: com.juan.dentro/texto.txt " +
"dest: /storage/emulated/../absolute address/../namefile.ext")
public void CopyFileAsset(String fileName, String dest) throws Exception {
InputStream stream = null;
OutputStream output = null;
stream = context.getAssets().open(fileName);
output = new BufferedOutputStream(new FileOutputStream(dest));
byte data[] = new byte[1024];
int count;
while((count = stream.read(data)) != -1)
{ output.write(data, 0, count); }
output.close();
stream.close();
}
} // => Fin
5 Likes
Horizon
December 8, 2021, 2:25am
10
Thank you @Juan_Antonio for this great guide
This would help all the extension developers
2 Likes
9.- Bare minimum.
Bare minimum, an extension that does not contain code.
We can use this extension to save images, text, javascript,... files, it has no function blocks or events.
C:\rush\exe\win\dentro\src\com\juan\dentro\Dentro.java
package com.juan.dentro;
public class Dentro {}
1 Like
Very Helpful Guide @Juan_Antonio
BTW I am I think I am the first one to see this topic this morning(IST)
Anke
December 8, 2021, 10:43am
13
Yes, as shown in my guide Some basics on Android storage .
But I would like to know why this was changed.
1 Like
10.- Another example. Find primes with Sieve of Eratosthenes. JavaScript. Playing with minimum.
- Find prime numbers less than a given number.
sieve.htm
<!DOCTYPE html>
<html><head></head><body>
<script>
datos = window.AppInventor.getWebViewString(); // Entrada de datos.
window.AppInventor.setWebViewString("" + getPrimes(datos)); // Salida
function getPrimes(max) {
var sieve = [], i, j, primes = [];
for (i = 2; i <= max; ++i) {
if (!sieve[i]) {
// i has not been marked -- it is prime
primes.push(i);
for (j = i << 1; j <= max; j += i) {
sieve[j] = true;
}
}
}
return primes;
}
</script>
</body></html>
1.- Create extension: j.f.aix
2.- Copy file sieve.htm in
C:\rush\exe\win\f\assets\sieve.htm
3.- Edit
C:\rush\exe\win\f\rush.yml
assets:
# Extension icon. This can be a URL or a local image in 'assets' folder.
icon: icon.png
# Extension assets.
other:
- sieve.htm
Beware of indentation.
4.- Edit
C:\rush\exe\win\f\src\j\f\F.java
package j.f;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
public class F extends AndroidNonvisibleComponent {
public F(ComponentContainer container) {
super(container.$form());
}
@SimpleFunction(description="http://localhost/j.f/sieve.htm")
public String Sieve() {
return "http://localhost/j.f/sieve.htm";
}
}
// Only return a string
../rush build
Get:
C:\rush\exe\win\f\out\j.f.aix
5.- Create an app with this extension:
The Sieve block returns http://localhost/j.f/sieve.htm and executes the script sieve.htm
numeros_primos_rush.aia (5.7 KB)
6.- I think it only works installed. Adapt it to the MIT Companion!
1 Like
TIMAI2
December 8, 2021, 12:00pm
15
@Anke
(related to Juan's aia/apk)
this is not working for an installed app, just returns false. Do you know why ?
1 Like
TIMAI2
December 8, 2021, 12:04pm
17
I did, that doesn't work either.
TIMAI2
December 8, 2021, 12:12pm
19
It is in the media folder (assets).
I updated my private message response to you. Seems that File Exists does not work on your extension assets files nor on files in the normal assets. I tried all forms of file path, setting of the Screen filescope to Asset, to no avail - unless I am missing something obvious....
It is rare that the CopyFile block finds the file but the Exists block does not find it.
1 Like
Anke
December 8, 2021, 12:46pm
21
Yes, this also doesn't work with the APK:
Anke
December 8, 2021, 12:57pm
22
Works fine with Niotron (Companion & APK):
2 Likes