Utilizar Intents en rad studio 10

Un intent sirve para hacer una llamada a componentes de la interfaz gráfica, servicios, código que se ejecutan en segundo plano como los  broadcast receivers, broadcast messages, etc ( en android se llaman activities).

En rad studio podemos acceder a los Intents a través de la clase JIntent que está en la Unit 
Androidapi.JNI.GraphicsContentViewText.

Las activities son parecidos a los forms de Delphi y tienen 2 partes, la parte lógica y la parte gráfica.
La parte lógica es un archivo .java que se usa para manipular, interactuar con el código de esa actividad. La parte gráfica es un archivo XML que tiene definidos todos los elementos del form con etiquetas parecidas al HTML.
En definitiva un intent sirve para llamar a aplicaciones externas a la nuestra, lanzar eventos a los que otras aplicaciones puedan responder, lanzar alarmas, etc.
Desde el link developer.android.com/guide/appendix/g-app-intents.html podéis encontrar una lista con las aplicaciones disponibles en Android junto con los intents que las invocan.

Por ejemplo, para el navegador web, tenemos dos acciones, VIEW y WEB_SEARCH, que abren el navegador en una url específica o realizan una búsqueda.
En el caso del dialer (marcador), tenemos las acciones CALL y DIAL, que vienen dadas por la URI tel:numero_de_teléfono, la diferencia entre estas dos acciones, es que CALL realiza la llamada al número de la URI, y DIAL solo lo marca, pero no realiza la llamada.


Ejemplos para rad studio 10 Seattle

-Abrir una URL
-Abrir un archivo PDF 
-
Enviar un texto 
-
Enviar un email 
-
Obtener el estado de la batería


-Obtener la versión de la aplicación
-Comprobar que una app tiene un permiso determinado para enviar un SMS

Abrir una URL
uses
  Androidapi.JNI.GraphicsContentViewText,
  FMX.Helpers.Android;


procedure TForm3.Button1Click(Sender: TObject);
var
  Intent: JIntent;
begin
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setData(StrToJURI('http://www.google.com'));
  SharedActivity.startActivity(Intent);
end;


Abrir un archivo PDF
uses
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.JavaTypes,
  FMX.Helpers.Android;


procedure TForm3.Button1Click(Sender: TObject);
var
  Intent: JIntent;
begin
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setDataAndType(StrToJURI('filepath'),  StringToJString('application/pdf'));
  SharedActivity.startActivity(Intent);
end;

Enviar un texto
procedure THeaderFooterForm.Button2Click(Sender: TObject);
var
  Intent: JIntent;
begin
  // Intent intent = new Intent(Intent.ACTION_SEND);
  // intent.setType("text/plain");
  // intent.putExtra(android.content.Intent.EXTRA_TEXT, "Android Rocks!!!");
  // startActivity(intent);

  Intent := TJIntent.Create;
  Intent.setType(StringToJString('text/plain'));
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT,
    StringToJString('Delphi Rocks!!!'));
  MainActivity.startActivity(Intent);
end;

Enviar un email
Uses
Androidapi.JNI.GraphicsContentViewText, Androidapi.JNIBridge, Androidapi.JNI.JavaTypes, FMX.Helpers.Android, Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.IOUtils; 

Procedure SendEmail(Const eAddress, eObject, eText, eAttach : String); 
var
 Intent : JIntent; 
D, S : JString; 
Uri : TJnet_Uri;
 Begin
 Intent := TJIntent.Create;
 Intent.setAction(TJIntent.JavaClass.ACTION_Send);
 Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK); 
Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, StringToJString(eAddress)); Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(eObject)); intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(eText)); Uri:=TJnet_Uri.JavaClass.parse(StringToJString(FileName));
 Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, Uri); Intent.setType(StringToJString('vnd.android.cursor.dir/email'));
 SharedActivity.startActivity(Intent); 
End;


Obtener el estado de la batería

Tomado de http://neftali.clubdelphi.com/?p=3157
Post en el que explica  cómo hacer una app utilizando Intents para obtener el estado de la batería del móvil.

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.Edit,
  FMX.StdCtrls, FMX.Layouts, FMX.Memo, FMX.Objects, FMX.Effects;

type

  TForm1 = class(TForm)
    Edit1: TEdit;
    Memo1: TMemo;
    Label1: TLabel;
    ShadowEffect1: TShadowEffect;
    Label2: TLabel;
    Image1: TImage;
    Image2: TImage;
    Label3: TLabel;
    BlurEffect1: TBlurEffect;
    Panel1: TPanel;
    Button2: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
const
  BateryHealthStr: array [1..7] of string =
    ('unknown', 'Good', 'Overhead', 'Dead', 'Over voltage', 'unspecified failure', 'Cold');
  BateryPluggedStr: array [1..4] of string =
    ('AC plugged', 'USB plugged', 'unknown',  'Wireless plugged');
  BateryStatusStr: array [1..5] of string =
    ('Unknown', 'Charging', 'Discharging', 'Not charging', 'Full');

const
  BATTERY_HEALTH_COLD = 7;
  BATTERY_HEALTH_DEAD = 4;
  BATTERY_HEALTH_GOOD = 2;
  BATTERY_HEALTH_OVERHEAT = 3;
  BATTERY_HEALTH_OVER_VOLTAGE = 5;
  BATTERY_HEALTH_UNKNOWN = 1;
  BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;

implementation

{$R *.fmx}

uses
  AndroidAPI.JNI.GraphicsContentViewText,
  AndroidAPI.JNI.JavaTypes,
  AndroidAPI.JNI.OS,
  FMX.Platform.Android,
  Androidapi.JNIBridge, Androidapi.Jni,  androidapi.JNI.Net,
  FMX.Helpers.Android;


procedure TForm1.Button1Click(Sender: TObject);
var
  filter: JIntentFilter;
  intentBatt: JIntent;
  iLevel, iScale: Integer;
  i:Integer;
  Str:JString;
  b:boolean;
  myContext: JContext;
begin
  // Contexto
  myContext := SharedActivityContext;

  // Creamos y Configuramos el Intent
  filter := TJIntentFilter.Create;
  // Asociamos la ACTION que queremos capturar
  filter.addAction(TJIntent.JavaClass.ACTION_BATTERY_CHANGED);
  // lo registramos
  intentBatt := myContext.registerReceiver(nil, filter);


  Memo1.Lines.Clear;

  // health
  i := intentBatt.getIntExtra(StringToJString('health'), -1);
  Memo1.Lines.Add('Salut: ' + BateryHealthStr[i]);
  // Icon
  //  i := battery.getIntExtra(StringToJString('icon-smal'), -1);
  //  Memo1.Lines.Add('icon-smal: ' + IntToStr(i));
  // Nivel de batería
  iLevel := intentBatt.getIntExtra(StringToJString('level'), -1);
  Memo1.Lines.Add('Level: ' + IntToStr(iLevel));
  // Plugged
  i := intentBatt.getIntExtra(StringToJString('plugged'), -1);
  Memo1.Lines.Add('Enchufado: ' + BateryPluggedStr[i]);
  // battery present
  b := intentBatt.getBooleanExtra(StringToJString('present'), False);
  Memo1.Lines.Add('Presente: ' + BoolToStr(b, True));
  // Escala para medir el nivel
  iScale := intentBatt.getIntExtra(StringToJString('scale'), -1);
  Memo1.Lines.Add('Escala: ' + IntToStr(iScale));
  // status de la batería
  i := intentBatt.getIntExtra(StringToJString('status'), -1);
  Memo1.Lines.Add('Estado: ' + BateryStatusStr[i]);
  // tecnología de la batería
  Str := intentBatt.getStringExtra(StringToJString('technology'));
  Memo1.Lines.Add('Tecnología: ' + JStringToString(Str));
  // Temperatura (en décimas de grado)
  i := intentBatt.getIntExtra(StringToJString('temperature'), -1);
  Memo1.Lines.Add('Temperatura: ' + FloatToStr(i / 10) + '°');
  // Voltage (en MILIVOLTIOS)
  i := intentBatt.getIntExtra(StringToJString('voltage'), -1);
  Memo1.Lines.Add('Voltaje: ' + FloatToStr(i/1000) + ' v.');

  // Mostramos la escala en el form
  i := (100 * iLevel) div iScale;
  Edit1.Text := IntToStr(i) + '%';
  // Modificar la imagen  (0..1)
  Image2.Scale.X := (i / 100);


end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Button1Click(nil);
end;


procedure TForm1.Button4Click(Sender: TObject);
var
  Intent: JIntent;
begin
  // Navegar
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setData(StrToJURI('http://neftali.clubdelphi.com'));
  SharedActivity.startActivity(Intent);

end;

end.


Obtener la versión de la aplicación
  uses
    Androidapi.JNI.JavaTypes,
    FMX.Helpers.Android,
    Androidapi.JNI.GraphicsContentViewText;


{$R *.fmx}

procedure TForm25.Button1Click(Sender: TObject);
var
  PackageManager: JPackageManager;
  PackageInfo : JPackageInfo;
begin
  PackageManager := SharedActivity.getPackageManager;
  PackageInfo := PackageManager.getPackageInfo(SharedActivityContext.getPackageName(), TJPackageManager.JavaClass.GET_ACTIVITIES);
  Edit1.Text:= JStringToString(PackageInfo.versionName);
end;


Comprobar que una app tiene un permiso determinado para enviar un SMS

uses
  System.UITypes,
  FMX.Dialogs,
  FMX.Helpers.Android,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Telephony;

function HasPermission(const Permission: string): Boolean;
begin
  //Permissions listed at http://d.android.com/reference/android/Manifest.permission.html
  Result := SharedActivity.checkCallingOrSelfPermission(
    StringToJString(Permission)) =
    TJPackageManager.JavaClass.PERMISSION_GRANTED
end;

procedure SendSMS(const Number, Msg: string);
var
  SmsManager: JSmsManager;
begin
  if not HasPermission('android.permission.SEND_SMS') then
    MessageDlg('App does not have the SEND_SMS permission',
      TMsgDlgType.mtError, [TMsgDlgBtn.mbCancel], 0)
  else
  begin
    SmsManager := TJSmsManager.JavaClass.getDefault;
    SmsManager.sendTextMessage(
      StringToJString(Number),
      nil,
      StringToJString(Msg),
      nil,
      nil);
  end;
end;

3 comentarios:

  1. Excelente contribución, muchas gracias por compartir.

    ResponderEliminar
  2. Muy buena la contribución, he tenido problemas al pasar el código a c++ , alguien tendrá estos códigos en C++.

    ResponderEliminar
  3. Aquí tienes un conversor a c++
    http://www.texttransformer.com/Delphi2Cpp_en.html

    ResponderEliminar