On Delphi XE8 i have simple function to check internet connection:
function TForm1.Internet: boolean;
begin
result:=false;
try
IdTCPClient1.ReadTimeout:=2500;
IdTCPClient1.ConnectTimeout:=2500;
IdTCPClient1.Port:=80;
IdTCPClient1.Host:='google.pl';
IdTCPClient1.Connect;
IdTCPClient1.Disconnect;
result:=true;
except
result:=false;
end;
end;
Everything works just fine in older android version but in andoid 6 the app just crashes (close) when i call IdTCPClient1.Connect.
Then I learned that this is blocking function and it has to be in worker thread so i wrote something like this:
type
TTest = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
and in the implementation section:
procedure TThread.Execute;
begin
try
Form1.IdTCPClient1.ReadTimeout:=2500;
Form1.IdTCPClient1.ConnectTimeout:=2500;
Form1.IdTCPClient1.Port:=80;
Form1.IdTCPClient1.Host:='google.pl';
Form1.IdTCPClient1.Connect;
Form1.IdTCPClient1.Disconnect;
except
showmessage('no internet connection');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Test : TTest;
begin
Test := TTest.Create(False);
end;
but unfortunately the app is still closing on android 6 when i call TForm1.Button1Click (on windows and older android versions works just fine)
Please help me ;)
Related
I am dealing with the following issue with Firemonkey (Delphi 10.4): When the Android OS will shut down and my app is still running, it does not trigger the OnCloseQuery, OnClose, and nor the OnDestroy events. Is there a way to detect or intercept the OS shutdown event? The same issue is presented when I kill the app with the square button (that is when I show the recently opened apps with the square button and I close the app that way).
Thank you in advance.
I finally found a solution from a TMS customer (Ken Randall "Randall_Ken" Active Customer.)
uses FMX.Platform;
procedure TMyForm.FormCreate(Sender: TObject);
var
AppEventSvc: IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService
(IFMXApplicationEventService, IInterface(AppEventSvc)) then
begin
AppEventSvc.SetApplicationEventHandler(AppEvent);
end;
end;
function TMyForm.AppEvent(AAppEvent: TApplicationEvent;
AContext: TObject): Boolean;
begin
if AAppEvent = TApplicationEvent.WillTerminate then
begin
// Do soomething
end;
Result := true;
end;
Basic facts:
The application was created as a multiplatform default empty application.
Wordpress is on a NonSSL connection.
On windows the code (below) works flawlessly.
On Android the data is being received by the
server flawlessly, However the application is being shut down.
Debug shows the exception IdConnClosedGracefully
The "try except" does not intercept the exception.
XE8, indy 10
Questions:
Am I doing something wrong?
Why is the exception not being intercepted.
What can I do to prevent the shutdown?
the code:
procedure TForm8.Button1Click(Sender: TObject);
var
LPostURL : String;
LXMLStream : TMemoryStream;
LHttp: TIdHttp;
begin
TTask.Run(procedure
var
LPostURL : String;
LXMLStream : TMemoryStream;
LResStream : TMemoryStream;
LHttp: TIdHttp;
begin
LHttp := TIdHTTP.Create;
LHttp.HTTPOptions := LHttp.HTTPOptions - [hoForceEncodeParams];
LHttp.HandleRedirects:=true;
buildpost;
xml.Active:=true;
LPostURL := 'http://benkyo.tk/xmlrpc.php';//edit1.Text;
LXMLStream := TMemoryStream.Create;
XML.SaveToStream(LXMLStream);
try
try
memo1.lines.text:=LHttp.post(LPostURL, LXMLStream);
except
on E:exception do
memo1.Lines.Text:=('IdHTTP1.Post error'+ E.Message);
end;
finally
LHttp.Free;
LXMLStream.Free;
end;
end);
end;
I have an Android application and service in the same process. Write code under RAD Studio Delphi 10.1.
I need to get geographic coordinates in Android Service (that I'm doing well) and write them to the SQLite database.
And from time to time the application can (when the user needs) process the coordinates in the user interface.
When I put TConnection (any - ADO, FireDAC, UniDAC) into DataModule not even make an active connection, the service stops working, even not running the OnStartCommand event.
Monitor.bat shows no obvious errors.
Please tell me how to work with a SQLite database in Android Service and it Android Application at the same time.
I found a solution:
I updated UniDAC components for Berlin to latest version (6.3.12).
TUniConnection and TUniQuery well work with SQLite in Android Service.
Add to Project->Deployment of the host application my SQLite DB-file, Remote Path sets to ".\assets\internal\".
I hope this code will useful for you.
procedure TDM.conSQLiteBeforeConnect(Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
conSQLite.Database := TPath.Combine(TPath.GetDocumentsPath, 'mybase.sqlite');
{$ENDIF}
end;
procedure TDM.conSQLiteError(Sender: TObject; E: EDAError; var Fail: Boolean);
begin
Log('--- DB error: %s:', [E.Message]);
Fail := False;
end;
function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
Log('+ START with Intent: ' + JStringToString(Intent.getAction.toString), []);
if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then
begin
try
conSQLite.Disconnect;
Log('- DB disconnected', []);
except
on E: Exception do
Log('- can not to disconnect DB', [E.Message]);
end;
Log('... service to be stoped', []);
JavaService.stopSelf;
Result := TJService.JavaClass.START_NOT_STICKY; // don't reload service
end
else
begin
Log('... service started', []);
try
conSQLite.Connect;
Log('+ DB connected', []);
UniQuery.SQL.Text := 'select count(*) as ALLREC from orders';
UniQuery.Open;
if UniQuery.RecordCount > 0 then
begin
UniQuery.First;
Log('... record count: %s', [UniQuery.FieldByName('ALLREC').AsString]);
end;
UniQuery.Close;
except
on E: Exception do
Log('- can not to connect DB: %s', [E.Message]);
end;
Result := TJService.JavaClass.START_STICKY; // rerun service if it stops
end;
end;
I have struggled the same issue but I started to use TSQLConnection (dbexpress) component with TSQLQuery (dbexpress) component and these are components wrok well in Android service.
The same project runs perfect on Windows/iOS platform, but cause deadlock on Android (two different android devices) after running for uncertain duration.
procedure TTestThread.FSynProc;
begin
Inc(Form1.FExecuted); //Variable of TForm
Form1.Text1.Text:= IntToStr(Form1.FExecuted);
end;
procedure TTestThread.Execute;
var
begin
while not Self.Terminated do
begin
Self.Synchronize(FSynProc);
sleep(10);
end;
end;
constructor TTestThread.Create;
begin
inherited Create(True);
Self.FreeOnTerminate:= True;
end;
destructor TTestThread.Destroy;
begin
inherited;
end;
code for launch TTestThread
procedure TForm1.StartTTProc;
begin
ftt:= TTestThread.Create; // Variable of TForm
ftt.Start;
end;
After StartTTProc, the number shows in 'Text1' increase continusely.
After running for an uncertain duration on android device, App freezed.
any advice?
I have a thread downloading and saving a clientDataset file cds file from a remote Datasnap Server.
This thread works in Windows, IOS (Simulator, Iphone, Ipad) but not on Android.
The app crashes after completed the file download and save it on Android.
The code is simple.
Thread:
TDownloadSaveRemoteDBThread = class (TThread)
public
Username,Password,host,port : String;
error : String;
Folder : String;
ServerMethod : String;
filename : String;
protected
procedure Execute; override;
end;
procedure TDownloadSaveRemoteDBThread.Execute;
var
sqlCon : TSqlConnection;
cds : TClientDataset;
ssm : TSqlServerMethod;
dpr : TDataSetProvider;
begin
inherited;
error :='';
SqlCon:=TSQLConnection.Create(nil);
try
sqlCon.DriverName:='Datasnap';
sqlCon.LoginPrompt:=false;
sqlCon.Params.Values['hostname']:=host;
sqlCon.Params.Values['port']:=port;
sqlCon.Params.Values['UserName']:=Username;
sqlCon.Params.Values['Password']:=Password;
try
sqlCon.Open;
cds:=TClientDataset.Create(nil);
ssm:=TSqlServerMethod.Create(nil);
dpr:=TDataSetProvider.Create(nil);
try
ssm.SQLConnection:=SqlCon;
ssm.ServerMethodName:=ServerMethod;
dpr.DataSet:=ssm;
cds.SetProvider(dpr);
cds.Open;
cds.SaveToFile(folder+filename);
cds.Close;
finally
cds.free;
ssm.free;
dpr.free;
end;
Except
on E : Exception do
Begin
error:=E.Message;
SQLCon.Close;
End;
end;
finally
SQLCon.Close;
SQLCon.free;
end;
end;
I have a button to start the thread in my mainform “Start Form”
procedure TStartForm.Button1Click(Sender: TObject);
var
DownloadSaveRemoteDBThread : TDownloadSaveRemoteDBThread;
begin
DownloadSaveRemoteDBThread:= TDownloadSaveRemoteDBThread.Create(true);
DownloadSaveRemoteDBThread.OnTerminate:= StartForm.ferdigHentDB;
DownloadSaveRemoteDBThread.Password:='test';
DownloadSaveRemoteDBThread.Username:='test';
DownloadSaveRemoteDBThread.host:=edit1.text; //127.0.0.1
DownloadSaveRemoteDBThread.port:='211';
DownloadSaveRemoteDBThread.Folder:=System.IOUtils.TPath.GetDocumentsPath + PathDelim +'db'+ PathDelim;
DownloadSaveRemoteDBThread.ServerMethod:= 'TServerMethods2.hentselect3';
DownloadSaveRemoteDBThread.filename:='select3.cds';
DownloadSaveRemoteDBThread.FreeOnTerminate:=true;
DownloadSaveRemoteDBThread.Start;
end;
Then after thread is finished I have this simple procedure
procedure TStartForm.ferdigHentDB(sender: Tobject);
begin
with sender as TDownloadSaveRemoteDBThread do
Begin
if error > '' then
Begin
showmessage(error);
End;
End;
end;
Any suggestions why Android crashes, is there an easy fix for this issue?
TThread in XE5 has two major bugs on Android. Sychronize() and Queue() are broken (Synchronize() is used to trigger the OnTerminate event), and TThread does not detach itself from the Android JVM before termination if any JNI objects are used by the thread. The first bug has not been fixed yet. The second bug is fixed in XE6, but there is a workaround you can use in XE5.