Android Files Deployment

In my first FMX application, I need to include some SO files for audio playback. For my VCL application it was as simple as including the dll files alongside the exe, but obviously Android is quite different.

The SO files come from the vendor in a structure. Some reading suggests that only the first one is required for modern Android devices. I do have the option of dynamically loading the files if that makes anything easier.

\libs\arm64-v8a\file.so
\libs\armeabi-v7a\file.so
\libs\x86\file.so
\libs\x86_64\file.so

I guess what I don’t get is where to place them in my source folder and how to deploy them to the application. I see the Project > Deployment window and have tried various things there, but need some help understanding it.

Add them individually from the deployment window menu bar top far left icon with (file with +) hardtop see on my resolution and it creates the DPK file for android installation with them included …destination folder needs to be same as the main so file

Rgds

Rainer

That’s what I’ve done, but the app crashes when it tries to load the SO statically. If I remove the unit that references the SO file there’s no crash.

Ask the vendor if they have successfully tested the files with a Delphi Android app?

You mean you’re deploying the .so files with a Remote Path value of library\lib\arm64-v8a\ for the 64-bit file(s) and library\lib\armeabi-v7a\ for the 32-bit file(s)?

OK, that’s the piece of the puzzle I was not understanding. I’ve changed the remote path for the 64-bit SO file and it now seems to be loading without error. Thank you. Do I need any of the other 3 SO files if I’m only targeting modern Android devices?

For the media files I want to play (as a test for now), I’ve added them with the remote path .\files\ and can see them in Windows Explorer in the Android64\Debug<APP-NAME>\files folder of my project, but can’t seem to access them in the actual app using TPath.Combine(TPath.GetHomePath, ‘Track 1.mp3’) (FileExists also returns false). The full path looks to be correctly formed when checked via debugging.

You will need \libs\armeabi-v7a\file.so if you’re targeting 32-bit as well as 64-bit ARM devices. As far as I know, Delphi does not support Intel (x86, x86_64) Android devices - unless they have Houdini? Someone else might be able to chime in on that count.

I just solved part of this. The media filenames had spaces in them and it seems that’s an issue. I renamed them and suddenly the files appear with TPath.GetFiles and the audio library loads and plays them!

I had similar problems with client data sets and had to load them into documents and write code to provide permissions and provide file locations in code
like the following excuse the show message code but this app did not make it to the public so code not cleaned up
It’s possible the DLL’s access is not permitted or android has put them somewhere other than the main code file

In the end I had to put the data file into documents folder
You may need to provide a hard coded path to the DLL’s in the form create procedure
version RAD studio 10.4 but worked in 10 2

Is your DLL code 64bit?..another problem for latest versions of Android and a lot depends on the version and android emulator used
Rgds Ray sans

procedure TForm1.FormCreate(Sender: TObject);

Var

sdataPath : String;

begin

MultiView1.CustomPresentationClass := TMultiViewAlertPresentation;

{$IF DEFINED(MSWINDOWS)}

sdataPath := System.SysUtils.GetCurrentDir;

CdsHloans4.FileName := sDataPath+PathDelim+‘Homeloans4.cds’;

if FileExists(‘Homeloans4.cds’) then

begin

//Showmessage('File located at- '+sDataPath+PathDelim+‘PersKb.fds’);

CdsHloans4.LoadFromFile(sDataPath+PathDelim+‘Homeloans4.cds’);

CdsHloans4.Active := True;

end

else

Showmessage(‘Could not find local Main data table at ’ + sdatapath+’..reinstall your app’);

{$ENDIF}

{$IF DEFINED(ANDROID)}

FPermissionWrite := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE); //Значение на запись

FPermissionRead := JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE);

PermissionsService.RequestPermissions([FPermissionWrite, FPermissionRead], nil);

sdataPath := System.IOUtils.TPath.Combine(System.IoUtils.tpath.getdocumentspath,‘Homeloans4.cds’);

// or on external GetSharedDocumentsPath ‘LeaseFD.fds’);

if sdataPath =‘’ then

begin

sdataPath := System.IOUtils.TPath.Combine(System.IOUtils.tpath.GetSharedDocumentsPath,‘Homeloans4.cds’);

//showmessage(‘The file Homeloans4.cds was found in shared documents on your memory card’);

end;

//else

//showmessage('Homeloansq.cds was found in documents on your phone ’ +sDataPath);

CdsHloans4.FileName := sDataPath;

{if FileExists(‘Homeloans4.cds’) then

begin

CdsHloans4.LoadFromFile(sDataPath);

CdsHloans4.Active := True;

end

else

Showmessage(‘Could not find local Main data table at ’ + sdatapath+’..reinstall your app’);}

//FPermissionCamera := JStringToString(TJManifest_permission.JavaClass.CAMERA);

VKAutoShowMode := TVKAutoShowMode.Always;

{$ENDIF}

TabControl1.ActiveTab := TabItemInfo;

MultiView1.Mode := TMultiViewMode(3);

Layout5.Visible := False;

end;

The SO (DLL) part of the problem was solved by deploying them to the correct folders.

My current problems are spaces in the file names and where to deploy the sample mp3 files so they are accessible to my app.

Deploying the sample files to library\lib\arm64-v8a\ did work, but doesn’t really seem like the right place for them.

Normally you would deploy them to either ./assets/internal or a subfolder thereof, which at runtime translates to TPath.GetDocumentsPath (or a subfolder thereof). An example would be to deploy to: ./assets/internal/Samples and the base path at runtime would be:

SamplesPath := TPath.Combine(TPath.GetDocumentsPath, 'Samples');

Thank you again. I now have the sample files deployed to their own folder and I can list and play audio as required.

Next I needed a good place for end users to add their own files for my app to play them.

TPath.GetSharedDownloadsPath maps to \Internal storage\Download and is accessible via Windows Explorer so that seems like a reasonable solution.