milenjao
milenjao

Reputation: 165

Delphi FMX Android app. How to open SMS window

How I can open Short Message Service (SMS) window on Android phode with pretyped message text and recipient number.

In manuals i found only Phone dialer

      PhoneDialerService.Call(edtTelephoneNumber.Text)

which allow make call, but nothing about sending SMS messages.

Upvotes: 1

Views: 2912

Answers (2)

blong
blong

Reputation: 2175

The question asks about launching the SMS window, which I've taken to mean launching the built-in SMS-sending app. It wants a target number and message content sent in.

This can be done by asking Android to start an activity using an intent set up to view a carefully crafted SMS-specific URI and containing the required message as an extra field.

The primary benefit to invoking the SMS app rather than sending the SMS within your own app is that it does not require additional permissions - the SMS app already has those permissions.

I show how to do this in my old activity launching article (which was written for Delphi XE6 but is still applicable to all later versions, with a few minor code updates here and there), but for completeness here is a helper unit that does the job:

unit SMSHelperU;

interface

procedure CreateSMS(const Number, Msg: string);

implementation

uses
  Androidapi.Helpers,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.App,
  Androidapi.JNI.Net,
  Androidapi.JNI.GraphicsContentViewText,
  System.SysUtils;

function LaunchActivity(const Intent: JIntent): Boolean; overload;
var
  ResolveInfo: JResolveInfo;
begin
{$IF RTLVersion >= 30}
  ResolveInfo := TAndroidHelper.Activity.getPackageManager.resolveActivity(Intent, 0);
{$ELSE}
  ResolveInfo := SharedActivity.getPackageManager.resolveActivity(Intent, 0);
{$ENDIF}
  Result := ResolveInfo <> nil;
  if Result then
{$IF RTLVersion >= 30}
    TAndroidHelper.Activity.startActivity(Intent);
{$ELSE}
    SharedActivity.startActivity(Intent);
{$ENDIF}
end;

procedure CreateSMS(const Number, Msg: string);
var
  Intent: JIntent;
  URI: Jnet_Uri;
begin
  URI := StrToJURI(Format('smsto:%s', [Number]));
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, URI);
  Intent.putExtra(StringToJString('sms_body'), StringToJString(Msg));
  LaunchActivity(Intent);
end;

end.

The routine can be called like this:

CreateSMS('123456789', 'O HAI2U!');

If you did want to actually send the SMS the unit below does that job but also includes code that self-checks the relevant permission is set for the app:

unit AndroidStuff;

interface

function HasPermission(const Permission: string): Boolean;
procedure SendSMS(const Number, Msg: string);

implementation

uses
  System.SysUtils,
  System.UITypes,
{$IF RTLVersion >= 31}
  FMX.DialogService,
{$ELSE}
  FMX.Dialogs,
{$ENDIF}
  FMX.Helpers.Android,
  Androidapi.Helpers,
  Androidapi.JNI.App,
  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
{$IF RTLVersion >= 30}
  Result := TAndroidHelper.Context.checkCallingOrSelfPermission(
{$ELSE}
  Result := SharedActivityContext.checkCallingOrSelfPermission(
{$ENDIF}
    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
{$IF RTLVersion >= 31}
    TDialogService.MessageDialog('App does not have the SEND_SMS permission', TMsgDlgType.mtError, [TMsgDlgBtn.mbCancel], TMsgDlgBtn.mbCancel, 0, nil)
{$ELSE}
    MessageDlg('App does not have the SEND_SMS permission', TMsgDlgType.mtError, [TMsgDlgBtn.mbCancel], 0)
{$ENDIF}
  else
  begin
    SmsManager := TJSmsManager.JavaClass.getDefault;
    SmsManager.sendTextMessage(
      StringToJString(Number),
      nil,
      StringToJString(Msg),
      nil,
      nil);
  end;
end;

end.

Upvotes: 2

See the class SMSManager on Android API.

There is a sendTextMessage method that you can use:

Try some code like this:

uses
  Androidapi.Helpers,
  Androidapi.JNI.JavaTypes, 
  Androidapi.JNI.Telephony;

procedure TForm1.Button1Click(Sender: TObject);
var
  destAdress: JString;
  smsManager: JSmsManager;
begin
  smsManager := TJSmsManager.JavaClass.getDefault;
  destAdress := StringToJString('0034123456789');
  smsManager.sendTextMessage(destAdress, nil, StringToJString('The message content'), nil, nil);
end;

You must add permissions to the project configuration. See the "Send SMS":

Send SMS - Allows an application to send SMS messages.

Regards.

Upvotes: 3

Related Questions