Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Desarrollo en Delphi para Android (https://www.clubdelphi.com/foros/forumdisplay.php?f=57)
-   -   Impresión en Android haciendo uso de PrintManager nativo (https://www.clubdelphi.com/foros/showthread.php?t=95632)

dani36652 28-03-2022 20:52:47

Impresión en Android haciendo uso de PrintManager nativo
 
Hola a todos, me presento como un programador entusiasta de Delphi.
Debido a que no encontraba algo claro en la red, o algunas opciones eran de pago, me di a la tarea de escribir un ejemplo de cómo imprimir en Android haciendo uso de PrintManager y así poner mi granito de arena para compartirlo con más desarrolladores.

En el siguiente link les dejo el repositorio en GitHub: https://github.com/dani36652/Ejemplo...oid-con-Delphi
Notas:
*Este ejemplo fue escrito en Delphi 11 Alexandria por lo que en el AndroidManifest.template.xml deberá establecer la librería correcta para el fileprovider cambiando androidx.core.content.FileProvider por android.support.v4.content.FileProvider*

Casimiro Notevi 29-03-2022 09:59:50

Gracias por compartirlo ^\||/

Neftali [Germán.Estévez] 29-03-2022 11:35:52

Muchas gracias.
^\||/^\||/^\||/

Nelson Alberto 27-06-2023 05:00:00

Impresión en Android haciendo uso de PrintManager nativo ?

no he podido imprimir aplicaciones delphi a android

jmbarrio 01-10-2024 13:10:41

Imprimir Contenido de un Memo
 
Buenas tardes, me he descargado tu aplicación Dani, muchísimas gracias. Necesito imprimir el contenido de un TMemo, y he intentado hacerlo desde tú código, he añadido un procedimiento nuevo para la impresion del Memo.

Código Delphi [-]
procedure ImprimirMemo(Texto:string);
var
  Impresor: JPrintHelper;
  TextoAImprimir: JString;
  Canvas: JCanvas;
  Paint: JPaint;
  Bitmap: JBitmap;
  Altura, Anchura: integer;
  TempFilePath :String;
  Uri:JNet_Uri;
begin
  Impresor := TJPrintHelper.JavaClass.init(TAndroidHelper.Context);
  Impresor.setScaleMode(TJPrintHelper.TJPrintHelper_SCALE_MODE_FIT);
  Impresor.setColorMode(TJPrintHelper.TJPrintHelper_COLOR_MODE_COLOR);
  Impresor.setOrientation(TJPrintHelper.TJPrintHelper_ORIENTATION_PORTRAIT);
  // Definir el texto que se imprimirá
  TextoAImprimir := StringToJString(Texto);
  // Definir dimensiones del contenido
  Anchura := 595; // A4 en puntos de densidad
  Altura := 842;  // A4 en puntos de densidad

  // Crear un bitmap para renderizar el contenido
  Bitmap := TJBitmap.JavaClass.createBitmap(Anchura, Altura, TJBitmap_Config.JavaClass.ARGB_8888);
  Canvas := TJCanvas.JavaClass.init(Bitmap);
  Paint := TJPaint.JavaClass.init;

  // Configurar el tamaño del texto
  Paint.setTextSize(12);

  // Dibujar el texto en el canvas
  Canvas.drawText(TextoAImprimir, 10, 25, Paint);

   // Guardar el bitmap en un archivo temporal
  TempFilePath := SaveBitmapToTempFile(Bitmap);

  // Obtener la URI desde el archivo temporal
  Uri := GetUriFromFile(TempFilePath);

  // Enviar el contenido al servicio de impresión
  Impresor.printBitmap(StringToJString('Impresion1'), Uri);

end;

y he añadido estas dos funciones

Código Delphi [-]
// Convertir el archivo temporal a JNet_Uri
function GetUriFromFile(const FilePath: string): Jnet_Uri;
var
  FileObj: JFile;
begin
  // Crear un objeto JFile con la ruta del archivo
  FileObj := TJFile.JavaClass.init(StringToJString(FilePath));

  // Obtener la URI desde el archivo
  Result := TJnet_Uri.JavaClass.fromFile(FileObj);
end;

// Guardar el JBitmap en un archivo temporal
function SaveBitmapToTempFile(Bitmap: JBitmap): string;
var
  OutputStream: JFileOutputStream;
  FileName: string;
  TempFile: JFile;
begin
  // Crear un nombre de archivo temporal
  FileName := TPath.Combine(TPath.GetDocumentsPath, 'temp_image.jpg');

  // Crear el archivo
  TempFile := TJFile.JavaClass.init(StringToJString(FileName));

  // Crear el FileOutputStream para escribir el bitmap
  OutputStream := TJFileOutputStream.JavaClass.init(TempFile);
  try
    // Comprimir y escribir el bitmap en el archivo
    Bitmap.compress(TJBitmap_CompressFormat.JavaClass.JPEG, 100, OutputStream);
    OutputStream.flush;
  finally
    OutputStream.close;
  end;

  // Retornar la ruta del archivo temporal
  Result := FileName;
end;

Al mandar la impresión en la previsualización se ve todo en negro, el código coge el texto del memo y lo pasa a un jbitmap que convierte en uri_jnet para lanzar la impresión igual que cuando lanzas la impresión de la imagen de la calavera. Seguro que hay una manera mucho más sencilla.

Por otro lado cuando lanzo la imagen de la calavera se previsualiza bien, selecciono la impresora que tengo en red, pero la impresora me bloquea la impresión. Hay que configurar algo en la impresora para poder imprimir desde mi móvil?

Muchisimas gracias, estoy a punto de terminar el proyecto y esto es lo último que me queda por programas. Así que toda ayuda será bienvenida.

jmbarrio 02-10-2024 09:04:54

Buenos días, finalmente he encontrado esta solución por sí le sirve de ayuda a alguien. He pasado el contenido del memo a un fichero HTML y he empleado el código del botón de imprimir html del proyecto de Dani.
Código Delphi [-]
HtmlContent := TStringList.Create;
  try
    HtmlContent.Add('');
    HtmlContent.Add('');
    HtmlContent.Add('');
    HtmlContent.Add('    ');
    HtmlContent.Add('    Contenido del Memo');
    HtmlContent.Add('');
    HtmlContent.Add('');
    HtmlContent.Add('    
');
    HtmlContent.Add(Memo1.Lines.Text);  // Agregar el contenido del TMemo
    HtmlContent.Add('    
'
); HtmlContent.Add(''); HtmlContent.Add(''); // Obtener la ruta para guardar el archivo en el almacenamiento del dispositivo FilePath := TPath.Combine(TPath.GetDocumentsPath, 'Ticket1.html'); // Guardar el archivo HTML HtmlContent.SaveToFile(FilePath); // Mensaje opcional de éxito ShowMessage('Archivo HTML guardado en: ' + FilePath); finally HtmlContent.Free; end;

Un saludo.

dani36652 02-10-2024 20:15:52

Hola qué tal.
apenas voy ingresando al foro ya que no había tenido el tiempo de hacerlo y poder responder.

el motivo por el cual la previsualización de la impresión de una imagen se mira en negro viene desde tu función:

Código Delphi [-]
function GetUriFromFile(const FilePath: string): Jnet_Uri;
var
  FileObj: JFile;
begin
  // Crear un objeto JFile con la ruta del archivo
  FileObj := TJFile.JavaClass.init(StringToJString(FilePath));

  // Obtener la URI desde el archivo
  Result := TJnet_Uri.JavaClass.fromFile(FileObj);
end;

Ya que desde android 7 la forma de obtener el URI de un archivo se hace mediante algo llamado "FileProvider".

Si tienes Delphi Sydney a Athens (10.4-12) tu función quedaría así:

Nota: Recuerda que para usar esta nueva forma de obtener el uri tienes que:
Marcar la casilla de "Secure File Sharing" en "Project>Options>Application>Entitlement List

Código Delphi [-]
uses
  {$IFDEF ANDROID}
  Androidapi.JNI.Webkit, FMX.Dialogs.Android,
  Androidapi.JNI.Print, System.Messaging,
  fmx.Platform.Android, Androidapi.jni,
  fmx.helpers.android, Androidapi.Jni.app,
  Androidapi.Jni.GraphicsContentViewText, Androidapi.JniBridge,
  Androidapi.JNI.Os, Androidapi.Jni.Telephony,
  Androidapi.JNI.JavaTypes,Androidapi.Helpers,
  Androidapi.JNI.Widget,System.Permissions,
  Androidapi.Jni.Provider,Androidapi.Jni.Net,
  AndroidAPI.JNI.Support;
 {$ENDIF}

function GetUriFromFile(const FilePath: string): Jnet_Uri;
var
  FileObj: JFile;
begin
  // Crear un objeto JFile con la ruta del archivo
  FileObj := TJFile.JavaClass.init(StringToJString(FilePath));

  // Obtener la URI desde el archivo
  Result := TAndroidHelper.JFileToJURI(FileObj);
end;

Embarcadero creó esa función del TAndroidHelper para dicho propósito.

Finalmente lo que mencionas de la disponibilidad de tu impresora me suena más a las configuraciones de la misma y no a la implementación desde Delphi.

Saludos.

jmbarrio 03-10-2024 09:25:23

Muchas gracias Dani, por responder y sobre todo por tus aportes y ayuda.

Un saludo.

jmbarrio 27-01-2025 17:02:33

Cita:

Empezado por jmbarrio (Mensaje 557719)
Buenos días, finalmente he encontrado esta solución por sí le sirve de ayuda a alguien. He pasado el contenido del memo a un fichero HTML y he empleado el código del botón de imprimir html del proyecto de Dani.
Código Delphi [-]
HtmlContent := TStringList.Create;
  try
    HtmlContent.Add('');
    HtmlContent.Add('');
    HtmlContent.Add('');
    HtmlContent.Add('    ');
    HtmlContent.Add('    Contenido del Memo');
    HtmlContent.Add('');
    HtmlContent.Add('');
    HtmlContent.Add('    
');
    HtmlContent.Add(Memo1.Lines.Text);  // Agregar el contenido del TMemo
    HtmlContent.Add('    
'
); HtmlContent.Add(''); HtmlContent.Add(''); // Obtener la ruta para guardar el archivo en el almacenamiento del dispositivo FilePath := TPath.Combine(TPath.GetDocumentsPath, 'Ticket1.html'); // Guardar el archivo HTML HtmlContent.SaveToFile(FilePath); // Mensaje opcional de éxito ShowMessage('Archivo HTML guardado en: ' + FilePath); finally HtmlContent.Free; end;

Un saludo.

Buenas tardes a tod@s, el código del botón que imprime el html es el siguiente

Código Delphi [-]
procedure ImprimirHTML(URL, NombreTrabajo: string);
begin
  CallInUIThread(
  procedure
  begin
    if doWebViewPrint then
    begin
      OnWebViewListener.NombreTrabajo := NombreTrabajo;
      WebClient.SetWebViewListener(OnWebViewListener);
      mWebView.setWebViewClient(WebClient);
      mWebview.getSettings.setAllowFileAccess(true); //ANDROID NIVEL DE API 30+
      mWebview.getSettings.setAllowFileAccessFromFileURLs(true); //ANDROID NIVEL DE API 30+
      mWebView.loadUrl(StringToJString(URL));
    end;
  end);
end;

La impresora imprime en formato A5, si el ticket tiene pocas líneas y cabe en un folio A5 lo imprime sin problemas, pero si tiene muchas lo deja cortado ya que solo imprime una hoja de A5 y deja la impresión cortada.

Dani, ¿sabes si hay que configurar algún parámetro en la unit UImpresion o algo similar?

Muchas gracias por vuestra atención.

Un saludo.


La franja horaria es GMT +2. Ahora son las 09:39:48.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi