Tips a tener en cuenta al crear apps móviles

TIPOS DE DATOS
El código fuente que use cualquiera de los siguientes tipos de datos no soportados, debería ser eliminado o reescrito usando un tipo alternativo
WideString, AnsiString, ShortString, AnsiChar, PAnsiChar, PWideChar, Openstring
Tipos usados en aplicaciones de escritorio
(1-based)
Tipos usados en Mobile Apps
(0-based)
Elimina su uso.
Considera utilizar 'array of byte'
Considera utilizar 'array of byte'


Se recomienda usar la clase tStringHelper para manejar Strings en apps Desktop y Móviles.
tStringHelper hace las conversiones automáticamente, por lo que puedes usar strings 0-based o 1-based en todos tus programas. Internamente todas las funciones y propiedades son 0-based en todos los escenarios.
Algunas de las funciones RTL que trabajan con strings 1-based tienen un sustituto directo como una función TStringHelper, según la siguiente tabla.
Delphi RTL Function
(1-based)
TStringHelper Function
(0-based)*
System.Pos
TStringHelper.IndexOf
System.Delete
TStringHelper.Remove
System.Copy
TStringHelper.Substring
System.SysUtils.Trim
TStringHelper.Trim


RESTRICCIONES DE COMPONENTES

No todos los componentes de la Tool Palette se pueden usar para una app Android, en función del tipo de app automáticamente se mostrarán los componentes adecuados.


FRAMEWORKS PARA ANDROID

FireMonkey
Es el framework ideal para desarrollo Android
VCL (No disponible para Android)
La VCL está disponible para Windows (32-bit or 64-bit).

RECOMENDACIONES DE ALINEACIÓN DE LAS TOOLBAR EN APPS PARA MÓVILES
Para asegurarse de que la barra de herramientas en su aplicación móvil se comporta y se ve igual en las plataformas iOS y Android, debe establecer las propiedades específicas de alineación en el Inspector de Objetos, de la siguiente manera:
Establezca la propiedad Align para todos los controles child de un TToolBar. Por ejemplo, los siguientes son los valores de propiedad align:
(alLeft, alRight, alCenter, alContents)
- Para mantener el espacio entre los controles, o para mantener el espacio entre el borde  izquierdo y derecho de las barras de herramientas, establezca las siguientes propiedades:
  Margins: (left, right)
  Padding: (left, right)

MarginsAndPadding

Por ejemplo, suponga que tiene una barra de herramientas con un child TLabel como  título, y dos speedbuttons alineados a la izquierda con espacio entre cada botón:
1)     En el  TToolBar, ponga
Align = alTop
2)     En el child TLabel, ponga
Align = alContents
3)     Envíe el TLabel a la parte posterior con el menú contextual.
4)     En los dos child TSpeedButtons , establezca:
Align = alLeft, alRight, alCenter, alContents, alVertCenter
Margins Left = 5



-  Para formatear un control segmentado (varios TSpeedButtons con un nombre de grupo común) de manera que se centre en la barra de herramientas:
Agregue un control TLayout a la TToolBar.
Establezca TLayout.Align a alCenter.
Añada botones a un TLayout y establezca las propiedades de alineación y márgenes para cada botón (Align = alLeft, Margins = Left, Margins = Right, y así sucesivamente).
- Para utilizar TLabel, debe establecer TLabel.AutoSize = False y establezca la propiedad Align.
Para centrar la etiqueta en una barra de herramientas que ya tiene botones, debe establecer TLabel.Align = alContents y seleccione ” Enviar al fondo” en el menú contextual.
Reglas de alineación similares se refieren a otros controles. Por ejemplo, suponga que haya agregado un TSwitch a un elemento del cuadro de lista; para que el switch quede ajustado a la derecha y centrado verticalmente, establezca las siguientes propiedades para TSwitch:
Align = Alright
Margins Right = 5

UTILIZAR FONTS EN ANDROID
Se pueden utilizar las fuentes que se quieran en tiempo de desarrollo, (serán las fuentes de su propio PC, que estarán instaladas en Windows, sin embargo, al implementar la aplicación para el dispositivo de destino (iOS o Android), las fuentes de la aplicación que se utilizarán serán las fuentes instaladas en el dispositivo. Las fuentes que se muestran en tiempo de diseño en el IDE no se copian en el dispositivo.
Para saber si una fuente puede estar disponible en tiempo de ejecución en un dispositivo móvil específico, es necesario comprobar si la fuente que está utilizando en tiempo de diseño es compatible con los dispositivos de destino:
 Fonts instaladas con iOS 6: http://support.apple.com/kb/ht5484
 Fonts instaladas con iOS 5: http://support.apple.com/kb/HT4980

PONER LOS PERMISOS NECESARIOS
Algunos permisos de Android básicos están preprogramadas para todas las aplicaciones Android FireMonkey. Se debe comprobar que los permisos de acceso específicos están habilitados para su dispositivo Android en la página de Opciones de proyecto.
Por ejemplo:
Para utilizar la cámara del dispositivo Android, asegúrese de que los permisos siguientes están habilitados:
  • Camera
  • Read/Write external storage

Para utilizar la ubicación GPS en el dispositivo Android, asegúrese de que uno o más de los permisos de acceso a la ubicación están activados:
  • Access coarse location
  • Access fine location
  • Access location extra commands
Para grabar audio en el dispositivo Android, asegúrese de que el siguiente permiso está habilitado:
  • Record audio

USANDO EL BOTÓN BACK DE ANDROID
Cuando el usuario presiona el botón Back de su dispositivo Android, se puede agregar un controlador de eventos en su form para el evento OnKeyUp y pegar el siguiente código en el controlador de eventos:

En Delphi:

if Key = vkHardwareBack then
begin
  // Do whatever you want to do here
  Key := 0; // Set Key = 0 if you want to prevent the default action
end;

Tip: Con el Tabbed with Navigation mobile template se implementa este manejador de evento

HACIENDO QUE TU APP FUNCIONE EN PANTALLA COMPLETA
De forma predeterminada, las aplicaciones de Android muestran la barra de estado de Android.
Si desea que la aplicación se ejecute en modo de pantalla completa y oculte la barra de estado Android, seleccione Proyecto - Opciones -Información de la versión y cambie el valor del  theme key a  No TitleBar.

SETTINGS PARA EL KEYBOARD, TEDIT Y TMEMO
  Keyboard
Pon la propiedad vkAutoShowMode a  vkasDefinedBySystem, vkasNever, or vkasAlways.
  TEdit and TMemo
Activa KillFocusByReturn (Permite que la tecla RETURN quite el foco al control actual)

USANDO ICONOS E IMÁGENES EN MÚLTIPLES RESOLUCIONES

En Android, las siguientes resoluciones son compatibles:
1x, 1,5x, 2x, 3x (pequeña, normal, grande, extra grande)
En iOS, las siguientes resoluciones son compatibles:
1x y 2x (Non-Retina y Retina)
Resoluciones múltiples pueden ser soportadas creando un MultiResBitmap usando el nuevo Editor MultiResBitmap .Para mas información vea Using Multi-Resolution Bitmaps
MultiResBitmap que soporta los siguientes formatos en  Android: 1x, 1.5x, 2.5x

Obtener info de la conexion wifi Android

Esta unit obtiene información de la conexión wifi y de los puntos de acceso disponibles desde vuestro móvil. Recordar que desde Project->Options->User Permissions hay que habilitarle el permiso ACCESS_WIFI_STATE


unit Unit2;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo,Androidapi.Helpers,
  Androidapi.JNI.JavaTypes, Androidapi.JNIBridge,
  Androidapi.JNI.GraphicsContentViewText, Androidapi.jni.net;

type
  TForm2 = class(TForm)
    Memo1: TMemo;
    ToolBar1: TToolBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}

procedure TForm2.Button1Click(Sender: TObject);

var
  Service: JObject;
  WifiManager: JWifiManager;
  ConnectionInfo: JWifiInfo;
  ScanResults: JList;
  ScanResult: JScanResult;
  I: Integer;
begin

  Memo1.Visible := true;
  Memo1.Lines.Clear;

  Service := SharedActivity.getSystemService(TJContext.JavaClass.WIFI_SERVICE);
    if not Assigned(Service) then
    raise Exception.Create('Could not locate Wifi Service');
  WifiManager := TJWifiManager.Wrap((Service as ILocalObject).GetObjectID);
  //tJwifimanager esta en la unit
  if not WifiManager.isWifiEnabled then
    Memo1.Lines.Add('Wifi is disabled')
  else
  begin
    ConnectionInfo := WifiManager.getConnectionInfo;
    Memo1.Lines.Add('Connection info');
    Memo1.Lines.Add('  SSID: ' + JStringToString(ConnectionInfo.getSSID));
    Memo1.Lines.Add('  BSSID: ' + JStringToString(ConnectionInfo.getBSSID));
    Memo1.Lines.Add('  MAC address: ' + JStringToString(ConnectionInfo.getMacAddress));
    ScanResults := WifiManager.getScanResults;
    for I := 0 to ScanResults.size - 1 do
    begin
      Memo1.Lines.Add('');
      Memo1.Lines.Add('Detected access point ' + IntToStr(I));
      ScanResult := TJScanResult.Wrap((ScanResults.get(I) as ILocalObject).GetObjectID);
      Memo1.Lines.Add('  SSID: ' + JStringToString(ScanResult.SSID));
      Memo1.Lines.Add('  BSSID: ' + JStringToString(ScanResult.BSSID));
      Memo1.Lines.Add('  Capabilities: ' + JStringToString(ScanResult.capabilities));
      Memo1.Lines.Add('  Frequency: ' + IntToStr(ScanResult.frequency) + 'MHz');
      Memo1.Lines.Add('  Signal level: ' + IntToStr(ScanResult.level) + 'dBm');
    end
  end
end;

end.



Libros: