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;
Related
Helo,
I typed the code as follows and this code works well.
By using an https connection I hope that the Packet Data received cannot be read by applications such as Wireshark or the Packet Capture application on Android.
how do you configure the client side?
this my code
procedure TForm1.Button1Click(Sender: TObject);
var
MyCompletionHandler: TCompletionHandler;
MyErrorCompletionHandler: TCompletionHandlerWithError;
begin
ShowLoadingIndicator(Self, True);
Memo1.Lines.Clear;
RESTClient1.BaseURL := 'https://reqres.in/';
RESTClient1.RaiseExceptionOn500 := False;
RESTClient1.SecureProtocols := [THTTPSecureProtocol.TLS12];
RESTRequest1.ClearBody;
RESTRequest1.Resource := 'api/users';
MyCompletionHandler := procedure
var i: Integer;
tJson: TJSONValue;
begin
Label1.Text := 'Complete!';
Memo1.Lines.Append('Header: ');
for I := 0 to RESTResponse1.Headers.Count-1 do
Memo1.Lines.Append(RESTResponse1.Headers.Strings[I]);
Memo1.Lines.Append('');
Memo1.Lines.Append('Body:');
tJson := TJSONObject.ParseJSONValue(RESTResponse1.Content);
try
memo1.Lines.Append(REST.Json.TJson.Format(tJson));
finally
FreeAndNil(tJson);
end;
HideLoadingIndicator(Self);
end;
MyErrorCompletionHandler := procedure(AObject: TObject)
begin
Label1.Text := 'Error!';
HideLoadingIndicator(Self);
end;
RESTRequest1.ExecuteAsync(MyCompletionHandler, True, True, MyErrorCompletionHandler);
end;
result packet capture using
app
and this simple apps made with firemonkey:
Simple Apps
Delphi 10.2.2 Firemonkey Android Question: How can I open a URL in Android's web browser from my application?
I tried to understand the concepts here: How can I open a URL in Android's web browser from my application? but the information didn't help me any. I am unable to wrap my brain around how they can get it to work compared to the code I currently have.
I've looked here too: http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FMX.Android_Intents_Sample
I've also looked here: https://developer.android.com/guide/components/intents-common.html?hl=en
I've tried this code:
function OpenURL(const URL: string; const DisplayError: Boolean = False): Boolean;
var
Intent: JIntent;
begin
// There may be an issue with the geo: prefix and URLEncode.
// will need to research
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW,
TJnet_Uri.JavaClass.parse(StringToJString(System.NetEncoding.TNetEncoding.URL.Encode(URL))));
try
TAndroidHelper.Activity.startActivity(Intent);
exit(true);
except
on e: Exception do
begin
if DisplayError then ShowMessage('Error: ' + e.Message);
exit(false);
end;
end;
end;
This is how I use that function:
OpenURL('https://www.patreon.com/phonelosers/overview/', true)
And it keeps giving me an error:
Error: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=https://www.patreon.com/phonelosers/overview/ }
I tried this code too:
function OpenURL(const URL: string; const DisplayError: Boolean = False): Boolean;
var
Intent: JIntent;
begin
// There may be an issue with the geo: prefix and URLEncode.
// will need to research
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW,
TJnet_Uri.JavaClass.parse(StringToJString(System.NetEncoding.TNetEncoding.URL.Encode(URL))));
if TAndroidHelper.Activity.getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
begin
try
TAndroidHelper.Activity.startActivity(Intent);
exit(true);
except
on e: Exception do
begin
if DisplayError then ShowMessage('Error: ' + e.Message);
exit(false);
end;
end;
end
else
begin
ShowMessage('Intent.resolveActivity <= 0');
end;
end;
which gives me "Intent.resolveActivity <= 0"
It doesn't matter which android phone I use. I have a Moto G Play, Samsung S8+, and a Moto Z2 Force which run Android versions 6.0.1, 7.0, 8.0. All the phones have chrome web browser installed and I can use it.
I look all over the web and the code below is what everyone is using to supposedly do what I need it to do. I looked at both Delphi and Android programming information.
Please help solve this Delphi 10.2.2 Firemonkey Android problem!
After using a different coding method:
procedure OpenURL(const URL: string);
var
LIntent: JIntent;
Data: Jnet_Uri;
begin
LIntent := TJIntent.Create;
Data := TJnet_Uri.JavaClass.parse(StringToJString(URL));
LIntent.setData(Data);
LIntent.setAction(StringToJString('android.intent.action.VIEW'));
TAndroidHelper.Activity.startActivity(LIntent);
end;
I figured out I forgot "System.NetEncoding.TNetEncoding.URL.Encode" and just removing that code from the source fixed the issue so that this code:
function OpenURL(const URL: string; const DisplayError: Boolean = False): Boolean;
var
Intent: JIntent;
begin
// There may be an issue with the geo: prefix and URLEncode.
// will need to research
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW,
TJnet_Uri.JavaClass.parse(StringToJString(URL)));
try
TAndroidHelper.Activity.startActivity(Intent);
exit(true);
except
on e: Exception do
begin
if DisplayError then ShowMessage('Error: ' + e.Message);
exit(false);
end;
end;
end;
now works!
Since this System.NetEncoding.TNetEncoding.URL.Encode has caused the issue, I'm wondering if I do need to encode my url special, what should I use?
use this code :
var
URL: string;
Intent: JIntent;
begin
URL := 'https://www.google.com';
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW,
TJnet_Uri.JavaClass.parse(StringToJString(URL)));
SharedActivity.startActivity(Intent);
end
I'm new in INDY library, so I use delphi XE8 and indy for TCP client/serverconnection; I built server application for Windows and client for Android, when client application send message"text" to server application it work but the client app don't receive anything:
IdTCPClient1.IOHandler.WriteLn('OK'+edit2.Text+inttostr(incr), IndyTextEncoding_OSDefault());
LLine := IdTCPClient1.IOHandler.ReadLn();
LLine variable is empty and the client don't receive anything from the server app.
I repeat that the client app is created for Android and the server for WIN32 when I tested the client/sever app for WIN32 it work fine but when I test client app for Android, the client app is connected and the server app receive the data but client app don't receive anything.
The Server side code is :
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
LLine: String;
begin
TIdNotify.NotifyMethod( ShowStartServerdMessage );
LLine := AContext.Connection.IOHandler.ReadLn(IndyTextEncoding_UTF8);
if ((char(LLine[1])='O') and (char(LLine[2])='K')) then
begin
tg.text:=sg.text;ta.text:=sa.text;
sg.text:=fg.text;sa.text:=fa.text;
fg.text:=(char(LLine[3]));fa.text:=(char(LLine[4]))+(char(LLine[5]))+(char(LLine[6]));
AContext.Connection.IOHandler.WriteLn('OK'+fa.text);
TIdNotify.NotifyMethod(StopStartServerdMessage);
sndPlaySound('C:\defi', SND_NODEFAULT Or SND_ASYNC );
end
else
if (char(LLine[1])='C') then
begin
AContext.Connection.IOHandler.WriteLn('OK'+fa.text);
TIdNotify.NotifyMethod(StopStartServerdMessage);
end;
end;
And the Client side :
procedure TForm1.Button2Click(Sender: TObject);
var
LLine2: String;
begin
if timer1.Enabled=false then
begin timer1.Enabled:=true;label4.text:=edit3.Text; end;
incr:=strtoint(label4.text);
incr:=incr+1;
IdTCPClient1.IOHandler.WriteLn('OK'+edit2.Text+inttostr(incr), IndyTextEncoding_UTF8);
LLine2 := IdTCPClient1.IOHandler.ReadLn();
if ((char(LLine2[1])='O') and (char(LLine2[2])='K')) then
begin
Memo1.Lines.Add('La commande est reçu par le serveur');
end;
end;
And in client side i have a timer on event of timer i have this code :
procedure TForm1.Timer1Timer(Sender: TObject);
var
s:string;
begin
IdTCPClient1.IOHandler.WriteLn('C', IndyTextEncoding_UTF8);
s := IdTCPClient1.IOHandler.ReadLn();
if ((char(s[1])='O') and (char(s[2])='K')) then
begin
label4.text:=char(s[3])+char(s[4])+char(s[5]);
end;
end;
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.
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;