如何读取 Delphi 中的 JPendingIntent?
How read JPendingIntent in Delphi?
如何阅读此代码中的 deliveryIntent
?
uses
Androidapi.JNI.JavaTypes, Androidapi.JNI.Telephony;
procedure TForm1.Button1Click(Sender: TObject);
var
smsTo: JString;
smsManager: JSmsManager;
begin
smsManager := TJSmsManager.JavaClass.getDefault;
smsTo := StringToJString(ENum.text);
PendIntent1:=TJPendingIntent.JavaClass.getBroadcast();
PendIntent2:=TJPendingIntent.JavaClass.getBroadcast();
smsManager.sendTextMessage(smsTo, nil, StringToJString(MSms.lines.text),PendIntent1,PendIntent2);
end;
因为我知道短信是不是没了?
谢谢
如果您阅读 SmsManager.sendTextMessage()
documentation,您应该提供自己的 Intent
对象(Delphi 中的 JIntent
),这些对象包含在 PendingIntent
中对象(Delphi 中的JPendingIntent
)。
因此,您将创建两个 Intent
对象,并为其分配了所需的操作字符串,然后使用 PendingIntent.getBroadcast()
方法将它们包裹在两个 PendingIntent
对象中(TJPendingIntent.JavaClass.getBroadcast()
in Delphi),然后将它们分别传递给 sentIntent
和 deliveryIntent
参数中的 sendTextMessage()
。
短信sent/failed后,将广播sentIntent
参数里面的Intent
。如果短信成功发送给收件人,将广播deliveryIntent
参数中的Intent
。
要处理这些 Intent
对象,您需要在您的应用中创建并注册一个 broadcastReceiver
。当您收到广播的 Intent
时,您可以检索它的 action
值(请参阅 Intent.getAction()
方法)并采取相应的行动。
不涉及 String
转换,除非您想在 Delphi String
和 Android JString
.[=36= 之间转换]
这是我在 Delphi 10.1 Berlin 上的做法:
- 基于 Java 代码示例,我采用了 here or here
- 这里是 Delphi 广播接收器的完整代码。使用此代码,您可以捕获意图和 ResultCode (getResultCode)。 Here 是一个如何实现它的简单示例。
单位
unit BroadcastReceiver;
interface
{$IFDEF ANDROID}
uses
Androidapi.JNI.Embarcadero, Androidapi.JNI.GraphicsContentViewText, Androidapi.helpers,
Androidapi.JNIBridge, FMX.Helpers.Android, Androidapi.JNI.JavaTypes,
System.Classes, System.SysUtils;
type
TBroadcastReceiver = class;
TListener = class(TJavaLocal, JFMXBroadcastReceiverListener)
private
fOwner: TBroadcastReceiver;
fReceiver: JFMXBroadcastReceiver;
public
constructor Create(aOwner: TBroadcastReceiver);
destructor Destroy; override;
procedure onReceive(context: JContext; intent: JIntent); cdecl;
end;
TOnReceive = procedure (aContext: JContext; aIntent: JIntent; aResultCode: integer) of object;
TBroadcastReceiver = class
private
fListener : TListener;
fRegistered: boolean;
fOnReceive: TOnReceive;
public
constructor Create(aOnReceiveProc: TOnReceive);
destructor Destroy; override;
procedure AddActions(const Args: array of JString);
procedure SendBroadcast(const aValue: string);
end;
{$ENDIF}
implementation
{$IFDEF ANDROID}
{ TBroadcastReceiver }
constructor TBroadcastReceiver.Create(aOnReceiveProc: TOnReceive);
begin
inherited Create;
fListener := TListener.Create(Self);
fOnReceive := aOnReceiveProc;
end;
destructor TBroadcastReceiver.Destroy;
begin
fListener.Free;
inherited;
end;
procedure TBroadcastReceiver.AddActions(const Args: array of JString);
var
vFilter: JIntentFilter;
i: Integer;
begin
if fRegistered then
TAndroidHelper.context.getApplicationContext.UnregisterReceiver(fListener.fReceiver);
vFilter := TJIntentFilter.JavaClass.init;
for i := 0 to High(Args) do
vFilter.addAction(Args[i]);
TAndroidHelper.context.getApplicationContext.registerReceiver(fListener.fReceiver, vFilter);
fRegistered := true;
end;
procedure TBroadcastReceiver.SendBroadcast(const aValue: string);
var
Inx: JIntent;
begin
Inx := TJIntent.Create;
Inx.setAction(StringToJString(aValue));
TAndroidHelper.Context.sendBroadcast(Inx);
end;
constructor TListener.Create(aOwner: TBroadcastReceiver);
begin
inherited Create;
fOwner := aOwner;
fReceiver := TJFMXBroadcastReceiver.JavaClass.init(Self);
end;
destructor TListener.Destroy;
begin
TAndroidHelper.context.getApplicationContext.unregisterReceiver(fReceiver);
inherited;
end;
// usually android call it from "UI thread" - it's not main Delphi thread
procedure TListener.onReceive(context: JContext; intent: JIntent);
begin
if Assigned(fOwner.fOnReceive) then
fOwner.fOnReceive(Context, Intent, fReceiver.getResultCode);
end;
{$ENDIF}
end.
然后
fBroadcast := TBroadcastReceiver.Create(OnReceiveBroadcast);
fBroadcast.AddActions([StringToJString(SENT_ACTION)]);
SENT_ACTION - 可以是任何字符串,例如'SENT' 或 123 - 这是过滤器的 ID。
那我发过去:
procedure TAndroidSMS.SendSMS(const aText, aPhone: string);
var
Intent: JIntent;
PendingIntent: JPendingIntent;
vSmsManager: JSmsManager;
begin
Result := seNotUpdated;
Intent := TJIntent.Create;
Intent.setAction(StringToJString(SENT_ACTION));
// Intent.putExtra( StringToJString(EXTRA_PHONE_PARAM), StringTojString(aPhone));
PendingIntent := TJPendingIntent.JavaClass.getBroadcast(TAndroidHelper.Context, 0, Intent, 0);
vSmsManager := TJSmsManager.JavaClass.getDefault;
vSmsManager.sendTextMessage( StringToJString(aPhone), nil, StringToJString(aText), PendingIntent, nil);
end;
并使用广播接收器接收:
{ usually android call it from "UI thread" - it's not main Delphi thread}
procedure TAndroidSMS.OnReceiveBroadcast(aContext: JContext; aIntent: JIntent; aResultCode: integer);
begin
// vAction := JStringToString(aIntent.getAction);
// vNum := JStringToString(aIntent.getStringExtra( StringToJString(EXTRA_PHONE_PARAM) ) );
// now change value, another thread is cheking periodically for this flag
{Intel, Arm, write to a single byte, or to a properly aligned 2- or 4-byte value will always be an atomic write.}
if aResultCode = TJActivity.JavaClass.RESULT_OK then
Result := seSent
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_RADIO_OFF then
Result := seRadioOff
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_GENERIC_FAILURE then
Result := seGenericFail
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_NO_SERVICE then
Result := seNoService
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_NULL_PDU then
Result := seNullPDU
else Result := seUnknown;
end;
如何阅读此代码中的 deliveryIntent
?
uses
Androidapi.JNI.JavaTypes, Androidapi.JNI.Telephony;
procedure TForm1.Button1Click(Sender: TObject);
var
smsTo: JString;
smsManager: JSmsManager;
begin
smsManager := TJSmsManager.JavaClass.getDefault;
smsTo := StringToJString(ENum.text);
PendIntent1:=TJPendingIntent.JavaClass.getBroadcast();
PendIntent2:=TJPendingIntent.JavaClass.getBroadcast();
smsManager.sendTextMessage(smsTo, nil, StringToJString(MSms.lines.text),PendIntent1,PendIntent2);
end;
因为我知道短信是不是没了?
谢谢
如果您阅读 SmsManager.sendTextMessage()
documentation,您应该提供自己的 Intent
对象(Delphi 中的 JIntent
),这些对象包含在 PendingIntent
中对象(Delphi 中的JPendingIntent
)。
因此,您将创建两个 Intent
对象,并为其分配了所需的操作字符串,然后使用 PendingIntent.getBroadcast()
方法将它们包裹在两个 PendingIntent
对象中(TJPendingIntent.JavaClass.getBroadcast()
in Delphi),然后将它们分别传递给 sentIntent
和 deliveryIntent
参数中的 sendTextMessage()
。
短信sent/failed后,将广播sentIntent
参数里面的Intent
。如果短信成功发送给收件人,将广播deliveryIntent
参数中的Intent
。
要处理这些 Intent
对象,您需要在您的应用中创建并注册一个 broadcastReceiver
。当您收到广播的 Intent
时,您可以检索它的 action
值(请参阅 Intent.getAction()
方法)并采取相应的行动。
不涉及 String
转换,除非您想在 Delphi String
和 Android JString
.[=36= 之间转换]
这是我在 Delphi 10.1 Berlin 上的做法:
- 基于 Java 代码示例,我采用了 here or here
- 这里是 Delphi 广播接收器的完整代码。使用此代码,您可以捕获意图和 ResultCode (getResultCode)。 Here 是一个如何实现它的简单示例。
单位
unit BroadcastReceiver;
interface
{$IFDEF ANDROID}
uses
Androidapi.JNI.Embarcadero, Androidapi.JNI.GraphicsContentViewText, Androidapi.helpers,
Androidapi.JNIBridge, FMX.Helpers.Android, Androidapi.JNI.JavaTypes,
System.Classes, System.SysUtils;
type
TBroadcastReceiver = class;
TListener = class(TJavaLocal, JFMXBroadcastReceiverListener)
private
fOwner: TBroadcastReceiver;
fReceiver: JFMXBroadcastReceiver;
public
constructor Create(aOwner: TBroadcastReceiver);
destructor Destroy; override;
procedure onReceive(context: JContext; intent: JIntent); cdecl;
end;
TOnReceive = procedure (aContext: JContext; aIntent: JIntent; aResultCode: integer) of object;
TBroadcastReceiver = class
private
fListener : TListener;
fRegistered: boolean;
fOnReceive: TOnReceive;
public
constructor Create(aOnReceiveProc: TOnReceive);
destructor Destroy; override;
procedure AddActions(const Args: array of JString);
procedure SendBroadcast(const aValue: string);
end;
{$ENDIF}
implementation
{$IFDEF ANDROID}
{ TBroadcastReceiver }
constructor TBroadcastReceiver.Create(aOnReceiveProc: TOnReceive);
begin
inherited Create;
fListener := TListener.Create(Self);
fOnReceive := aOnReceiveProc;
end;
destructor TBroadcastReceiver.Destroy;
begin
fListener.Free;
inherited;
end;
procedure TBroadcastReceiver.AddActions(const Args: array of JString);
var
vFilter: JIntentFilter;
i: Integer;
begin
if fRegistered then
TAndroidHelper.context.getApplicationContext.UnregisterReceiver(fListener.fReceiver);
vFilter := TJIntentFilter.JavaClass.init;
for i := 0 to High(Args) do
vFilter.addAction(Args[i]);
TAndroidHelper.context.getApplicationContext.registerReceiver(fListener.fReceiver, vFilter);
fRegistered := true;
end;
procedure TBroadcastReceiver.SendBroadcast(const aValue: string);
var
Inx: JIntent;
begin
Inx := TJIntent.Create;
Inx.setAction(StringToJString(aValue));
TAndroidHelper.Context.sendBroadcast(Inx);
end;
constructor TListener.Create(aOwner: TBroadcastReceiver);
begin
inherited Create;
fOwner := aOwner;
fReceiver := TJFMXBroadcastReceiver.JavaClass.init(Self);
end;
destructor TListener.Destroy;
begin
TAndroidHelper.context.getApplicationContext.unregisterReceiver(fReceiver);
inherited;
end;
// usually android call it from "UI thread" - it's not main Delphi thread
procedure TListener.onReceive(context: JContext; intent: JIntent);
begin
if Assigned(fOwner.fOnReceive) then
fOwner.fOnReceive(Context, Intent, fReceiver.getResultCode);
end;
{$ENDIF}
end.
然后
fBroadcast := TBroadcastReceiver.Create(OnReceiveBroadcast);
fBroadcast.AddActions([StringToJString(SENT_ACTION)]);
SENT_ACTION - 可以是任何字符串,例如'SENT' 或 123 - 这是过滤器的 ID。
那我发过去:
procedure TAndroidSMS.SendSMS(const aText, aPhone: string);
var
Intent: JIntent;
PendingIntent: JPendingIntent;
vSmsManager: JSmsManager;
begin
Result := seNotUpdated;
Intent := TJIntent.Create;
Intent.setAction(StringToJString(SENT_ACTION));
// Intent.putExtra( StringToJString(EXTRA_PHONE_PARAM), StringTojString(aPhone));
PendingIntent := TJPendingIntent.JavaClass.getBroadcast(TAndroidHelper.Context, 0, Intent, 0);
vSmsManager := TJSmsManager.JavaClass.getDefault;
vSmsManager.sendTextMessage( StringToJString(aPhone), nil, StringToJString(aText), PendingIntent, nil);
end;
并使用广播接收器接收:
{ usually android call it from "UI thread" - it's not main Delphi thread}
procedure TAndroidSMS.OnReceiveBroadcast(aContext: JContext; aIntent: JIntent; aResultCode: integer);
begin
// vAction := JStringToString(aIntent.getAction);
// vNum := JStringToString(aIntent.getStringExtra( StringToJString(EXTRA_PHONE_PARAM) ) );
// now change value, another thread is cheking periodically for this flag
{Intel, Arm, write to a single byte, or to a properly aligned 2- or 4-byte value will always be an atomic write.}
if aResultCode = TJActivity.JavaClass.RESULT_OK then
Result := seSent
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_RADIO_OFF then
Result := seRadioOff
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_GENERIC_FAILURE then
Result := seGenericFail
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_NO_SERVICE then
Result := seNoService
else if aResultCode = TJSmsManager.JavaClass.RESULT_ERROR_NULL_PDU then
Result := seNullPDU
else Result := seUnknown;
end;