PDA

Ver la Versión Completa : Stream read error en Android


Yulexis
11-07-2018, 16:26:25
Saludos a todos.
Tengo el siguiente código el cual funciona perfecto en Windows pero cuando compilo y lo ejecuto en Android me devuelve el siguiente error: Stream read error.

var
datos :TStream;
ruta : string;
Zip :TZipFile;
begin

ForceDirectories(GetHomePath + PathDelim + 'ENTRADAS' );

ruta := GetHomePath + PathDelim + 'ENTRADAS' + PathDelim + 'update.zip';
datos := TFileStream.Create(ruta, fmCreate);
NetHTTPClient1.Get('Act.zip',datos);
datos.Free;

Zip := TZipFile.Create;
Try
Zip.Open (ruta, zmRead);
Zip.ExtractAll(GetHomePath + PathDelim + 'ENTRADAS');
Finally
Zip.Free;
End;
end;

Espero alguien pueda darme una mano.
Desde ya gracias.

mamcx
11-07-2018, 22:27:29
La verdad no estas dando detalles. Donde esta el error, que exactamente dice, etc.

Neftali [Germán.Estévez]
12-07-2018, 08:59:15
Estaría bien que utilizaras Debug o Log (en la aplicación Android) para saber exactamente qué línea es la que te está fallando.
¿Te da algún error al ejecutar?
Algunas ideas...


Un Try..except para capturar algíun tipo de excepción no estaría mal.
Otra cosa que se me ocurre es tema de permisos. ¿Has asignado permisos a la aplicación? ¿Cuales?
Visualiza la ruta donde estás intentando realizar las operaciones, ¿Están creadas? ¿Son correctas?
¿El GET está descargando algo? ¿Tienes el fichero en el almacenamiento?

Yulexis
12-07-2018, 13:56:26
La verdad es que no me dice nada más que el error. Trataré con los consejos que me dan.

Cuando pinchaba el botón para la descarga me soltaba el error. No hice nada, compilé nuevamente y ahora lo no me suelta el error, se queda dormida. Me va a volver loco :D
El GET no llega a descargar nada. Veré el tema de las rutas.
Si saben algún método para descargar un archivo que funcione en Android les estaría agradecido. Estoy utilizando XE8

Neftali [Germán.Estévez]
13-07-2018, 11:46:14
Revisa el tema de permisos que te he comentado.

Yulexis
13-07-2018, 21:26:15
Saludos Neftali
Estoy tratando de detectar el error de la siguiente manera pero no me dice nada, se queda colgada.
La otra parte de código funciona bien, se crea la carpeta y se crea TStream. A la parte de descomprimir el zip nunca a llegado pero me imagino que funcione.
try
NetHTTPClient1.Get('Act.zip',datos);
except
on E: Exception do

ShowMessage( 'Excepción 2: ' + E.Message );
end;


Cuando va a descargar es cuando la cosa se jode.
Creo que los permisos que tiene son los que debe de tener:
- Permiso de lectura y escritura en la SD
- Acceso completo a la red

Lo que me extraña ahora es que ni tratando el error me lo muestra.
"Estaría bien que utilizaras Debug o Log (en la aplicación Android) para saber exactamente qué línea es la que te está fallando.
¿Te da algún error al ejecutar?"Lamentablemente no tengo ni idea de como hacerlo.

Neftali [Germán.Estévez]
16-07-2018, 09:22:22
Lamentablemente no tengo ni idea de como hacerlo.


Para el tema de los LOGS, una forma sencilla es enviar los mensajes a un Memo (por ejemplo) y a la vez grabar en disco. Crea un procemimiento que escriba en el Memo y luego lo guarde en disco. Cada vez que realices una operación (y los try..except) vuelca el contenido a log copn ese procedimiento.
Si la aplicación se cuelga, luego puedes recuperar ese fichero.

mamcx
16-07-2018, 15:29:59
No sirve simplemente haciendo "print" a la consola? No hay libreria log en firemonkey?

Yulexis
16-07-2018, 19:06:03
Pido disculpas por las molestias pero sigo enredado. Bueno Nestalí... no tengo otra que seguirte molestando.

Con el tema de generar un LOG no hay problema porque lo entendí a la primera y ya había realizado algo parecido para determinar donde me generaba el error. Es como les decía, todo funciona menos la descarga.
Ya no me da el error que me daba al inicio (no he hecho nada). Ahora o se cierra en cuanto pincho el botón, o se bloquea y tengo que terminarlo.
Este un código que encontré pero que es prácticamente lo mismo pero con tratamiento de errores. Igual no me funciona:
procedure DownLoad (url, guardar_en : string);
var
Stream: TMemoryStream;
hc: THTTPClient;
begin
Stream := TMemoryStream.Create;
hc := THTTPClient.Create;
try
try
hc.Get(url, Stream);
Stream.SaveToFile(guardar_en);
except
on e: Exception do
ApplicationShowException(e);
end;
finally
hc.Free;
Stream.Free;
end;
end;


El error que me genera es el siguiente:
"No mapping for the Unicode character exists in te target multi-byte code page."

Ni idea :(
En Windows funciona, el problema es en Android. Al final a la descarga la voy a tener que meter dentro de un hilo porque que a se quede bloqueada la app mientras descarga (si por fin logro que descargue) no le veo gracia.
Si alguno conoce cómo realizar esta descarga favor de ponerme el código. Es la parte fundamental de la app que estoy realizando por lo que sin esto no puedo seguir.

Neftali [Germán.Estévez]
16-07-2018, 19:19:42
Revisa este código de Luis Navarro, para descargar imágenes en Android (https://community.embarcadero.com/blogs/entry/download-an-image-in-background-with-android-services). Yo lo he usado en esta aplicación de Android (http://neftali.clubdelphi.com/funwithdelphi-la-foto-del-da/) (sin ser un servicio) y funciona perfectamente.
A ver si con esto consigues realizar la descarga.


Revisa también este mensaje (https://stackoverflow.com/questions/26060832/delphi-xe6-no-mapping-for-the-unicode-character-exists-in-the-target-multi-byte)a ver si te sirve esa solución.

Yulexis
19-07-2018, 22:42:45
Saludos Neftali y mamcx.
Con el siguiente código que encontré en la red según los "puntos de control" que he puesto después de cada acción me dice que la descarga se ha realizado. Al final compruebo si el archivo .zip existe y si me dice que si y lo extraigo.
Recordarles que el último error que lanzaba era el siguiente: "No mapping for the Unicode character exists in te target multi-byte code page."
El código que encontré y que le muestro a continuación también me generaba ese error y lo resolví agregándole el segundo parámetro a la función Create:


XMLRequest := TStringStream.Create( XMLRqst, TEncoding.UTF8 );


Hasta ahora las pruebas que he realizado no han fallado y siempre han dado el mismo resultado, por lo que el tema principal del hilo fue RESUELTO (Tengo que meter todo en un hilo de ejecución claro).


var
XMLRqst : String;
XMLRequest : TStringStream;
idHTTP : TIdHTTP;

ruta, ruta_imagen : string;
Mi_Arch : TIniFile;
i : Integer;
Zip :TZipFile;
begin
XMLRqst := '<root company="belvew"/>';
ForceDirectories( Directorio_raiz );
Memo1.Lines.Add('Directorio de la actualización creado.');

ruta := Directorio_raiz + 'update.zip';
Memo1.Lines.Add('Ruta donde guardar el .zip: ' + ruta);

try
XMLRequest := TStringStream.Create( XMLRqst, TEncoding.UTF8 );
try
idHTTP := TIdHTTP.Create;
try
idHTTP.ReadTimeout := 60000;{ IdTimeoutInfinite; }
idHTTP.ConnectTimeout := 60000;
idHTTP.HandleRedirects := True;
idHTTP.Compressor := TIdCompressorZLib.Create(idHTTP);

Memo1.Lines.Add('Iniciando descarga...');

idHTTP.Get( 'Act.zip', XMLRequest );
XMLRequest.SaveToFile(ruta);
if FileExists(ruta) then Memo1.Lines.Add('Descargado en: ' + ruta);

finally
idHTTP.Free;
end;
finally
XMLRequest.Free;
end;
except
on E : Exception do
begin
ShowMessage( 'exception : '#13 + E.Message );
end;
end;

Memo1.Lines.Add('Extrayendo archivo...');
if FileExists(ruta) then
begin
Memo1.Lines.Add('Existe: ' + ruta);
Zip := TZipFile.Create;
Try
Zip.Open (ruta, zmRead);
Zip.ExtractAll( Directorio_raiz );
Memo1.Lines.Add('Archivo extraido.');
Finally
Zip.Free;
End;
end
else
Memo1.Lines.Add('NO existe: ' + ruta);

Memo1.Lines.Add('Iniciando creación de entradas...');
ruta := Directorio_raiz + 'Entradas.ini';
if FileExists( ruta ) then
begin
Memo1.Lines.Add('Existe: ' + ruta );
Mi_Arch := TIniFile.Create(ruta );
Mi_Arch.ReadSections(ListBox1.Items);
for I := 0 to ListBox1.Items.Count -1 do
begin
ruta_imagen := Mi_Arch.ReadString(ListBox1.Items[i],'img','');
Memo1.Lines.Add('Creando anuncio ' + IntToStr(i));
Memo1.Lines.Add('... ' + ruta_imagen);
Crea_Anuncio(Directorio_raiz + ruta_imagen ,ListBox1.Items[i], Mi_Arch.ReadString(ListBox1.Items[i],'descrip',''));
end;
end;

end;

Como les comenté, parece que ha descargado el archivo y que logra extraerlo. Pero... (como siempre)...
Entre los archivos existe un .ini (los .ini de toda la vida) que es el que trae la configuración de toda la actualización. Este señor me dice que existe, pero no logro leerlo :( Se extrae en: /data/data/com.embarcadero.prueba/files/ENTRADAS/Entradas.ini