While trying to implement Notifications at my project, Delphi Seattle can't reference FMX.Notification properly.
This is what I get:
[DCC Fatal Error] UnitMain.pas(27): F2613 Unit 'FMX.Notification' not found.
And then it makes an automatically reference to System.Notification, however it crashes my Android app when trying to use a object from this class.
How can I correctly implement Notifications on Delphi Seattle?
Note: It must run on both iOS and Android.
According to Embarcadero's official Seattle changes:
The FMX.Notification unit has been replaced by System.Notification.
The TNotificationCenter component now supports Windows 8 and later Windows versions. This component has also undergone some minor changes:
It provides a Loaded property to check whether the notification center is ready to use or not.
The type of ApplicationIconBadgeNumber has changed from Word to Integer.
Its Supported method is no longer necessary and has been removed.
The TBaseNotificationCenter class has replaced the IFMXNotificationCenter interface. Classes that used to implement the IFMXNotificationCenter interface must become subclasses of TBaseNotificationCenter and implement the virtual abstract methods of their parent class.
Hereby how I figured out to display notifications now:
procedure TForm_Master.showNotification(Sender: TObject);
var
MyNotification: TNotification;
begin
MyNotification := NotificationCenter1.CreateNotification;
try
MyNotification.Name := 'NotificationName';
MyNotification.AlertBody :=
'Here goes your message';
MyNotification.FireDate := Now;
// Send notification to the notification center
NotificationCenter1.ScheduleNotification(MyNotification);
finally
MyNotification.Free;
end;
end;
Related
I've created simple Android Service on 10.2.3 and pinned it to my Android App same as it stands in docs. However, there where no libProxyAndroidService.so in {$BDS}/lib/android/release, I've copied it from debug dir. Next thorn made by Embarcadero to me was hanging of whole application while calling
TLocalServiceConnection.StartService('somename');
I have installed 10.3.1 with hope that this bug is eliminated in this release, but it did the same.
Running app in debug mode, I have putted some breakpoints in System.Android.ServiceApplication, when steping over and over by code, it crashed in System.InitUnits, line 23357:
try
while I < Count do
begin
P := Table^[I].Init;
Inc(I);
InitContext.InitCount := I;
if Assigned(P) and Assigned(Pointer(P^)) then
begin
{$IF defined(MSWINDOWS)}
TProc(P)();
{$ELSEIF (defined(POSIX) and defined(CPUX86)) and defined(ASSEMBLER)}
CallProc(P, InitContext.Module^.GOT);
{$ELSE}
TProc(P)(); << 23357 crashing
{$ENDIF}
end;
After execution of malfunctional P, UI thread hangs out, Service is never executed, but in background Android App is still executing code (new threads in message log)
Edit:
I've checked what is under P^
This is initalization part of unit FMX.Platform
https://quality.embarcadero.com/browse/RSP-17857
It's old bug, never fixed by Embarcadero
Just remove all things which use FMX.Types unit, remove this unit from evey uses.
Then set ClassGroup to TPersistent
Wasted hours :|
procedure TPlatformAndroid.BindAppGlueEvents;
var
AndroidAppGlue: TAndroidApplicationGlue;
begin
AndroidAppGlue := PANativeActivity(System.DelphiActivity)^.instance; // <------- Error occurs here
AndroidAppGlue.OnApplicationCommandEvent := HandleApplicationCommandEvent;
AndroidAppGlue.OnContentRectEvent := HandleContentRectChanged;
AndroidAppGlue.OnInputEvent := HandleAndroidInputEvent;
end;
Related issues: RSP-12199 and RSP-13381. FMX seems to have a lot of problems related to use of System.DelphiActivity in a service. And for good reason. DelphiActivity probably shouldn't exist in the first place! You are not supposed to hold on to references to the Activity object in the first place. And a Service doesn't even require an Activity to run! Apps and Services alike run as Contexts instead (the Activity and Service classes both derive from the Context class), so if you need to hold a reference to something, hold one to the Context that the code is running in (which FMX also does). What is FMX doing with DelphiActivity that is so important that it can't be done in other (safer) ways?
Conclusion: There is nil in System.DelphiActivity in Services so loading FMX units will create a crash in initUnits.
PDFed link with bug explanation: https://www.docdroid.net/TfUjBwg/bug.pdf
I have a simple TCP server application that I have copied from the internet.
unit TCPServer;
interface
uses
System.SysUtils, System.Variants, System.Classes,
FMX.Forms, FMX.Dialogs, IdBaseComponent, IdComponent, IdSocketHandle,
IdCustomTCPServer, IdTCPServer, IdContext;
type
TForm2 = class(TForm)
Tserver: TIdTCPServer;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure TserverExecute(AContext: TIdContext);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
Binding : TIdSocketHandle;
begin
Tserver.DefaultPort := 16000;
Tserver.Bindings.Clear;
Binding := Tserver.Bindings.Add;
Binding.IP := '0.0.0.0';
Binding.Port := 16000;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Tserver.Active := True;
end;
procedure TForm1.TserverExecute(AContext: TIdContext);
Var
C : String;
begin
C:= AContext.Connection.Socket.ReadLn();
if C = 'TESTSTRING' then
begin
AContext.Connection.Socket.Writeln('SENT');
end;
end;
end.
I am attempting to get it to compile on a Android device. I have created a new multidevice form Unit2 (Unit2.pas and Unit2.fmx )and pasted the above file inside Unit2.pas.
When I compile the project I get the error
E1026 File not found Unit2.dfm
I am brand new to delphi programming. I would like to know what is a dfm file. How is it different from a fmx file which seems to be the correct way to create a Form on my IDE.I am using Embarcadero® Delphi 10 Seattle
Based on what I see in your code, you are working with a VCL Forms Application, which is for Windows only. Yet you say you are targeting Android. There are multiple issues here, so I'll start from the top.
E1026 File not found Unit2.dfm
I do not see any reference to Unit2 in your code. There is nothing here which suggests that such a file even exists in the first place. Your unit above is TCPServer.pas and I don't see Unit2 in any uses clause. If I had to guess, this unit was originally named Unit2.pas but you modified the name at the very top of the unit to TCPServer without instructing the project of your name change.
I am attempting to get it to compile on a Android device.
You are going about the wrong way if this is your intention. Your above unit is for a VCL application, but VCL is for Windows only. It will not work on any mobile platform, period.
I would like to know what is a dfm file. How is it different from a fmx file
A DFM file is tied to a VCL application, which is how I know that's what your current project is targeting. An FMX file is tied to a Firemonkey application, which is what you will need to target multi-platform. You cannot mix the two together in the same application if you're targeting mobile platforms. Both DFM and FMX are the files which contain the form's design (as opposed to the code), and it differs between the two frameworks.
I am brand new to delphi programming.
I highly advise that you step back and go read up on Delphi first before you try to begin coding, especially if you're targeting a mobile platform.
On another note, your unit refers to FMX units in its uses clause, but look at the line which says {$R *.dfm}. This means it's looking for a DFM file instead. I don't know how you acquired this code, but it's a huge mix-up and is impossible to compile under either framework.
I am a newbie to Delphi XE5 and currently developing Android platform applications on my Windows desktop using Delphi XE5.
I have two forms(Form1 and Form2) and tried to show Form2 in modal way on Form1 according to the way showed in Marco's RAD Blog(http://blog.marcocantu.com/blog/xe5_anonymous_showmodal_android.html).
But result was not as expected.
procedure TForm1.Button1Click(Sender: TObject);
var
frm2: TForm2;
begin
frm2 := TForm2.Create(nil);
ShowMessage('before frm2.ShowModal...');
frm2.ShowModal (
procedure(ModalResult: TModalResult)
begin
if ModalResult = mrOK then
if frm2.ListBox1.ItemIndex >= 0 then
edit1.Text := frm2.ListBox1.Items [frm2.ListBox1.ItemIndex];
frm2.DisposeOf;
end
);
ShowMessage('after frm2.ShowModal...');
end;
I wrote above code and run the application on an Android device.
I clicked the Button1, then I got the messagebox "before frm2.ShowModal... ", next "after frm2.ShowModal...", and then Form2 was showed.
I expect that the order should be 1)"before frm2.ShowModal... " message, 2) Form2 being showed, and 3) "after frm2.ShowModal..." message.
What's wrong with me?
The call to the anonymous ShowModal is not blocking, which means that any code after the ShowModal will be executed first.
One note here. Calling frm2.DisposeOf is wrong.
You must use this pattern:
declare
procedure TFrm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
See http://www.malcolmgroves.com/blog/?p=1585.
The documentation has been corrected in XE7, Using FireMonkey Modal Dialog Boxes, but this pattern can be used in all Delphi versions.
Conclusion: if you want to execute code after the modal dialog is closed, put that code inside the anonymous method.
I am developing inapp-Purchase in Delphi XE6.
Based on embarcadero documentation I create an InAppPurchase component as below:
FInAppPurchase := TInAppPurchase.Create(self);
{$IFDEF Android}
FInAppPurchase.ProductIDs.Add(License5And);
FInAppPurchase.ProductIDs.Add(License10And);
FInAppPurchase.ProductIDs.Add(License20And);
FInAppPurchase.ProductIDs.Add(License50And);
{$ENDIF}
{$IFDEF IOS}
FInAppPurchase.ProductIDs.Add(License5);
FInAppPurchase.ProductIDs.Add(License10);
FInAppPurchase.ProductIDs.Add(License20);
FInAppPurchase.ProductIDs.Add(License50);
{$ENDIF}
FInAppPurchase.OnSetupComplete := InAppPurchase1OnSetupComplete;
FInAppPurchase.OnConsumeCompleted := InAppPurchase1ConsumeCompleted;
FInAppPurchase.OnError := InAppPurchase1Error;
FInAppPurchase.OnProductsRequestResponse := InAppPurchase1ProductsRequestResponse;
FInAppPurchase.OnPurchaseCompleted := InAppPurchase1PurchaseCompleted;
FInAppPurchase.OnRecordTransaction := InAppPurchase1RecordTransaction;
FInAppPurchase.OnVerifyPayload := InAppPurchase1VerifyPayload;
{$IFDEF Android}
FInAppPurchase.ApplicationLicenseKey := myLicenseKeyFromGoogleDeveloperConsole;
{$ENDIF}
Then in InAppPurchase1OnSetupComplete I Called the FInAppPurchase.QueryProducts then it goes into InAppPurchase1ProductsRequestResponse and products and InavlidProductIDs both are empty. I don't know what I missed. Any help will be appreciated.
I check my products in google developer console all of them are 'Active' and as Type of 'Managed'.
p.s. Code is working perfect on ios Device.
I lost a lot of time to understand the problem.
After I studied the source code I have understand that in Android the Events are asynchronous, you must wait the "QueryProducts" result.
In order to fix this problem I created a TTimer that wait 5 second before it read "InAppPurchase.IsProductPurchased"
(I'm sorry for bad English)
It seems the app should be published for alpha or beta testing.
Instead of uploading for production I need to upload it for alpha first then publish it. after that the products are shown.
I developed the interface with the market starting from the example CapitalITrivia in Enbarcadero. I had the same problem and I read the answer that was given here.
I tried it and actually works. But this solution did not satisfy me because it depends on a delay not justified.
I realized that in InAppPurchaseSetupComplete was called the QueryProducts function and then I performed IsProductPurchased.
If I move the IsProductPurchased test in InAppPurchaseProductsRequestResponse function I get the expected result without introducing the delay.
did someone already find the correct way to program an alarm clock using DEPHI XE 5 and Android OS?
I found this code , but it does not work/compile at all:
procedure TNotificationsForm.btnSendScheduledNotificationClick(Sender: TObject);
var
Notification: TNotification;
begin
{ verify if the service is actually supported }
if NotificationC.Supported then // compile error here
begin.Supported
Notification := NotificationC.CreateNotification; // compile error here
try
Notification.Name := 'MyNotification';
Notification.AlertBody := 'Delphi for Mobile is here!';
{ Fired in 10 second }
Notification.FireDate := Now + EncodeTime(0,0,10,0);
{ Send notification in Notification Center }
NotificationC.ScheduleNotification(Notification);
finally
Notification.DisposeOf;
end;
end
end;
The first error is that NotificationC.Supported this property does not exist
You should mention that the code is based on one of the sample applications distributed with XE5. They can be found in the Start Menu entry for XE5 under Samples, or in the default C:\Users\Public\Documents\RAD Studio\12.0\Samples\MobileCodeSnippets\Notifications folder (Windows 7).
It appears you've forgotten to drop the TNotificationCenter component (available on the Component Palette's Services page) on the form and name it NotificationC as the demos do. Once you've done that, your code compiles just fine.
When you mention that you get a "compile error" in a question here, it's important to include the error message. We can't see your screen from where we are. :-) You have that exact information right in front of you, so there's no excuse for not including it. The Messages window will even copy the exact message to the clipboard for you to paste here, if you right-click the error line.