Insert files into the extension using Rush. JavaScript from extension

Hello friends,

this topic is about inserting multiple files into the extension.aix.

I have done a tutorial in Spanish and now I would like to share it in this Community:
http://kio4.com/appinventor/146_extension_archivo_rush.htm

We will create an extension called com.juan.dentro.aix and inside it will contain a text, image and html file. We will use Rush.

1.- Using Rush we create the extension com.juan.dentro.aix

2.- With a text editor we create these files:

- interno.txt

Uno, dos, tres.
One, two, three.
Hola amigo.
Hello friend.

- pitagoras.htm

<!DOCTYPE html>
<html><head></head><body>
<script>
    datos =  window.AppInventor.getWebViewString(); // Entrada de datos.
    datos = datos + ":";  
  
    catetos = datos.split(":"); 
    cateto1 = catetos[0];
    cateto2 = catetos[1];
    
    hipotenusa = Math.sqrt(Math.pow(cateto1, 2) + Math.pow(cateto2, 2)) ;
   
    window.AppInventor.setWebViewString("" + hipotenusa); // Salida datos 
</script>
</body></html>

- perro.png
perro

  • We copy those three files in the folder:
    C:\rush\exe\win\dentro\assets
    rush23

  • We edit:
    C:\rush\exe\win\dentro\rush.yml

assets:
  # Extension icon. This can be a URL or a local image in 'assets' folder.
  icon: icon.png
  # Extension assets.
  other:
     - interno.txt
     - perro.png
     - pitagoras.htm

We add: - interno.txt, - perro.png and - pitagoras.htm

LOOK, the indentation is very important, respect the margins.

..\rush build

and get: com.juan.dentro.aix

Now with a decompiler, like Java Decompiler, we decompile the file com.juan.dentro.aix (change to com.juan.dentro.zip)

rush24

  • Notice that it contains an assets subfolder and inside are the files interno.txt, perro.png and pitagoras.htm
6 Likes

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:

rush25i

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

rush27

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

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 :+1:

BTW I am I think I am the first one to see this topic this morning(IST) :joy:

Yes, as shown in my guide Some basics on Android storage.
But I would like to know why this was changed. :upside_down_face:

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
rush36

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 :slightly_smiling_face:

../rush build

Get:
C:\rush\exe\win\f\out\j.f.aix

5.- Create an app with this extension:
rush34

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!

rush35

1 Like

@Anke
(related to Juan's aia/apk)

this is not working for an installed app, just returns false. Do you know why ?

image

1 Like

Try

/myimage150.png

1 Like

I did, that doesn't work either.

Where is myimage150.png?

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