App inventor 2 en español
Cómo programar los teléfonos móviles con Android
mediante App inventor 2 - Juan Antonio Villalpando
-- Tutorial de iniciación de App Inventor 2 en español --
Volver al índice del tutorial
____________________________
275B.- Descomprimir archivo .zip con subdirectorios. Sitio web local. CloudDB.
com.KIO4_Unzip.aix
________________________________________________
1.- Descomprime .zip con subdirectorios. Crea sitio web local.
p175B_extension_unzip_web.aia
- Descomprime archivos .zip con subdirectorios.
- En el siguiente ejemplo tenemos en el assets un archivo llamado web.zip (660 KB), es un archivo comprimido en donde se encuentra una estructura de archivos y subdirectorios que forman un pequeño sitio web.
- La aplicación copia ese archivo desde el assets al directorio de la aplicación mediante el componente CopyFile.
- El bloque UnzipFolder, descomprime ese archivo en el directorio web de la aplicación.
- Mediante el componente WebViewer (VisorWeb), se muestra la página de inicio (index.htm) del sitio web.
- He utilizado el bloque GetAsdPath para obtener la dirección del archivo de la aplicación, podría haber utilizado el bloque MakeFullPath del componente Archivo.
- Una vez descomprimido el archivo web.zip, se podría borrar del directorio de la aplicación, esto no lo he contemplado en este ejemplo.
- Podemos crear una estructura de directorios y subdirectorios en nuestro ordenador, comprimirlo en .zip, pasarlo al asset y mediante esta extensión descomprimir en el directorio de la aplicación, así tendremos una estructura de directorios.
- También podemos borrar un directorios con sus subdirectorios.
________________________________________________
- Diseño.
________________________________________________
- Bloques.
________________________________________________
2.- Envío del archivo web.zip a CloudDB. Base64. Recuperación. Descomprimir y mostrar.
p175B_extension_unzip_web_CloudDB.aia
- Esta extensión también contiene dos bloques para trabajar con Base64, uno de ellos convierte un archivo situado en el directorio de la aplicación a String Base64 y otro bloque convierte un String Base64 a archivo.
- En este ejemplo tenemos el archivo web.zip en el asset, mediante la extensión lo pasamos a String Base 64 y lo enviamos a CloudDB.
- Bajamos ese String de CloudDB y creamos un archivo llamado web2.zip en el directorio de la aplicación.
- Descomprimimos el archivo web2.zip y mostramos la página index.htm como hemos visto anteriormente.
________________________________________________
- Diseño.
________________________________________________
- Bloques.
________________________________________________
3.- Borrar archivo y directorio.
- Una vez descomprimido el archivo lo podemos borrar del directorio de la aplicación median Delete.
- También podemos borrar el directorio creado con sus subdirectorios con el bloque DeleteDirectory.
- [El bloque RemoveDirectory del componente Archivo no funciona con varios niveles de subdirectorios.]
________________________________________________
- Código fuente.
- El bloque de descomprimir está basado en este código:
https://howtodoinjava.com/java/io/unzip-file-with-subdirectories/
- Este código:
- Descomprime archivos .zip incluso teniendo subdirectorios.
- Pasa un archivo que esté en el directorio de la aplicación a String Base64.
- Pasa un String Base64 a un archivo en el directorio de la aplicación.
- Obtiene la dirección del directorio de la aplicación.
|
package com.KIO4_Unzip;
// ?© Juan Antonio Villalpando
// http://kio4.com/appinventor/275B_extensiones_descomprimir.htm
// Enero 2023
import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.runtime.util.MediaUtil;
import com.google.appinventor.components.runtime.*;
import android.content.Context;
// ZIP
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.util.zip.ZipOutputStream;
import java.util.Enumeration;
// Base 64
import android.util.Base64; // API 8
import java.io.IOException;
@DesignerComponent(version = 1,
description = "Unzip file with subdirectories. File to String Base64. Base64 String to file. Get App path." +
"Juan Antonio Villalpando - KIO4.COM ",
category = ComponentCategory.EXTENSION,
nonVisible = true,
helpUrl = "http://kio4.com/appinventor/275B_extensiones_descomprimir.htm",
iconName = "")
@SimpleObject(external = true)
public class KIO4_Unzip extends AndroidNonvisibleComponent implements Component {
public static final int VERSION = 1;
private ComponentContainer container;
private Context context;
public KIO4_Unzip(ComponentContainer container) {
super(container.$form());
this.container = container;
context = (Context) container.$context();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// UNZIP DIRECTORY RECURSIVE /////////////////
// https://howtodoinjava.com/java/io/unzip-file-with-subdirectories/
@SimpleFunction(description = "Unzip zip file with subdirectories. fileZipPath: absolute path zip file. destinationDirPath: absolute path destination dir .")
public void UnzipFolder(String fileZipPath, String destinationDirPath) {
fileZipPath = fileZipPath.replace("file://","");
destinationDirPath = destinationDirPath.replace("file://","");
String filename = fileZipPath;
File srcFile = new File(filename);
// create a directory with the same name to which the contents will be extracted
// String zipPath = filename.substring(0, filename.length()-4);
String zipPath = destinationDirPath;
File temp = new File(zipPath);
temp.mkdir();
ZipFile zipFile = null;
try {
zipFile = new ZipFile(srcFile);
// get an enumeration of the ZIP file entries
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry entry = e.nextElement();
File destinationPath = new File(zipPath, entry.getName());
//create parent directories
destinationPath.getParentFile().mkdirs();
// if the entry is a file extract it
if (entry.isDirectory()) {
continue;
}
else {
// System.out.println("Extracting file: " + destinationPath);
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
int b;
byte buffer[] = new byte[1024];
FileOutputStream fos = new FileOutputStream(destinationPath);
BufferedOutputStream bos = new BufferedOutputStream(fos, 1024);
while ((b = bis.read(buffer, 0, 1024)) != -1) {
bos.write(buffer, 0, b);
}
bos.close();
bis.close();
}
}
}
catch (IOException ioe) {
// System.out.println("Error opening zip file" + ioe);
}
finally {
try {
if (zipFile!=null) {
zipFile.close();
}
}
catch (IOException ioe) {
// System.out.println("Error while closing zip file" + ioe);
}
}
}
/////////////////////// RemoveDirectory /////////////////////////////////////////////////
// https://stackoverflow.com/questions/73953530/delete-files-in-folder-recursively-in-java-i-o
@SimpleFunction(description = "Delete directory and subdirectories. Set absolute path. It also deletes files.")
public void DeleteDirectory(String directory) {
File f = new File(directory);
deleteDirectory(f);
}
private boolean deleteDirectory(File directoryToBeDeleted) {
File[] allContents = directoryToBeDeleted.listFiles();
if (allContents != null) {
for (File file : allContents) {
deleteDirectory(file);
}
}
return directoryToBeDeleted.delete();
}
/////////////////// Obtener el directorio ASD /storage/emulated/0/Android/data/namepackage/files /////////////
@SimpleFunction(description = "Get App Specific Directory path (ASD). Example: /storage/emulated/0/Android/data//files")
public String GetAsdPath() {
return context.getExternalFilesDir(null).toString();
}
///////////////////////////////// BASE 64 archivo a String ///////////////////////////////////////////////
////////// Archivo a String directamente, sin evento.
@SimpleFunction(description = "Convert File to String Base64. Set absolute address, example: /storage/emulated/0/Pictures/my_picture.png")
public String FileToStringDirect(String pathFile) {
pathFile = pathFile.replace("file://","");
String fileName = pathFile;
File file = new File(fileName);
try {
// Reading a Image file from file system
FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int) file.length()];
imageInFile.read(imageData);
// Convierte el archivo a Base64 String
String imageDataString = Base64.encodeToString(imageData, Base64.DEFAULT);
imageInFile.close();
return (imageDataString); // SALIDA.
} catch (FileNotFoundException e) {
return ("File not found."); // SALIDA.
} catch (IOException ioe) {
return ("Error en la lectura del archivo."); // SALIDA.
}
}
///////////////////////////////// BASE 64 String a archivo en ASD ///////////////////////////////////////////////
// Funcion que hace la decodificacion del String a Archivo Directamente, sin evento.
@SimpleFunction(description = "String Base 64 to File. Name file must begins with a slash (/), the file is written to the sdcard" +
" (for example, writing to /myFile.txt will write the file to /storage/emulated/0/Android/data//files/myFile.txt).")
public String StringToFileASDDirect(String string, String fileName) {
File file = new File(fileName);
try {
// Convierte string Base64 a archivo byte array
// byte[] imageByteArray = Base64.decodeBase64(string);
byte[] imageByteArray = Base64.decode(string, Base64.DEFAULT);
// Escribe archivo en byte array a un archivo de sistema.
FileOutputStream imageOutFile = new FileOutputStream(GetAsdPath() + fileName); // en directorio App
imageOutFile.write(imageByteArray);
imageOutFile.close();
return (fileName);
} catch (FileNotFoundException e) {
return ("File not found."); // SALIDA.
} catch (IOException ioe) {
return ("Error en la lectura del archivo."); // SALIDA.
}
}
} // => FIN
|
________________________________________________
- Prueba de stress.
p175B_extension_unzip_stressB.aia (26 MB)
- Esta app contiene el archivo fotos.zip de 25 MB.
- Se descomprime en App/fotos/fotos/subdir/
- Contiene 7 fotos de unos 4 MB cada una.
- El Borrado del directorio (RemoveDirectory) foto no funciona.
___________________________
|