Search code examples
androiddelphibluetoothdelphi-xe5delphi-xe6

How to send a string or char by bluetooth with delphi XE5?


I'm trying to make a app to work with Arduino. I just would like to send a character or a simple string, like "a".

Here is my current code:

unit TabbedFormwithNavigation;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Graphics, FMX.Forms, FMX.Dialogs, FMX.TabControl, FMX.StdCtrls,
  System.Actions, FMX.ActnList, FMX.Gestures, FMX.ListView.Types, FMX.ListView;
  Androidapi.JNI.BluetoothAdapter,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNIBridge,
  FMX.ListBox, FMX.Layouts, FMX.Memo, FMX.Edit, FMX.Objects, FMX.ListView.Types,
  FMX.ListView, System.Rtti, FMX.Grid, Data.Bind.GenData,
  System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt,
  Fmx.Bind.DBEngExt, Data.Bind.Components, Data.Bind.ObjectScope;

//------------------------------------------------------------------------------

type
  TTabbedwithNavigationForm = class(TForm)
    TabControl1: TTabControl;
    TabItem1: TTabItem;
    TabItem2: TTabItem;
    TabItem3: TTabItem;
    TabItem4: TTabItem;
    ActionList1: TActionList;
    TabControl2: TTabControl;
    TabItem5: TTabItem;
    TabItem6: TTabItem;
    ChangeTabAction1: TChangeTabAction;
    ToolBar1: TToolBar;
    lblTitle1: TLabel;
    ToolBar2: TToolBar;
    lblTitle2: TLabel;
    ToolBar3: TToolBar;
    lblTitle3: TLabel;
    ToolBar4: TToolBar;
    lblTitle4: TLabel;
    ToolBar5: TToolBar;
    lblTitle5: TLabel;
    ChangeTabAction2: TChangeTabAction;
    btnBack: TSpeedButton;
    btnNext: TSpeedButton;
    GestureManager1: TGestureManager;
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
      Shift: TShiftState);
    procedure TabControl1Gesture(Sender: TObject;
      const EventInfo: TGestureEventInfo; var Handled: Boolean);
    procedure FormShow(Sender: TObject);
    procedure ListView1ItemClick(const Sender: TObject;
      const AItem: TListViewItem);
  private
    { Private declarations }
  public
    { Public declarations }
    targetMACAddress:string; // Endereço MAC do dispositivo selevionado
    ostream:JOutputStream;
    istream:JInputstream;
    uid:JUUID;              // UUID para tráfego SPP
    Sock:JBluetoothSocket;
    Adapter:JBluetoothAdapter;  // Adaptador BLUETOOTH local
    remoteDevice:JBluetoothDevice;
  end;

//------------------------------------------------------------------------------

var
  TabbedwithNavigationForm: TTabbedwithNavigationForm;

implementation

{$R *.fmx}

procedure TTabbedwithNavigationForm.FormCreate(Sender: TObject);
begin
  { This defines the default active tab at runtime }
  TabControl1.ActiveTab := TabItem4;
{$IFDEF ANDROID}
  { This hides the toolbar back button on Android }
  btnBack.Visible := True;
{$ENDIF}
end;

//------------------------------------------------------------------------------

procedure TTabbedwithNavigationForm.FormKeyUp(Sender: TObject; var Key: Word;
  var KeyChar: Char; Shift: TShiftState);
begin
  if Key = vkHardwareBack then
  begin
    if (TabControl1.ActiveTab = TabItem1) and (TabControl2.ActiveTab = TabItem6) then
    begin
      ChangeTabAction2.Tab := TabItem5;
      ChangeTabAction2.ExecuteTarget(Self);
      ChangeTabAction2.Tab := TabItem6;
      Key := 0;
    end;
  end;
end;

//------------------------------------------------------------------------------

procedure TTabbedwithNavigationForm.FormShow(Sender: TObject);
var
  s:string;
  i:integer;
  list:TStringList;
begin
  list:=TStringList.Create;
  s:=checkBluetooth; // Verifica se o bluetooth está habilitado
  if pos('disabled',s)<>0 then begin
    ShowMessage('Por favor, ligue o bluetooth e tente novamente!');
    exit
  end;

  // Esta é a melhor conexão SPP UUID para conectar com um dispositivo serial Bluetooth
  uid:=TJUUID.JavaClass.fromString(stringtojstring('00001101-0000-1000-8000-00805F9B34FB'));

  list.Clear;
  list.AddStrings(getbonded);    // Faz uma lista com dispositivos pareados

  listview1.Items.Clear;  // Lampa a lista e a reconstrói
  listview1.BeginUpdate;
  for i := 0 to list.Count-1 do begin
    listview1.Items.Add;
    listview1.Items.Item[i].Text:=list[i].Split(['='])[0];
    listview1.Items.Item[i].Detail:=list[i].Split(['='])[1];
  end;
  listview1.EndUpdate
end;

//------------------------------------------------------------------------------

procedure TTabbedwithNavigationForm.ListView1ItemClick(const Sender: TObject;
  const AItem: TListViewItem);
begin

  ShowMessage('Você selecionou: '+Aitem.Text);

  // Dependendo do dispositivo bluetooth selecionado - fazer alguma coisa com ele
  targetMACAddress:=Aitem.Detail;
  if trim(targetMACAddress)='' then exit;

  Adapter:=TJBluetoothAdapter.JavaClass.getDefaultAdapter;
  remoteDevice:=Adapter.getRemoteDevice(stringtojstring(targetMACAddress));
  sock:=remoteDevice.createRfcommSocketToServiceRecord(UID);
  try
    sock.connect;
  except
    ShowMessage('Não pôde conectar-se com o dispositivo bluetooth');
  end;
  if not sock.isConnected then
  begin
    ShowMessage('Falha ao tentar conectar novamene, tente de novo...');
    exit;
  end;
    Toast('Conectado');
    TabControl1.ActiveTab := TabItem1;
end;

end;

//------------------------------------------------------------------------------

procedure TTabbedwithNavigationForm.TabControl1Gesture(Sender: TObject;
  const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
{$IFDEF ANDROID}
  case EventInfo.GestureID of
    sgiLeft:
    begin
      if TabControl1.ActiveTab <> TabControl1.Tabs[TabControl1.TabCount-1] then
        TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex+1];
      Handled := True;
    end;

    sgiRight:
    begin
      if TabControl1.ActiveTab <> TabControl1.Tabs[0] then
        TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex-1];
      Handled := True;
    end;
  end;
{$ENDIF}
end;

end.

//------------------------------------------------------------------------------

function StringToJA(Data: String): TJavaArray<Byte>;
var
  Arr: TBytes;
  len: integer;
begin
  Arr := TEncoding.Default.GetBytes(Data);
  len := Length(Arr);
  Result := TJavaArray<Byte>.Create(len);
  if len > 0 then Move(Arr[0], Result.Data^, len);
end;

//------------------------------------------------------------------------------

I just want to know how to send the information when I click at the button, how exactly I can do this. I know I must use the function below:

function StringToJA(Data: String): TJavaArray<Byte>;
var
  Arr: TBytes;
  len: integer;
begin
  Arr := TEncoding.Default.GetBytes(Data);
  len := Length(Arr);
  Result := TJavaArray<Byte>.Create(len);
  if len > 0 then Move(Arr[0], Result.Data^, len);
end;

PS.: If you know how to convert this code into C++ will be helpfull to me, because C++ is easier than delphi to me.

Since now, thanks a lot.


Solution

  • Once you have connected the BluetoothSocket to a paired device, call the socket's getInputStream() and getOutputStream() methods to obtain streams that you can use for reading and writing, respectively.