Advertisement
BankUpload Join!

Thursday, October 8, 2015

How to Develop Android Database Applications in RAD Studio XE7

Not so long ago, in RAD Studio XE5 there was introduced support for Android application development. On the Internet there can be found a lot of information about Android application development in Delphi XE5, but when it comes to development of database applications, it becomes much more difficult. The point is that the components and drivers included in the RAD Studio XE5 distribution (for example, FireDAC and dbExpress drivers) have severe limitations: on Android and iOS platforms, they support just 2 databases — SQLite and InterBase. And what to do when you develop a serious business-application, that requires remote connection to Oracle, MySQL or PostgreSQL from Android? We have come across such questions on various forums dedicated to database application development for Android and decided to reveal the topic as detailed as possible.

Components

Let’s start with description of the components we will use:
  • UniDAC – it is universal data access components that allow to connect to SQLite, Oracle, MySQL, PostgreSQL, and InterBase from Android (you can use UniDAC for connection from Windows to almost all the known databases, but this is beyond the scope of this blog).
If you want to work not with all those databases, but with a particular one, you can use more specific components:
  • LiteDAC – SQLite Data Access Components
  • ODAC – Oracle Data Access Components
  • MyDAC – MySQL Data Access Components
  • PgDAC – PostgreSQL Data Access Components
  • IBDAC – InterBase Data Access Components
All these components also support Android as a target platform in RAD Studio XE5.

Connection to database

Work with databases on Android in general is no different from the one on Windows, but there are some nuances when setting connection and deploying files to a mobile device, if you work with a local DB. We will consider here how to establish connection to each supported database.

SQLite

If you not deploy the database file to a mobile device, you should set:
ForceCreateDatabase := True
In this case, on the first application launch, a database file will be created automatically.

LiteDAC sample

var
  Connection: TLiteConnection;
begin
  Connection := TLiteConnection.Create(nil);
  try
    Connection.Options.ForceCreateDatabase := True;
    Connection.Database := IncludeTrailingPathDelimiter(TPath.GetDocumentsPath) + 'db.sqlite3';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

UniDAC sample

var
  Connection:  TUniConnection;
begin
  Connection := TUniConnection.Create(nil);
  try
    Connection.ProviderName := 'SQLite';
    Connection.SpecificOptions.Values['ForceCreateDatabase'] := 'True';
    Connection.Database := IncludeTrailingPathDelimiter(TPath.GetDocumentsPath) + 'db.sqlite3';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

Oracle

It is impossible to install Oracle client to a mobile device, because Oracle client for Android simply doesn’t exist. Therefore the only way to establish connection to Oracle from a mobile device is to connect directly via TCP/IP. For this, the Direct option should be set to True:
Direct := True;
In addition, the server name must be generated correctly, since, if we have no client, we have no tnsnames.ora file with the server list as well. Therefore, to establish connection from Android, we need to know the server Host and Port, as well as its SID or Service Name.
To connect via the SID, the server should be set in the following way:
Server := 'Host:Port:sid=SID';
or a simplified way:
Server := 'Host:Port:SID';
To connect via the Service Name – as follows:
Server := 'Host:Port:sn=SID';
In other words, the ‘sid=’ prefix of the third parameter indicates that connection is established via the SID, and the ‘sn=’ prefix indicates that connection is established via the Service Name. If no prefix is specified, then, by default, it is considered, that we want to establish connection via the SID.
The majority of Oracle servers have the same SID and Service Name, so you, most likely, won’t have to go into such nuances, since you can learn more about this in the Oracle documentation.

ODAC sample

var
  Session:  TOraSession;
begin
  Session := TOraSession.Create(nil);
  try
    Session.Options.Direct := True;
    Session.Server := 'server:1521:orcl';
    Session.Username := 'user_name';
    Session.Password := 'password';
    Session.Connect;
  finally
    Session.Free;
  end;
end;

UniDAC sample

var
  Connection:  TUniConnection;
begin
  Connection := TUniConnection.Create(nil);
  try
    Connection.ProviderName := 'Oracle';
    Connection.SpecificOptions.Values['Direct'] := 'True';
    Connection.Server := 'server:1521:orcl';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;

MySQL

MySQL client software for Android also doesn’t exist, therefore connection to MySQL server will also be established directly via TCP/IP. For this, let’s set the corresponding option:
Direct := True;

MyDAC sample

var
  Connection:  TMyConnection;
begin
  Connection := TMyConnection.Create(nil);
  try
    Connection.Options.Direct := True;
    Connection.Server := 'server';
    Connection.Port := 3306;
    Connection.Database := 'database_name';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

UniDAC sample

var
  Connection:  TUniConnection;
begin
  Connection := TUniConnection.Create(nil);
  try
    Connection.ProviderName := 'MySQL';
    Connection.SpecificOptions.Values['Direct'] := 'True';
    Connection.Server := 'server';
    Connection.Port := 3306;
    Connection.Database := 'database_name';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

PostgreSQL

With PostgreSQL, everything is more simple. Since PgDAC and UniDAC only allow establish direct connection via TCP/IP, it is enough for us to specify the Server and Port and perform Connect.

PgDAC sample

var
  Connection:  TPgConnection;
begin
  Connection := TPgConnection.Create(nil);
  try
    Connection.Server := 'server';
    Connection.Port := 5432;
    Connection.Database := 'database_name';
    Connection.Schema := 'schema_name';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

UniDAC sample

var
  Connection:  TUniConnection;
begin
  Connection := TUniConnection.Create(nil);
  try
    Connection.ProviderName := 'PostgreSQL';
    Connection.Server := 'server';
    Connection.Port := 5432;
    Connection.Database := 'database_name';
    Connection.SpecificOptions.Values['Schema'] := 'schema_name';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

InterBase

Using InterBase ToGo, you can connect to both local or remote DB.
To connect to a local db, just the path to the local db on the device should be set:
Database := IncludeTrailingPathDelimiter(TPath.GetDocumentsPath) + 'db.gdb';
If you need to establish connection to a remote server, you should specify not only the database, but the server as well:
UniConnection.Server := 'server';
UniConnection.Database := 'C:\db.gdb';
Please note that the IncludeTrailingPathDelimiter(TPath.GetDocumentsPath) prefix should be specified when connecting to a local DB, and it is not needed for connection to a remote database.

IBDAC local database sample

var
  Connection:  TIBCConnection;
begin
  Connection := TIBCConnection.Create(nil);
  try
    Connection.Database := IncludeTrailingPathDelimiter(TPath.GetDocumentsPath) + 'db.gdb';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

IBDAC remote database sample

var
  Connection:  TIBCConnection;
begin
  Connection := TIBCConnection.Create(nil);
  try
    Connection.Server := 'server';
    Connection.Database := 'C:\db.gdb';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

UniDAC local database sample

var
  Connection:  TUniConnection;
begin
  Connection := TUniConnection.Create(nil);
  try
    Connection.ProviderName := 'InterBase';
    Connection.Database := IncludeTrailingPathDelimiter(TPath.GetDocumentsPath) + 'db.gdb';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

UniDAC remote database sample

var
  Connection:  TUniConnection;
begin
  Connection := TUniConnection.Create(nil);
  try
    Connection.ProviderName := 'InterBase';
    Connection.Server := 'server';
    Connection.Database := 'C:\db.gdb';
    Connection.Username := 'user_name';
    Connection.Password := 'password';
    Connection.Connect;
  finally
    Connection.Free;
  end;
end;

Deployment to mobile device

In order for our application to be able to work with local SQLite and InterBase ToGo databases, we should make sure these databases are deployed to an Android device. Nothing difficult at this, since the deployment process is similar in both Delphi XE4 and Delphi XE5. First we should call the Project->Deployment menu:
After this add our databases for SQLite and InterBase to the list of files, that must be deployed to an Android device together with your application:
Please note that the deployment path is different for Android and iOS. If you want to deploy your application to both platforms, then make sure the deployment paths are specified correctly for both of them.
NOTE: Dont forget to change the Remote Path default value . with one of the described above.
Deployment PathDestination on Device
TPath.GetDocumentsPath.\assets\internal/data/data/com.embarcadero.MyProjects/files
TPath.GetSharedDocumentsPath.\assets/mnt/sdcard/Android/data/com.embarcadero.MyProjects/files

Download file to Android app using Delphi

This is a very simple one, because it works the same way as it did with Delphi for Windows:

function HttpGet(const url: string): string;
var
  HTTP: TIdHTTP;
begin
  HTTP := TIdHTTP.Create(nil);
  try
    Result:=http.Get(url);
  finally
    FreeAndNil (http);
  end;
end;

Tuesday, February 17, 2015

INTEGRATING APPLICATION DELPHI XE7TWITTER WITH TWITTER

delphi twiter


INTEGRATING APPLICATION DELPHI XE7 ANDROID WITH TWITTER


Both desktop and mobile, in development on several occasions the need to have our application interact with other applications of the target platform in our development.


Straight to the point

Let's cut to Delphi and start a Multi-Device application (File-> New-> Other-> Multi-Device Projects-> Blank Application).

INTEGRATING APPLICATION DELPHI XE7 ANDROID WITH WHATSAPP

There is no doubt that the instant messaging application Whatsapp snapped up big for communication via mobile devices, in this post we will see how punch it direct from a Delphi XE7 application. As a reference we will use the FAQ Whatsapp , there is no explanation of how to do through the Android in Java, our work here is only in the "conversion" to Delphi. Let the project, go to the Delphi XE7.



How to get SMS messages from the Android inbox using Delphi XE7

for fetch sms messages from the Android inbox please check this code: uses SysUtils, FMX.Helpers.Android, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Net, Androidapi.JNI.JavaTypes, Androidapi.JNI.Telephony; function FetchSms:string; var cursor: JCursor; uri: Jnet_Uri; address,person,msgdatesent,protocol,msgread,msgstatus,msgtype, msgreplypathpresent,subject,body, servicecenter,locked:string; msgunixtimestampms:int64; addressidx,personidx,msgdateidx,msgdatesentidx,protocolidx,msgreadidx, msgstatusidx,msgtypeidx,msgreplypathpresentidx,subjectidx,bodyidx, servicecenteridx,lockedidx:integer; begin uri:=StrToJURI('content://sms/inbox'); cursor := SharedActivity.getContentResolver.query(uri, nil, nil,nil,nil); addressidx:=cursor.getColumnIndex(StringToJstring('address')); personidx:=cursor.getColumnIndex(StringToJstring('person')); msgdateidx:=cursor.getColumnIndex(StringToJstring('date')); msgdatesentidx:=cursor.getColumnIndex(StringToJstring('date_sent')); protocolidx:=cursor.getColumnIndex(StringToJstring('protocol')); msgreadidx:=cursor.getColumnIndex(StringToJstring('read')); msgstatusidx:=cursor.getColumnIndex(StringToJstring('status')); msgtypeidx:=cursor.getColumnIndex(StringToJstring('type')); msgreplypathpresentidx:=cursor.getColumnIndex(StringToJstring('reply_path_present')); subjectidx:=cursor.getColumnIndex(StringToJstring('subject')); bodyidx:=cursor.getColumnIndex(StringToJstring('body')); servicecenteridx:=cursor.getColumnIndex(StringToJstring('service_center')); lockedidx:=cursor.getColumnIndex(StringToJstring('locked')); while (cursor.moveToNext) do begin address:=JStringToString(cursor.getString(addressidx)); person:=JStringToString(cursor.getString(personidx)); msgunixtimestampms:=cursor.getLong(msgdateidx); msgdatesent:=JStringToString(cursor.getString(msgdatesentidx)); protocol:=JStringToString(cursor.getString(protocolidx)); msgread:=JStringToString(cursor.getString(msgreadidx)); msgstatus:=JStringToString(cursor.getString(msgstatusidx)); msgtype:=JStringToString(cursor.getString(msgtypeidx)); msgreplypathpresent:=JStringToString(cursor.getString(msgreplypathpresentidx)); subject:=JStringToString(cursor.getString(subjectidx)); body:=JStringToString(cursor.getString(bodyidx)); servicecenter:=JStringToString(cursor.getString(servicecenteridx)); locked:=JStringToString(cursor.getString(lockedidx)); Result:=IntToStr(trunc(msgunixtimestampms/1000))+' '+address+' '+body; end; end;

Saturday, February 7, 2015

Google Material Design and FireMonkey?

Google Material Design and FireMonkey?

Google Material Design

A few weeks ago Google has officially released the specifications of the Material Design , the new guidelines for the GUI of Android applications.
It is a very extensive documentation that covers many aspects of mobile application GUI and definitely will take some time before all these proposals are absorbed by developers around the world.
Some applications very popular but have already released updates including elements of the Material Design and of course there is no better source of inspiration of the same Google applications (Chrome, Google+, Play Store, Play Music, ...).

Workaround for error EBitmapLoadingFailed on Android Lollipop

Workaround for error EBitmapLoadingFailed on Android Lollipop

Introduction

There is a bug in Delphi XE7 why Android will not boot on Lollipop (Android 5.0). In particular, they go to crash immediately after displaying the splash, because EBitmapLoadingFailed exception that is raised during the loading of the images contained in the file .fmx. 
The same application (same APK) run smoothly on Android versions prior to 5.

There are a couple of threads about it, on social-network:

Describes a workaround (which I have applied to the beta version of ColorMapp this morning) that is to load the graphic resources (TBitmap) at runtime rather than leave them embedded in the application resources (thus preventing a loaded through a call to TBitmap. LoadFromStream, which seems to be the critical point of failure).

Steps to apply the workaround:

1) Save to disk all the bitmap of each form

(Handy if you have already uploaded the pictures at design time, less useful if you are writing an application from scratch)

To simplify the process, I wrote a piece of code that iterates on the components of a form and saves all of the bitmap that is TImage.
You can look at the function of SaveAllImagesToDisk ImageDumpUnit.pas unit , found in my GitHub repository:


For example, in the event OnCreate of form I added:

{$ IFDEF mswindows}
SaveAllImagesToDisk (Self);
{$ ELSE}
LoadAllImagesFromDisk (Self);
{$ ENDIF}

Running the application on Win32 platform, you will generate a folder with subfolders images_dump (one for each form) with images saved in PNG files.
The $ ELSE branch of the compiler directive is executed for example on Android, so the Win32 application dumps and the Android application tries to dynamically load images from the storage device.

2) Remove all bitmap resources (.fmx)

The easiest (but requires to act manually on each component of your form with a bitmap) is to:
  • empty all entries of MultiResBitmap (eliminating all versions of the bitmap);
  • empty the TBitmap (eg. the properties StartValue / StopValue of TBitmapAnimation), opening the component editor and pressing the Clear key;
If you have many TBitmap and empty them manually seems impossible, you may act directly on the DFM, looking all occurrences of Bitmap. 

3) Load at run-time images corresponding

Again you can take advantage of the function LoadAllImagesFromDisk ImageDumpUnit.pas unit , taking care to call it for example in the event OnCreate of your form.

4) Add to deploy all PNG files generated in step 1

Through the deployment manager of Delphi, add the PNG file so that they are distributed with your application. Take care to indicate how RemotePath, the value 'assets / internal / images_dump /' followed by the name of the corresponding form.


5) subsidiaries have no other TBitmap

For example, I realized that the problem also with TBitmap (not just TMultiResBitmap) present in many components (eg. The TBitmapAnimation). To these I solved manually (mimicking the behavior of LoadAllImagesFromDisk) but it may make sense to automate the dump and load dynamic even those.

Conclusion

It 's all, following these steps I have solved the crash of my application XE7 ColorMapp on Android 5.0 Lollipop and currently I have a beta running on my Nexus 5.
Account to promote the beta in production just made tests on some other device.


Barcode Scanner on Android and iOS - Read and produce Barcode with Delphi XE7

In a previous blog post , we saw how it is possible to control third-party applications via Intent(Barcode Scanner) to easily implement the functionality of reading (and production) of a bar code from your Delphi application (XE5) for Android. 
I decided, after some requests received via email, to publish this update that takes advantage of the support (introduced in version XE6 and illustrated by Brian Long in his blog post ) to handle the event onActivityResult . 
Motivations

In the old version of this example (for XE5), in fact, sfruttavo the system clipboard and event management application to understand when, once started Barcode Scanner in read mode, the user had actually concluded scanning a barcode. 
Thanks to the fact that Barcode Scanner scanned copy the code to the clipboard, so I could get in my application Delphi string with the text corresponding to the bar code. 

Read and produce Barcode with Delphi XE5 (Android)

There are several online articles about how to integrate the reading of barcodes in mobile applications Delphi (find the link also later in this post).

We will now see an approach that allows you to add the scanning capabilities and production of barcodes (and / or QR code) in a Delphi app (Android), without the need to install third-party components or fill in your app libraries of third parties.

Everything is based on the interaction, mediated by the operating system, with an existing application (widespread, free and available on Google Play Store) which is called Barcode Scanner (license details here ).

Develop Android applications with Delphi

You can create apps for Android devices including phones, tablets, and now Google Glass with Delphi. Develop Android apps quickly in the RAD Studio visual designer and code editor to deliver high performance, natively compiled apps for the best user experience. You can then simply select the iOS target to deliver a compiled native iOS app from the exact same codebase. You can also target Windows and Mac OS X with the exact same codebase.
for See more than 20 Android code snippets and demo videos for Delphi and RAD Studio see this page
http://www.embarcadero.com/de/products/delphi/android-app-development

delphi android play mp3 audio from http internet source

in delphi xe7 sample you can find  Native Music Player Demo in android and ios
http://www.fmxexpress.com/native-music-player-demo-in-delphi-xe6-firemonkey-on-android-and-ios/

How can check network is available on Android ( Delphi XE7 )

this code help you to check for network is available on Android 


Friday, February 6, 2015

How can handle a back-button press in a Delphi XE7 Android app?

if you need  make Android app react to the back-button
Right now, most of the demo applications have an on-screen back button to go back to a previous screen. Pressing the physical button always seems to quit the app, and in some situations it results in an access violation.

SEND SMS IN DELPHI APP (Android)

how can send sms form delphi app in android?
please see this examples

Example 1:

Delphi Android how can get phone number of the existing simcard

for get the number of the existing sim card to the desired device
you ca use this code but maybe not work in all android device




uses

Find Android Device Mac Address With Delphi XE

For find wifi mac address in android  device can use this code



wifimanag is wifimanag is = (wifimanag is) getsystemservi by (context.wıfı_servı by); wifiınfo Winfo = wifimanager.getconnectionınfo (); String MacAddress = wınfo.getmacaddress ();


How Can Find Mac Address in IOS with Delphi XE App

For get mac address in IOS device can use this code


  Uses
 {$ IFDEF IOS}
 iosapi.uıkit;
 {$ ENDIF}

 there is
 {$ IFDEF IOS}
 Device: uıdevi end;
 {$ ENDIF}
 begin
 {$ IFDEF IOS}
 Device: = tuıdevice.wrap (tuıdevice.occlass.currentdevi by);
 ShowMessage (device.uniqueıdentifier.utf8string);
 ShowMessage (device.identifierforvendor.uuıdstring.utf8string);
 {$ ENDIF}
 end; 

HOW CAN CREATE Custom Dialogs IN ANDROID (DELPHI ex7)

android Native message box, these messages can be created with .xml I would like to share their screen. 


Exactly what are they? 

Where it makes sense that the device screen (Editor, combo, trackbar) that there was no place to place or in the display of the image are the tools you can use is a serious inconsistency. 

Example: With a Combo Object Editor will open as soon as you clicked on an object, you can assign more choice. 

You will understand that you use a structure that can be used in more places. 

Parente as "tcustomedit" can give objects derived from the class. 

If you comboboxsettings and trackbarsettings returntext area in section automatically returns True value of the parent object that will be written. 

Android Youtube Component For Delphi XE7

if you need use video from you youtube account in you android application you can use this component

 was part of the YouTube video that is part youtubeıd equal sign (=) in the post there 

When you write and getdesign option "True" if you can see the video information automatically as you'll see below. 

Tested with XE6. 




Note: in the sample project file:

Use:
1) youtube1.play: First video shows the options playable resolution.
Is broadcast as video can be played on your YouTube videos and you can see after the device application that can play the video in the drop-down options.

Example:



2) youtube1.download: First "youtube1.downloadfold" and must specify where you want to download. After the video resolution indicates the options and the choice can be downloaded after the start of the download process. 
"Ondownload" percentage of video downloaded in the event that you can see the file size and download time. 

2.Delphi -Android Play Sound

Android Play Sound From Stream File
From Delphi IDE click on "Project". Then select "Resources and Images...". Choose your media file and set it as RCDATA. Remember your resource identifier. Note: Make sure the media type is supported by TMediaPlayer otherwise it won't work.
uses
System.IOUtils;

procedure PlayAudio(ResourceID: string);
var
ResStream: TResourceStream;
TmpFile: string;
begin
ResStream := TResourceStream.Create(HInstance, ResourceID, RT_RCDATA);
try
TmpFile := TPath.Combine(TPath.GetTempPath, 'tmp.mp3');
ResStream.Position := 0;
ResStream.SaveToFile(TmpFile);
MediaPlayer1.FileName := TmpFile;
MediaPlayer1.Play;
finally
ResStream.Free;
end;
end;
PlayAudio('Resource_1');

 
Important Note: Most of my code into notepad deposited collected from different sources. For this reason, do not specify a majority in the source. Such is the case and you have a code that you know the source of the spell would be requested to notify the comments. Regards.