Delphi FMX - Android API 26 - SQLite DB Connection with UniDAC - android

I'm using Tokyo 10.2.3 and UniDAC component for interacting with an SQLite database on Android API 26 Platform.
So far, with the help from Dave:
http://www.delphiworlds.com/2018/06/targeting-android-8-and-higher-continued/
... the App worked fine with access to 'TakePhoto', 'Positioning', 'W/R to external storage' ... The UniDAC MySQL Connection is working too but seems to need no further permissions.
But I can get no connection to my SQLite Database anymore. Before the change from SDK14 to SDK26, the connection worked fine. Seems to me, as it is a problem with accessing 'external' URIs as Dave described in his blog. I changed the Manifest.xml, added a file-provider and added the provider_paths.xml too.
The way of choose the Databasefile with UniDAC as String:
SQLiteConnection1.Database := TPath.Combine(TPath.GetDocumentsPath, 'test.db');
Any solutions or help outside?

Deployment path: assets\internal
Change UniConnection.Direct to true.
Add UNIDAC before connection
procedure TDataModule1.UniCon_SQliteBeforeConnect(Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
DataModule1.UniCon_SQlite.Database :=
TPath.Combine(TPath.GetDocumentsPath, 'st_pass.db');
{$ENDIF}
end;

Related

Deploying SQLite database with Delphi application on Android

I'm having some trouble with adding SQLite database into my Android application written in Delphi. First, I have added the database file into the project manager and in deployment manager changed its Remote Path to .\assets\internal\. Then I have added the following code into FDConnection BeforeConnect event. The code is:
begin
{$IFDEF ANDROID}
MissiledbConnection.Params.Values['ColumnMetadataSupported'] := 'False';
MissiledbConnection.Params.Values['Database'] :=
TPath.Combine(TPath.GetDocumentsPath, 'MissileDB.db');
{$ENDIF}
end;
Despite that, I'm still getting this error while trying to compile Android version of my application:
[FireDAC][Stan][Def]-254. Definition [MissileDB.db] is not found in []
When I compile my application under Windows, everything works perfectly fine. I honestly have no idea what I'm doing wrong, since every tutorial I've found only mentions the Deployment manager and the event code, which I implemented as I shown.
Thank you in advance for your help.
I applied to "TPath.GetHomePath" and the application started. Resource 'assets/internal' places the database in this directory by default. It is inaccessible from the outside. How to put deploy to a different but public or shared directory, unfortunately, I do not know.
regards AK

Is there any way with FireMonkey to use android-support-v4 that goes with Marshmallow?

I need the android-support-v4 that goes with Android Marshmallow because it's contain the object PermissionChecker and it's the only way to know (on Marshmallow and up) if a user has denied an app permission (like location for example).
I saw C:\Program Files (x86)\Embarcadero\Studio\18.0\lib\android\debug\android-support-v4.jar but I don't see any PermissionChecker inside C:\Program Files (x86)\Embarcadero\Studio\18.0\lib\android\debug\classes.dex so i guess it's an old support-v4 that it's used inside the classes.dex.
Is there any way to update the classes.dex to use instead the latest android-support-v4 ?
Here's what I did:
Used Java2OP against the android-support-v4.jar file in C:\Users\Public\Documents\Embarcadero\Studio\18.0\PlatformSDKs\android-sdk-windows\extras\android\support\v4 (you may need to download the Android Support Library in the Extras section of Android SDK Manager) because the PermissionChecker exists in that jar.
Disabled android-support-v4.dex.jar in the Libraries node for the project.
Added the android-support-v4.jar (mentioned in step 1) to the project
Using TJPermissionChecker.JavaClass.checkSelfPermission now returns the correct result if the user has denied the permission (i.e. in Android 6 or above)
On the off-chance the answer to my comment/question to the posted question is "Oh, I hadn't tried that" and that regular approach works just fine, here is a unit that does regular Android permission checking.
unit MiscU;
interface
function HasPermission(const Permission: string): Boolean;
implementation
uses
FMX.Helpers.Android,
Androidapi.Helpers,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.GraphicsContentViewText;
function HasPermission(const Permission: string): Boolean;
begin
//Permissions listed at http://d.android.com/reference/android/Manifest.permission.html
{$IF RTLVersion >= 30}
Result := TAndroidHelper.Context.checkCallingOrSelfPermission(
{$ELSE}
Result := SharedActivityContext.checkCallingOrSelfPermission(
{$ENDIF}
StringToJString(Permission)) =
TJPackageManager.JavaClass.PERMISSION_GRANTED
end;
end.
I'll remove this answer if it transpires that I am simply unaware of certain aspects of the more modern Android releases and this listing is not at all relevant to the issue the asker is trying to solve.

Resolving ANDROIDAPI and FMX units

I'm totally new in Delphi Android programming and I need to create a very simple Android App that should send a simple SMS message.
I found an example on the internet and it looks quite simple...
uses
FMX.Helpers.Android,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.Net,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.Telephony;
procedure SendSMS (target,messagestr:string);
var
smsManager: JSmsManager;
smsTo: JString;
begin
smsManager:= TJSmsManager.JavaClass.getDefault;
smsTo:= StringToJString(target);
smsManager.sendTextMessage(smsTo, nil, StringToJString(messagestr), nil, nil);
end;
But...
When I try to put those lines in USES clause, I get them red-underlined followed by the message "Cannot resolve unit name...". I found all those units (.DCU, .O and .PAS) in folders on my computer and added those paths in Search Path and Browsing Path in Tools/Library/Android...
I have the latest JDK, Android SDK and Android NDK...
I use Delphi XE8, but I get the exactly same message in Delphi 10...
Any ideas?
Thanks in advance...
You must be sure to start a Delphi multi-device application in D10 and switch the target platform to 'Android'. Then hook up your emulator or device. The FMX - and the AndroidApi units are not in scope on a Win32/Win64 project.

delphi XE7 firemonkey android shared object / library to be dynamically loaded - template

Is there a template to create a .so file that can be loaded by another delphi ape file - I have tried starting a blank fire monkey project and changing program to library and build it but the .so file that it produces won't load with dlopen within another delphi project. I have read that in other development environments there is a islibrary setting. I guess more to the point is there an example .so library built with fire monkey - I have found the bare bones link without fire monkey but it uses just jni not androidapi.jni - thanks
If you start a blank Firemonkey project and change Unit to Library, you'll get this compiler error:
[DCC Error] myfunnylib.pas(1): E2029 'UNIT' expected but 'LIBRARY' found
Trying to add an existing library project to the project group will separate said project from the rest of the build and assign unique build targets and platforms to it. Which will leave you with options to compile for Windows and OS X.
The only way I've heard of so far is to pre-compile your library with another compiler. FPC has been mentioned elsewhere. I haven't tried that yet but its next on the list.
http://wiki.freepascal.org/Android
Don't get confused by the fact that every Android app is in fact a shared object with the extension .so (for shared object). However, this is not the same thing as a shared library.
Because a library exports its functions while an application does not. To a compiler, that IS quite a difference though you wouldn't see that by looking at the file extension (but its prefix lib instead).
If you restrict your question to XE and Firemonkey, my only suggestion here would be to look into Android services. A bound local service might offer similar capabilities you'd expect from a library:
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Android_Service
It's also important to note that Android N will not allow dynamic linking anymore so many of the methods you'll find elsewhere as a solution won't work.
suat dmk's code example in the answer below, though up-voted, is misleading.
It cannot be compiled for Android or iOS in XE 10.1 or any of its predecessors.
UPDATE:
There's a definite statement from Embarcadero staff regarding this issue.
It took a bit of patience in explaining the question, but the reply is clear enough:
[..] wants Delphi to have a project type of Shared Library(.so),
in this case then he is right, Delphi does not have it right now. [..]
quod erat demonstrandum
Hence there can be no such template. Also answers this question.
the following codes may be useful.
//-- Code for libMylib.so (MyLib.dproj) ---
library MyLib;
// uses SysUtils;
function GetSum(a, b: integer ) : integer; cdecl;
begin
Result := a + b;
end;
exports
GetSum name 'GetSum';
begin
end.
//-- Code for using libMylib.so (TestMyLib.dproj) ---
var
DocDir, LibFN: string;
GetSum: function(a, b: integer ) : integer; cdecl;
hLib: HMODULE;
begin
DocDir := IncludeTrailingPathDelimiter(System.IOUtils.TPath.GetLibrary`enter code here`Path);
LibFN:=DocDir + 'libMyLib.so';
hLib := LoadLibrary(LibFN); //ERROR (Segmentation fault (11))
if hLib<>0 then
begin
GetSum := GetProcAddress(hLib, 'GetSum');//It works
ShowMessage(IntToStr(GetSum(3, 8)));//It works
end;
end;
P.S: you must add compiled libMyLib.so file to Deployment of TestMyLib.dproj.
P.S2: it gives an error while executing "LoadLibrary", but it Works.
I couldn't find a solution. Probably it is related with compiler/linker options of MyLib.dproj. Because when I test another '.so' file which is compiled with C++, no problem occurs while calling LoadLibrary.

Load text file into stringlist in Delphi XE-5 Firemonkey Android App

I have a text file (tags.txt) that i would like to deploy with my app. I then want to load it into a TStringList at start up. As of now for testing purposes, i have it just in a button's onClick event. However, it doesn't seem to work. I have read a number of resources on line, including those from embarcadero and SO. I just do not know what i am doing wrong. I get a "Cannot open file "/data/data/com.embarcadero.PTMMobile/files/tags.txt". No such file or directory.
Here is my code:
var
frmMain: TfrmMain;
AppPath: String;
Tags: TStringList;
implementation
{$R *.fmx}
uses System.IOUtils;
procedure TfrmMain.Button1Click(Sender: TObject);
begin
Tags:= TStringList.Create;
try
AppPath := TPath.Combine(TPath.GetDocumentsPath, 'tags.txt');
Label1.Text:= AppPath;
Tags.LoadFromFile(AppPath);
Label2.Text:= IntToStr(Tags.Count);
finally
Tags.Free;
end;
end;
end.
My remote path is assets\internal
Looking at your screenshot it seems the original file is in the Debug binaries folder of your application.
Try to move the file in the project folder and retry (of course you have to re-add the new file location to your deploy options).
The binaries folder may be cleaned up at each build, deleting your original file just before trying to deploy it to the device.
Hth

Categories

Resources