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.
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
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.
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;
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:
All of the paths in the Deployment tab use backslashes as I assume they refer to the Windows file system structure that the project files are on. Iām guessing they are converted to forward slashes when deployed. If you use forward slashes in the Deployment window, it still compiles and deploys but the app hangs.
Iām experimenting with adding Windows 64-bit to the target platforms. So far Iāve added conditional defines to cope with different calling conventions, uses statements, etc and it now compiles.
What I donāt know is how to define the target for the windows DLL in the deployment window for the Win64 platform so that it ends up alongside the exe file.