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)
-   -   Problema BlueTooth Android 12 (https://www.clubdelphi.com/foros/showthread.php?t=96368)

jhonalone 24-09-2023 21:02:57

Problema BlueTooth Android 12
 
1 Archivos Adjunto(s)
Hola amigos.
Vergüenza siento de tener que volver a solicitar vuestra ayuda.
Como siempre, antes de molestaros he buscado y rebuscado todo lo posible y lo imposible.
No he hallado solución y me extraña que nadie haya tenido este problema aún.
Tengo una app que utiliza algunas funciones de bluetooth, como :
Código Delphi [-]
Adapter := TJBluetoothAdapter.JavaClass.getDefaultAdapter;
Adapter.enable;
JStringToString(Adapter.getName);
Y además otras acciones utilizadas para imprimir via bluetooth.
Como a partir de la versión de android 11 o 12 más o menos esto no me funciona he desarrollado una app
de prueba para ver si lo conseguía.
Como soy incapaz de conseguir que fuencione, os pido ayuda.
Adjunto podeis descargar la app de prueba para hacero una idea de lo que ocurre.
Gracias anticipadas por vuestra ayuda.
Saludos cordiales.
Archivo Adjunto 4117

Casimiro Notevi 25-09-2023 11:07:21

No sé si esto te servirá de ejemplo:

Código Delphi [-]
unit MainForm;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls;

type
  TForm1 = class(TForm)
    ButtonPrint: TButton;
    procedure ButtonPrintClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.ButtonPrintClick(Sender: TObject);
var
  Intent: JIntent;
begin
  // Crear un Intent para enviar datos a la impresora
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.setType(StringToJString('text/plain'));

  // Especificar el texto que deseas imprimir
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString('Texto para imprimir'));

  // Enviar el Intent para imprimir
  Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, nil);
  Intent.setPackage(StringToJString('com.android.bluetooth'));

  // Iniciar la actividad para imprimir
  SharedActivity.startActivity(Intent);
end;

end.


Debe estar la impresora emparejada en Android y asegúrate de tener los permisos adecuados para el Bluetooth.

jhonalone 25-09-2023 11:57:32

Muchas gracias Casimiro.
Es interesante para enviar texto a una impresora de escritorio por bluetooth..
Yo lo estoy enviando a una portátil en plan ticket, pero por bluetooth.
El problema está precisamente con los permisos.
Han cambiado desde la versión 12, según Google pero aunque le das los permisos, se cae el programa en la línea que indico en el adjunto.

He intentado darle todos los permisos que indica Google, pero nada. Siempre se cae en el mismo punto.

Código Delphi [-]
procedure TDevice.ListaDevices;
var
  Msg: string;
  I, B: Integer;

  ListaVinculados: TBluetoothDeviceList;
  LServices: TBluetoothServiceList;
begin

  try
  FBluetoothManager.Create;
   FBluetoothManager.EnableBluetooth;
    FBluetoothManager := TBluetoothManager.Current;
    if FBluetoothManager = nil
    then begin
         Close;
         end;

    FBluetoothManager.SocketTimeout := 100;

    BluetoothAdapter := FBluetoothManager.CurrentAdapter; // Aquí DA FALLO
     ShowMessage('Aquí');   exit;
    if BluetoothAdapter = nil
    then begin
         Close;
         end;

    ListaVinculados := FBluetoothManager.GetPairedDevices(BluetoothAdapter);
    if ListaVinculados = nil
    then begin
         Close;
         end;
         
   ComboDevices.Items.Clear; // Limpiamos cada vez el combo
   
    for I := 0 to ListaVinculados.Count - 1 do
    begin
      Impresora := ListaVinculados[i] as TBluetoothDevice;
      if Impresora.IsPaired then
      begin
        LServices := Impresora.GetServices;
        for B := 0 to LServices.Count - 1 do
        begin
          ServiceGUI := GUIDToString(LServices[b].UUID);
          Guid := LServices[b].UUID;
          ServiceName := LServices[b].Name;
        end;
      end
      else begin
           Close;
           end;
    ComboDevices.Items.Add(Impresora.DeviceName);
    end;
  except
   on E: Exception do
   begin
     Close;
   end;

 end;
 //FBluetoothManager.Destroy;
 if ComboDevices.Items.Count > 0 // Seleccionamos el primero
   then ComboDevices.ItemIndex := 0;

end;
Este es el texto y el punto donde se cae el programa

En la versión 9 funciona perefecto.
La prueba del adjunto la estoy usando a ver si consigo comunicar en la versión 13.
El problema es muy parecido al de mi último post.
Saludos.

Casimiro Notevi 25-09-2023 12:15:21

No sé qué permisos estás usando, pero creo que para bluetooth no han cambiado.
De memoria te diría que ACCESS_FINE_LOCATION, PERMISSION_ACCESS_COARSE_LOCATION, BLUETOOTH_SCAN y BLUETOOTH_CONNECT

Casimiro Notevi 25-09-2023 12:39:02

Si el SDK >= 31 entonces los permisos deben ser BLUETOOTH_SCAN, BLUETOOTH_CONNECT y PERMISSION_ACCESS_FINE_LOCATION
En caso contrario basta con PERMISSION_ACCESS_FINE_LOCATION

jhonalone 25-09-2023 13:17:07

Casimiro, he probado lo improbable.
Estoy empezando a sospechar que el problema quizá sea de la versión de Delphi 11.0 que estoy usando.
Código Delphi [-]
// Hasta aquí llega
------------------------------------
  BluetoothAdapter := FBluetoothManager.CurrentAdapter; // Aquí DA FALLO
------------------------------------
// He probado con todos y con parte de ellos
const
  BlueTooth = 'android.permission.BLUETOOTH';
  BlueAdmin ='android.permission.BLUETOOTH_ADMIN';
  BlueConect='android.permission.BLUETOOTH_CONNECT';       //
  BlueScan = 'android.permission.BLUETOOTH_SCAN';           //
  BluePrint ='android.print.BLUETOOTH';
  BluePrivi ='android.permission.BLUETOOTH_PRIVILEGED';
  BlueDebug ='android.permission.BLUETOOTH_DEBUG';
  CorseLocate = 'android.permission.ACCESS_COARSE_LOCATION';
  FineLocate = 'android.permission.ACCESS_FINE_LOCATION';
  BlueSeting ='android.permission.BLUETOOTH_SETTINGS';
  BlueAdvert ='android.permission.BLUETOOTH_ADVERTISE';    //

Casimiro Notevi 25-09-2023 13:20:49

Mira esto.
EDITO: He equivocado el enlace y ahora no encuentro el que quería ponerte.

jhonalone 26-09-2023 00:59:24

No importa, Gracias.
Creo que estoy en vias de encontrar una solución.

jhonalone 26-09-2023 11:25:51

1 Archivos Adjunto(s)
¿SOLUCIONADO...?
Casi... Casi...
Siempre sale alguna meiga por ahí.
Ahora, he puesto los nuevos permisos en AndroidManifest.template.xml y he seguido las instrucciones de Google en este enlace.
Quizá le sobren algunos permisos, pero... "por mucho pan, nunca es mal año"
Hablando de las meigas... cuando la app está abierta, despues de unos segundos, el terminal emite un mensaje diciendo que "No responde. Cerrar o esperar"
y en ésas estamos.
Podéis descargar y probar la app con sus fuentes en el adjunto. Por si el tema le ayuda a alguien.
Archivo Adjunto 4119
Saludos.

Casimiro Notevi 26-09-2023 11:34:06

Claro, daba por hecho que ponías los permisos en el "manifest".
No puedo probarlo porque no tengo un delphi con android.

dani36652 27-09-2023 18:28:05

Cita:

Empezado por jhonalone (Mensaje 552612)
Hola amigos.
Vergüenza siento de tener que volver a solicitar vuestra ayuda.
Como siempre, antes de molestaros he buscado y rebuscado todo lo posible y lo imposible.
No he hallado solución y me extraña que nadie haya tenido este problema aún.
Tengo una app que utiliza algunas funciones de bluetooth, como :
Código Delphi [-]
Adapter := TJBluetoothAdapter.JavaClass.getDefaultAdapter;
Adapter.enable;
JStringToString(Adapter.getName);
Y además otras acciones utilizadas para imprimir via bluetooth.
Como a partir de la versión de android 11 o 12 más o menos esto no me funciona he desarrollado una app
de prueba para ver si lo conseguía.
Como soy incapaz de conseguir que fuencione, os pido ayuda.
Adjunto podeis descargar la app de prueba para hacero una idea de lo que ocurre.
Gracias anticipadas por vuestra ayuda.
Saludos cordiales.
Archivo Adjunto 4117

Hola, me descargué tu proyecto y lo que puedo notar es que no tienes seleccionados los permisos que vas a utilizar referente al Bluetooth y por ello no se te declaran en el Manifest.xml.

Te sugiero seleccionarlos eligiendo antes que todo la plataforma Android después irte a Project>Options>Uses Permissions y ahí marcar todos los permisos que va a usar tu aplicación y de igual forma al momento de construirse dichos permisos irán declarados en el manifest de manera automática.

Desconozco si ya depuraste, pero hay algo muy extraño o al menos me ocurre a mí que en la versión comunitaria de Delphi no se muestran las excepciones y simplemente se cierra el depurador. Saludos cordiales.

jhonalone 27-09-2023 21:58:43

1 Archivos Adjunto(s)
Muchas gracias. Dani.
Espero que la versión que hayas bajado sea la última.
Utilizo Delphi 11.0.
Algunos de los permisos nuevos, los he tenido que declarar en el Manifest directamente, porque no aparecen en la lista de Project>Options>Uses Permissions
La última versión funciona correctamente.
Archivo Adjunto 4120
Ahora tengo un problema nuevo: como el terminal (Android 13) tarda en encontrar los dispositivos, genera un error en el dispositivo de "PruebaBluetooth no responde" "Cerrar aplicación" "Esperar". Esto ocurren en Android 13, en otro terminal con Android 9 no ocurre. (También tarda un poco en detectar los dispositivos)

He desarrollado un simple programa para asegurarme de que el error depende de la espera y he confirmado que me salta el mismo error.
Código Delphi [-]
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.ListBox;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
 I : Integer;
begin
  for I := 1 to 25
  do begin
       ComboBox1.Items.Add('Item Lento '+ I.ToString);
       Sleep(1000);
     end;

end;

end.

No sé como evitar el mensaje. Quizá abra un nuevo hilo para ver si alguien lo ha resuelto.
Un efusivo saludo.

dani36652 28-09-2023 19:33:21

Cita:

Empezado por jhonalone (Mensaje 552722)
Muchas gracias. Dani.
Espero que la versión que hayas bajado sea la última.
Utilizo Delphi 11.0.
Algunos de los permisos nuevos, los he tenido que declarar en el Manifest directamente, porque no aparecen en la lista de Project>Options>Uses Permissions
La última versión funciona correctamente.
Archivo Adjunto 4120
Ahora tengo un problema nuevo: como el terminal (Android 13) tarda en encontrar los dispositivos, genera un error en el dispositivo de "PruebaBluetooth no responde" "Cerrar aplicación" "Esperar". Esto ocurren en Android 13, en otro terminal con Android 9 no ocurre. (También tarda un poco en detectar los dispositivos)

He desarrollado un simple programa para asegurarme de que el error depende de la espera y he confirmado que me salta el mismo error.
Código Delphi [-]
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.ListBox;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
 I : Integer;
begin
  for I := 1 to 25
  do begin
       ComboBox1.Items.Add('Item Lento '+ I.ToString);
       Sleep(1000);
     end;

end;

end.

No sé como evitar el mensaje. Quizá abra un nuevo hilo para ver si alguien lo ha resuelto.
Un efusivo saludo.

Hola estimado... quizás eso se resuelva metiendo esa tarea "pesada" a un hilo en segundo plano evitando así que durante la tarea se te "congele" el hilo principal y el sistema operativo te indique que la app no responde.
Prueba algo como esto:

Código Delphi [-]
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.ListBox;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
 ThreadSegPlano: TThread;
begin
  ThreadSegPlano:= TThread.CreateAnonymousThread(
  procedure 
  var 
    I : Integer; //Los contadores en hilos y procedimientos anonimos deben ser variables locales...
  begin
    for I := 1 to 25 do
    begin 
      //Siempre haz un Synchronize cuando modifiques el estado y propiedades de objetos visuales en este caso el Combo
      TThread.Synchronize(TThread.CurrentThread,
      procedure
      begin     
        ComboBox1.Items.Add('Item Lento '+ I.ToString);
      end);
      Sleep(1000); //Esta es tu tarea pesada, se le deja al hilo en segundo plano.....
    end;
  end);
  ThreadSegPlano.FreeOnTerminate:= True; //Liberar el hilo en memoria cuando termine
  //ThreadSegPlano.OnTerminate:= Aquí puedes asignarle un evento para cuando termine el hile como ocultar algun loading panel o mostrar un mensaje 
 // de carga finalizada, etc.
  ThreadSegPlano.Start;
end;

end.

Considero que en tu caso deberás meter el código de la búsqueda en un hilo en segundo plano pero no te olvides de hacer el synchronize a los objetos visuales...

Resumen para usar un hilo (Thread):

Código Delphi [-]
 procedure BtnClick(Sender: TObject);
 var 
   Thread: TThread; //Declaras el hilo
 begin
   Thread:= TThread.CreateAnonymousThread(
    procedure 
    begin 
      TareaPesada;
       TThread.Synchronize(TThread.CurrentThread,
       procedure 
       begin
         //Modificar Objetos visuales Ej. Label.Text:= 'Hola';
       end);
    end);  
   Thread.FreeOnTerminate:= True;
   Thread.Start;
 end;

Saludos cordiales!

jhonalone 28-09-2023 22:21:14

Hola, Dani.
No estoy familiarizado con los hilos TThread.
Intentaré implementarlo y te contaré.
Si me veo obligado y no soy capaz, te rogaría que me ayudaras implementándolo en el procedimiento que me originó el problema y yo ya lo trasladaría a otros problemas similales. Gracias.
Código Delphi [-]
procedure TDevice.ListaDevices;
var
  Msg: string;
  I, B: Integer;

  ListaVinculados: TBluetoothDeviceList;
  LServices: TBluetoothServiceList;
begin

  try

    FBluetoothManager := TBluetoothManager.Current;
    if FBluetoothManager = nil
    then begin
         Close;
         end;

    FBluetoothManager.SocketTimeout := 100;

    BluetoothAdapter := FBluetoothManager.CurrentAdapter;

    if BluetoothAdapter = nil
    then begin
         Close;
         end;

    ListaVinculados := FBluetoothManager.GetPairedDevices(BluetoothAdapter);
    if ListaVinculados = nil
    then begin
         Close;
         end;

   ComboDevices.Items.Clear; // Limpiamos cada vez el combo

    for I := 0 to ListaVinculados.Count - 1 do
    begin
      Impresora := ListaVinculados[i] as TBluetoothDevice;
      if Impresora.IsPaired then
      begin
        LServices := Impresora.GetServices;
        for B := 0 to LServices.Count - 1 do
        begin
          ServiceGUI := GUIDToString(LServices[b].UUID);
          Guid := LServices[b].UUID;
          ServiceName := LServices[b].Name;
        end;
      end
      else begin
           Close;
           end;
    ComboDevices.Items.Add(Impresora.DeviceName);
    end;
  except
   on E: Exception do
   begin
     Close;
   end;

 end;
 FBluetoothManager.Free;
 BluetoothAdapter.Free;
 Guid.Empty;
 if ComboDevices.Items.Count > 0 // Seleccionamos el primero
   then ComboDevices.ItemIndex := 0;

end;
Un saludo muy efusivo.

jhonalone 29-09-2023 11:31:54

Miles de gracias Dani, por tus aportaciones y, sobre todo, por tu tiempo y tu interés
Funciona perfecto. Ya no salta el mensje de esperar/cerrar. Sólo una meiga: el programa no cierra con el boón vkHardwareBack del dispositivo.
Bueno, la meiga se solucionó con esto
Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
begin
 Application.Terminate;
end;
A ver si soy capaz de implementarlo en el procedimiento de la lista de pareados por bluetooth.
Gracias nuevamente. Un saludo muy cordial.

jhonalone 29-09-2023 16:47:39

Gracias otra vez, dani36652.
Basado en tus explicaciones y tus consejos he conseguido resolver mis 2 problemas:
1) Acceder a los ficheros internos en Android 13 aqui.
2) Eliminar el mensaje de que la aplicación "No responde. Esperar o Cerrar" aqui
Lo publico porque creo que puede haber alguien que pueda tener el mismo problema. Es mi costrunbre.
Saludos muy cordiales.


La franja horaria es GMT +2. Ahora son las 23:10:53.

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