Delphi XE5 Android Httpserver segmentation fault? - android

I'm having this incredibly crazy error!
I drop idhttpserver,webbrowser on a new mobile android app.
I want the server to provide content to the browser.
It works great on windows but fails on my android device.
I tested a tcpserver and tcpclient. I can get the client to connect, but when I start
writeln and readln I get segmentation fault.
Even if I run with debugging off the application still crashes... here is the code snippet.
procedure TForm37.Button1Click(Sender: TObject);
begin
IdHTTPServer1.Bindings.Add;
try
IdHTTPServer1.Active := true;
if IdHTTPServer1.Active then
Button1.Text := 'Server Started';
except on E: Exception do
Button1.Text := 'Server Failed';
end;
end;
procedure TForm37.Button2Click(Sender: TObject);
var
astring : string;
begin
try
astring := IdHTTP1.Get('http://10.0.1.78:6000/');
// or astring := IdHTTP1.Get('http://127.0.0.1:6000/');
ShowMessage(astring);
except on E: Exception do
Button2.Text := 'connection failed';
end;
end;
procedure TForm37.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
AResponseInfo.ContentText :=
'<html><head><title>My First Response</title></head>' +
'<body>Command: ' + ARequestInfo.Command +
'<br />Host: ' + ARequestInfo.Host +
'<br />URI: ' + ARequestInfo.URI +
'<br />UserAgent: ' + ARequestInfo.UserAgent +
'</body></html>';
end;

This answer is sure to be very unpopular.
I too am trying to develop an FM HD Android Datasnap application using XE5 and I am getting Segementation Fault (11) at every turn! It's completely unpredictable.
Compiling as a Win32 target produces no errors.
For example:
A button's event handler will execute and complete successfully the first time the button is clicked and then on a second click it will produce a segmentation fault for no apparent reason.
My application almost does nothing useful at this point, but it's taken me hours and hours of trial an error to get it to do what it does.
I personally don't think that Android development in Delphi XE5 is actually viable unless you happen to be someone who already develops Android apps using the other dev. environments and/or you've got nothing better to do all day than fight with it.

Related

Delphi XE8 Get Web Data RaiseError

Good Morning,I have a confused problem.I'm writing a multi-device application to get data from web server. I'm Using Rad Studio XE8.When the application running, it raise error like this
Debugger Exception Notification
Project SmartManager.apk raised exception class Segmentation fault (11).
1.I create a WSDL Importer,the WSDL file location is 'http://60.12.81.154/MobileQueryService/services/MobileQueryDaoImpl?wsdl'
2.Add a button and two edit component to the app .The button Onclick event is to finish user login,the code is:
**
procedure TFrmUserLogin.LoginByWebService;
var
ret: string;
JSONObject: TJSONObject;
begin
try
ret := GetMobileQueryDaoImplPortType.Sys_Return_UserInfo(eUserNo.Text, ePwd.Text);
if ret <> '' then
begin
JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(ret), 0) as TJSONObject;
...
end;
except
showmessage('login failure!')
end;
end;
**
when the APP Run to 'ret := GetMobileQueryDaoImplPortType.Sys_Return_UserInfo(eUserNo.Text, ePwd.Text);',it raise error "class Segmentation fault (11)".
3.The webserver is writen by Java ,running on Tomcat7,when the app raise error,I find the server is running Normal.I print the result,it is right.
4.this app is running normal on win32 or win64 platform,but when i switch to android,the error is raised.
5.I have tested 2 mobile phone.One is HuaWei P6, the Android version 4.2.The Other is HuaWei P9, the Android version is 6.0. The App is working OK on P6,but raised error On P9.
6.Yesterday,I tried another way to get data from wbeserver By using httpclient,
the code like this:
**
procedure TFrmUserLogin.LoginByHttp;
var HttpClient:TIDHttp;
ParamList:TStringList;
url:String;
retResponse:TStringStream;
i: Integer;
rt,ret: string;
begin
try
HttpClient:=TIdHTTP.Create(Application.Owner);
retResponse:=TStringStream.Create;
url:='http://60.12.81.154/MobileQueryService/servlet/UserLoginAction' ;
ParamList:=TStringList.Create;
ParamList.Add('userno='+eUserNo.Text);
ParamList.Add('password='+ePwd.Text);
HttpClient.Post(url,ParamList,retResponse);
...
end;
**
The error is same!!!
Then I replace 'HttpClient.Post(url,ParamList,retResponse);'
with
'HttpClient.Get(url+'?userno='+eUserNo.Text+'&password='+ePwd.Text,retResponse);'
It is working as expected.
I do not know why,can anyone help me ?
I debugged the problem and it stops at the following line of code in "System.pas" file :
dlclose(handle);
I found when the handle is 0,the error raised.And I checked the file in XE10,all the code using dlclose will check that weather the handle is 0,like this :
if handle<>0 then dlclose(handle);
Could it be said that it is a bug of XE8?

Delphi android application is raising issue in Lennova A5000 mobile

I'm using Delphi 10 Seattle trail version for developing mobile application. And I tried to create new android mobile application which contains only TEditBox. And then compiled by setting the option as "Release". Then, generated the .apk file and then provided the file to the user. And when the user tried to click the edit box, the application raises the error message that "The Appname is not responding".
The user is using the Lennova A5000 and the Os is Android 5.0.2.
And the same application is running in my Moto g2 (5.0.2) and Micromax Yureka.
Please provide me is there any solution.
Also, I have updated the app in google app store. Then, it is showing as incompatible application for this device (Lennova A5000).
And also I have updated all the android SDK packages. After that also, it is raising the same issue.
I think this may be problem to Embarcadreo Delphi or any missing packages? Dont know what to do.
Thanks in advance.
Atlast I got the solution from Embarcadreo website. Please follow the mentioned steps.
1.Copy FMX.Platform.Android.pas to the project folder from source/fmx folder
and add the copied files to the project.
Then, do the changes in the following procedures.
procedure TPlatformAndroid.RunOnUIThread(Proc: TThreadProcedure);
procedure TPlatformAndroid.RunOnUIThread(Proc: TThreadProcedure);
begin
//MainActivity.runOnUiThread(TSimpleProcedureRunner.Create(Proc));
CallInUIThread(
procedure()
begin
Proc;
end);
end;
procedure TPlatformAndroid.SynchronizeOnUIThread(Proc: TThreadProcedure);
procedure TPlatformAndroid.SynchronizeOnUIThread(Proc: TThreadProcedure);
var
Runner: TSimpleProcedureRunner;
begin
// CallInUIThread(
// procedure()
// begin
// Runner := TSimpleProcedureRunner.Create(Proc);
// MainActivity.runOnUiThread(Runner);
// Runner.Event.WaitFor;
// end);
CallInUIThreadAndWaitFinishing(
procedure()
begin
Proc;
end);
end;
procedure TPlatformAndroid.SetClipboard(Value: TValue);
procedure TPlatformAndroid.SetClipboard(Value: TValue);
var
Setter: TClipboardSetter;
begin
Setter := TClipboardSetter.Create(Value.ToString);
CallInUIThread(
procedure()
begin
SharedActivity.runOnUiThread(Setter);
end);
Setter.Done.WaitFor(INFINITE);
end;
function TPlatformAndroid.GetClipboard: TValue;
function TPlatformAndroid.GetClipboard: TValue;
var
Getter: TClipboardGetter;
begin
Getter := TClipboardGetter.Create;
CallInUIThread(
procedure()
begin
SharedActivity.runOnUiThread(Getter);
end);
Getter.Done.WaitFor(INFINITE);
Result := Getter.Value;
end;
Then, Rebuild the project. After doing this every thing is working fine.

Delphi Android XE7 Loading Bitmap Failed

I developed a application . Its working very nice at my phone but its not working when this application start to workin at the other phones
Its closed after the showing splash screen.
I taking this problem ,'EBitmapLoadinFailed' 'Loading Bitmap Failed' when i debug at the phone of the using with the other phones.
I have a bitmap in to listbox in my mainform.
I disabled bitmaps in listbox its woking
my form create code is,
procedure Tfrm_login.FormCreate(Sender: TObject);
var
strdb : String;
begin
try
strDB :=System.IOUtils.TPath.GetDocumentsPath + PathDelim + 'user.s3db';
with con do
begin
LoginPrompt := False;
Params.Clear;
Params.Values['Database'] := strDB;
Params.Values['DriverID'] := 'SQLite';
Params.Values['CharacterSet'] := 'utf8';
Connected := True;
end;
sqlexe('CREATE TABLE IF NOT EXISTS AYARLAMA('+
'ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,'+
'TIP NVARCHAR(50) NULL,'+
'DEGER NVARCHAR(255) NULL)');
except
//fdf
end;
end;
My Form Show Code,
procedure Tfrm_login.FormShow(Sender: TObject);
begin
try
with myq do
begin
sql.Clear;
sql.Add('SELECT * FROM AYARLAMA WHERE TIP='+''''+'MAIL'+'''');
Open;
if RecordCount>0 then
begin
first;
edit_ad.Text:=FieldByName('DEGER').AsString;
end;
end;
except
/// tyrt
end;
end;
I think installing Delphi's Android 5.0 update will help if the device is Android 5.0. I have solved my same problem that way.
The link is :
http://cc.embarcadero.com/item/30110

Delphi XE5 Anonymous ShowModal doesn't work as expected

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.

How can I get a phone's contact list in a Firemonkey mobile application?

How can I get a phone's contact list in a FireMonkey mobile application?
here you go .. It's not finished as it reads all numbers for one person and if there are two numbers you will have two times this person listed inside list .. but from here I think you can work and adjust it to your needs :))
function GetContact: TStringList;
var
cursorContacts, cursorContactsPhone: JCursor;
hasPhoneNumber: Integer;
id: Int64;
displayName, phoneNumber, contactID: string;
begin
Result := TStringList.Create;
cursorContacts := SharedActivity.getContentResolver.query(TJContactsContract_Contacts.JavaClass.CONTENT_URI, nil, nil, nil, nil);
if (cursorContacts.getCount > 0) then
begin
while (cursorContacts.moveToNext) do
begin
id := cursorContacts.getLong(cursorContacts.getColumnIndex(StringToJString('_ID')));
displayName := JStringToString(cursorContacts.getString(cursorContacts.getColumnIndex(StringToJString('DISPLAY_NAME'))));
hasPhoneNumber := cursorContacts.getInt(cursorContacts.getColumnIndex(StringToJString('HAS_PHONE_NUMBER')));
if (hasPhoneNumber > 0) then
begin
cursorContactsPhone := SharedActivity.getContentResolver.query(TJCommonDataKinds_Phone.JavaClass.CONTENT_URI, nil,StringToJString('CONTACT_ID = ' + IntToStr(id)),nil, nil);
while (cursorContactsPhone.moveToNext) do
begin
phoneNumber := JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString('DATA1'))));
contactID := JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString('CONTACT_ID'))));
Result.Add(displayName + ': ' + phoneNumber);
end;
cursorContactsPhone.close;
end;
end;
end;
cursorContacts.close;
end;
Best Regards,
Kruno
Here's my code (inspired and originally created by #mali kruno, I only changed it to my needs!) to search through all contacts based on TEdit OnChange event:
I use this function in my commonfunctions.pas unit:
function GetContact (Name: string; Number: string; const tip: integer) : TStringList;
var
cursorContactsPhone: JCursor;
Typo1, Typo2: string;
FindBy: JString;
ToFind: TJavaObjectArray<JString>;
CurRec: integer;
begin
Result:=TStringList.Create;
CurRec:=0;
ToFind:= TJavaObjectArray<JString>.Create(2);
if Name <> '' then
begin
ToFind.Items[0] := StringToJString('data1');
ToFind.Items[1] := StringToJString('display_name');
FindBy := StringToJString('display_name LIKE "%' + Name + '%"');
Typo1:='data1';
Typo2:='display_name';
end
else if Number <> '' then
begin
ToFind.Items[0] := StringToJString('display_name');
ToFind.Items[1] := StringToJString('data1');
FindBy := StringToJString('data1 LIKE "%' + Number + '%"');
Typo1:='display_name';
Typo2:='data1';
end;
cursorContactsPhone := SharedActivity.getContentResolver.query(TJCommonDataKinds_Phone.JavaClass.CONTENT_URI, ToFind, FindBy, nil, nil);
while (cursorContactsPhone.moveToNext) do
begin
Result.Add
(JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString(Typo2)))) + ' - ' +
JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString(Typo1)))));
CurRec:=CurRec+1;
end;
cursorContactsPhone.close;
end;
I call it from ContactSearch.Change event (it's TEdit component) like this:
procedure TMainF.ContactsSearch.Change(Sender: TObject);
var ResultNo: integer; SearchContacts: string; Results: TStringList;
begin // begin main procedure
if ContactsSearch.Text.Length > 1 then
begin //begin search and memo update
SearchContacts:=ContactsSearch.Text;
Results:=GetContact(SearchContacts, '', 0);
ResultNo:=0;
Memo1.Lines.Clear;
for ResultNo := 0 to Results.Count-1
do
begin
Memo1.Lines.Add(Results.Strings[ResultNo]);
end;
Results.Free;
end;
end;
Note, that the Result is a TStringList created in a function and freed in a procedure after Memo update.
Note also, that I only search if TEdit length is 2 or more, since otherwise entering just "a" in a tedit would show all contacts that have a letter "a" in their name, and therefore it would freeze a little every time you search, use backspace etc...
The workaround would be to load the phonebook in a TStringList on application start, and then search through the stringlist only, but that would make few other troubles:
a) phonebook update wouldn't be detected, or you'd have to implement "Update" button, which would make no sense to do the workaround at all..
b) app start would take longer
c) haven't tried that and not sure how much would it actually speed-up the search, since the Memo.Lines.Add takes more time than the query itself, so...
As for the duplicates, you can see that here are not handled, because currently I don't have a need to do so, but you can easily handle this using "sort" in a Memo, or, even better if you don't want to lose the entries that would otherwise appear as a duplicate, manage them inside a TStringList itself, so that you merge numbers in the same line, or create sub-stringlists for each name (of course, only if a name appears more than once, if you don't want to end up having twice as much stringlists as you'd actually need).
Hope this helps.
You do it in much the same way as a programmer would who uses the native programming APIs, given that Delphi does not provide a unified/wrapped solution to this problem.
You need to research how the Android SDK surfaces the contact list and how the iOS SDK surfaces its contact list, then make use of the native APIs to access it.
It will differ wildly between the 2 platforms, but it would be feaible to write some OS-independent interface to it once you've established the implementation on the 2 different OSs and seen what is on offer and what is accessible across the two implementations. This is what FMX does in other instances of similar features implemented on the two platforms.
If the required APIs haven't already been imported into Delphi's RTL, which is quite possible, then you'd also need to write the imports for those APIs you need in order to be able to call them in the first place.
Executive summary:
Roll up your sleeves
Get stuck in
Code it up yourself
Bask in the pleasure of having got some cool API stuff working

Categories

Resources