I just made an app with Delphi XE6 that receives push notifications with kinvey based on this example
When the application is running and I send a push the PushEvent handler receives it well, but when the application is closed and I press the notification it only opens my app.
Can I know which notification was pressed and get parameters from it?
Thanks in advance.
Edit:
I get a little bit closer, in my FormCreate ask for Extras:
procedure TForm1.FormCreate(Sender: TObject);
var
LIntent: JIntent;
LExtras: JBundle;
LExtrasArray: TJavaObjectArray<AndroidApi.JNI.JavaTypes.JObject>;
begin
LIntent := SharedActivity.getIntent;
try
if LIntent <> nil then
begin
LExtras := LIntent.getExtras;
if LExtras <> nil then
begin
//Now try to get the data
LExtrasArray := LExtras.KeySet.toArray;
for I := 0 to LExtrasArray.Length - 1 do
Memo1.Lines.Add(JStringToString(LExtrasArray.Items[I].toString));
end;
end;
finally
LIntent := nil;
end;
end;
With this code I get "gcm" in my memo.
So, when the notification fires my app I get this Extra available.
Now the problem is how I get info about that extra?
I tried LExtras.getString(StringToJString('message')) but this writes '' instead of the push message
Sarina DuPont answer me in her Blog
PushEvents component has a property StartupNotification for this purpose
procedure TMainForm.FormShow(Sender: TObject);
begin
if Assigned(PushEvents.StartupNotification) then
//Do something here!
//for example
//Memo.Text := PushEvents.StartupNotification.Message;
end;
Related
A client of mine had the question of whether it is possible to send a push notification in the employee app if they have not entered their hours by a certain time.
Is it possible to create a service for Android and iOS apps that checks every hour if the hours of the day have been entered in the database, and if not then send a push notification?
I don't know where to start, and if it is possible. But if other apps can do it, it should be possible with this app as well.
As #SilverWarior Suggests I have created two pieces of code one makes the notifications when the app goes to the background then when the app goes to the foreground I clear Tnotificationcenter. I've used the appevent function to trigger the enterdbackground and willbecomeforground.
The Appevent code looks like this:
function TForm1.AppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
begin
case AAppEvent of
TApplicationEvent.EnteredBackground:
begin
Gethourregistration(FEmployeeNr,NOW);
if dm.MthourregistrationControl.RecordCount<1 then
begin
var Notification := NotificationCenter1.CreateNotification;
try
Notification.Name := 'message1';
Notification.AlertBody := 'You have not yet entered todays hours!';
Notification.FireDate :=Date+encodetime(19,0,0,0);
{ Send notification in Notification Center }
NotificationCenter1.ScheduleNotification(Notification);
Notification.Name := 'message2';
Notification.AlertBody := 'You have not yet entered todays hours!';
Notification.FireDate :=Date+encodetime(21,0,0,0);
{ Send notification in Notification Center }
NotificationCenter1.ScheduleNotification(Notification);
finally
Notification.Free;
end;
end;
end;
TApplicationEvent.WillBecomeForeground:
Notificationcenter1.CancelAll;
end;
end;
I use the OnCreate event for asking permission for sending notifications and trigger the AppEvent.
procedure TForm1.FormCreate(Sender: TObject);
var
AppEventSvc: IFMXApplicationEventService;
begin
if NotificationCenter1.AuthorizationStatus <> TAuthorizationStatus.Authorized then
begin
FPendingAction := Action;
NotificationCenter1.RequestPermission;
end;
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(AppEventSvc)) then
begin
AppEventSvc.SetApplicationEventHandler(AppEvent);
end;
end;
I have tested this code and for me, this works perfectly.
Im using Delphi 10.1 for developing android application and I have used the Delphi sample for implementing Android 26 API and when I have used notification, it does not display. And also I have tried with the Notification example. But it does not works. Please help me to implement the notification as I need to implement this from Android services.
procedure TForm1.ImmediateNotification;
var
LNotification: TNotification;
begin
LNotification.EnableSound := False;
LNotification.Title := 'Immediate Notification';
LNotification.Subtitle := 'Subtitles are cool';
LNotification.AlertBody := 'This is an immediate notification';
FNotifications.PresentNotification(LNotification);
end;
Seeing that you aren't responsive, I'm going on a whim here, I've put my notification code up for you, to implement it with Android Service, you should check out: This from the DocWiki
procedure TF_SS_MAIN.NotifyAndroid(text: string);
var
Notification: TNotification;
begin
{verify if the service is actually supported}
if NotificationCenter1.Supported then
begin
Notification := NotificationCenter1.CreateNotification;
Notification.Name := 'Notif Name';
Notification.AlertBody := text;
Notification.FireDate := Now;
{Send notification in Notification Center}
NotificationCenter1.ScheduleNotification(Notification);
end;
end;
I am building an application for Android using Delphi XE5 that makes use of the Zxing barcode application and it uses the clipboard to retrieve the result. All of the code (Most of it anyway) is from a tutorial that I have found on the web. When I followed the tutorial, it worked to a charm but when applying the SAME code within an application that I was already working on - it did not work. Whenever accessing the clipboard ( in the 'OnTimer' event), the application always hangs and stops working. No error, nothing. App freezes and I have to close it via the phone's task manager.
The application fails right after the following line
Log.Add('AndroidClipboardScanner:1'); Log.SaveToFile(INIFileLog);
I have changed the coding around so that the app assumed the Clipboard service was available in the Ontimer event and it proceeded but it then failed after the following line:
Log.Add('AndroidClipboardScanner:4'); Log.SaveToFile(INIFileLog);
I am not sure where to begin debugging because the same code works in the other application that I created following the initial guide I found. I can also confirm that the ClipService is being assigned properly, otherwise the intent wouldn't even begin. Any help or guidance would be much appreciated ! Below is my code...
This Declared in the 'Private' variables section of the form:
ClipService: IFMXClipboardService;
This within the 'OnTimer' event for Timer1:
procedure TMain_Form.Timer1Timer(Sender: TObject);
var
barCode : String;
begin
timer1.Enabled := false;
Log.Add('AndroidClipboardScanner:0.1'); Log.SaveToFile(INIFileLog);
Try
if assigned(ClipService) then begin
Log.Add('AndroidClipboardScanner:1'); Log.SaveToFile(INIFileLog);
if (ClipService.GetClipboard.ToString <> 'nil') then
begin
Log.Add('AndroidClipboardScanner:2'); Log.SaveToFile(INIFileLog);
timer1.Enabled := false;
Log.Add('AndroidClipboardScanner:3'); Log.SaveToFile(INIFileLog);
Elapsed := 0;
Log.Add('AndroidClipboardScanner:4'); Log.SaveToFile(INIFileLog);
editHold.PasteFromClipboard;
//EditHold.Text := ClipService.GetClipboard.ToString;
Log.Add('AndroidClipboardScanner:5'); Log.SaveToFile(INIFileLog);
end else
begin
Log.Add('AndroidClipboardScanner:6'); Log.SaveToFile(INIFileLog);
Timer1.Enabled := False;
Log.Add('AndroidClipboardScanner:7'); Log.SaveToFile(INIFileLog);
end;
Log.Add('AndroidClipboardScanner:8'); Log.SaveToFile(INIFileLog);
end else begin
ShowMessage('Unexpected error has occured');
end;
Except
ShowMessage('Unexpected error has occured..');
End;
end;
Within the ONCreate procedure of the form:
if not TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService,
IInterface(ClipService)) then begin
ShowMessage('Clipboard Failed:1');
ClipService := nil;
end;
Elapsed := 0;
This is for click event for the button that begins the intent:
procedure TMain_Form.Button_ShowScannerClick(Sender: TObject);
{$IFDEF ANDROID}
var
intent: JIntent; {$ENDIF}
begin
{$IFDEF ANDROID}
//ShowMessage('Scanner:1');
if assigned(ClipService) then begin
//ShowMessage('Scanner:2');
ClipService.SetClipboard('nil');
intent := tjintent.Create;
intent.setAction(stringtojstring('com.google.zxing.client.android.SCAN'));
intent.putExtra(tjintent.JavaClass.EXTRA_INTENT,
stringtojstring('"SCAN_MODE"'));
sharedactivity.startActivityForResult(intent,0);
Elapsed := 0;
timer1.Enabled := true;
//ShowMessage('Scanner:3');
end;
{$ENDIF}
You didn't set the SCAN_MODE parameters like:
intent.putExtra(tjintent.JavaClass.EXTRA_TEXT,
stringtojstring('"SCAN_MODE","ONE_D_MODE,QR_CODE_MODE,PRODUCT_MODE,DATA_MATRIX_MODE"'));
Also you can check timer interval parameter...
I tested the solution on few devices.
With low interval value I had black screen sometimes
I have managed to register a custom protocol handler in my XE5 Android app by modifying the Androidmanifest.template.xml file. My application pops up properly whenever a myapp://myurl URL is clicked on.
The problem is, I need to get the URL that was clicked on when the app is launched in order to bring up the correct part of the app. Can anyone help me figure out how to get this?
Based on this example, try something like this:
uses
...,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.Net,
FMX.Helpers.Android;
procedure TMainForm.FormCreate(Sender: TObject);
var
intent: JIntent;
uri: Jnet_Uri;
uriStr: String;
begin
intent := SharedActivity.getIntent;
if intent <> nil then
begin
if TJIntent.JavaClass.ACTION_VIEW.equals(intent.getAction) then
begin
uri := intent.getData;
uriStr := JStringToString(uri.toString);
// use uriStr as needed...
end;
end;
end;
Does anybody know how to get this to work?
The closest I got was the code below, but got no success.
At first, it gives you some hope when it tells you need the SEND_SMS permission. But after you setup this permission, nothing happens!
uses
Androidapi.JNI.JavaTypes;
procedure TForm1.Button1Click(Sender: TObject);
var
smsManager: JSmsManager;
smsTo, smsFrom: JString;
begin
smsManager:= TJSmsManager.JavaClass.getDefault;
smsTo:= StringToJString('552199999999'); //replace with the right destination number
smsFrom:= StringToJString('552499999999'); //replace with the right originator number
smsManager.sendTextMessage(smsTo, smsFrom, StringToJString(Edit1.Text), nil, nil);
end;
Try to pass empty value (nil) to the scAddress parameter of the sendTextMessage function call to use the current default SMS center:
uses
Androidapi.JNI.JavaTypes, Androidapi.JNI.Telephony;
procedure TForm1.Button1Click(Sender: TObject);
var
smsTo: JString;
smsManager: JSmsManager;
begin
smsManager := TJSmsManager.JavaClass.getDefault;
smsTo := StringToJString('091...');
smsManager.sendTextMessage(smsTo, nil, StringToJString('Test SMS'), nil, nil);
end;
The second parameter to sendTextMessage is not the "sender" number, rather it identifies the SMS provider service center.
You almost certainly did not want to specify anything here. Simply pass nil and the SMSManager will use the device default service center for delivering your message.
sRecipient := StringToJString(edRecipient.Text);
sMessage := StringToJString(edMessage.Text);
sendTextMessage(sRecipient, nil, sMessage, nil, nil);
See also:
http://delphi-android.blogspot.dk/2013/10/how-to-send-sms-with-delphi-on-android.html
for a copy & paste function.
I like to have such functions in a separate unit, instead of putting it into the Button's event handler.
You can also do it with JIntend object as below
procedure CreateSms(const Number, Msg: string);
var
Intent: JIntent;
Uri: Jnet_Uri;
begin
Uri := TJnet_Uri.JavaClass.parse(StringToJString(Format('smsto:%s', [Number])));
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, Uri);
Intent.putExtra(StringToJString('sms_body'), StringToJString(Msg));
SharedActivity.startActivity(Intent);
end;