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
Related
I am trying to build my application on android. I am bit stucked on
GstElement* pipeline = gst_parse_launch ("rtspsrc location=rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov ! decodebin ! appsink name=sink", &err);
because, GError *err writes out no element "rtspsrc". I have already searched for some ways to add missing plugins/elements, but with no success.
I have found this page, which shows how to install plugins in code, but when I tried, gst_install_plugins_sync returned GST_INSTALL_PLUGINS_HELPER_MISSING and from this point, i don't know how to continue.
I have fully built library for gstreamer-1.0 including libgstrtsp-1.0, but I don't understand why my program doesn't find it.
How can I add plugins/elements to android?
Thanks for your help!
//EDIT:
Link, which I used to build libary, and I am using Android 4.4.4
You have to define extra plugins inside your Android.mk file:
GSTREAMER_PLUGINS := $(GSTREAMER_PLUGINS_CORE) $(GSTREAMER_PLUGINS_PLAYBACK) $(GSTREAMER_PLUGINS_CODECS) $(GSTREAMER_PLUGINS_CODECS_RESTRICTED) $(GSTREAMER_PLUGINS_NET) $(GSTREAMER_PLUGINS_SYS)
The list of available plugins groups are defined in:
$(GSTREAMER_ROOT_ANDROID)/$(TARGET_ARCH_ABI)/share/gst-android/ndk-build/plugins.mk
Additonally use playbin to play the RTSP stream like:
gst_parse_launch("playbin uri=rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", &error);
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;
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.
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.
I want to add my own framework code that runs in the Android "system_server" (handles all the system level services). My service loads a JNI library that talks to a driver I have added to the kernel. The service is designed to allow an app to register a listener with it to get updates from the driver. I found a pretty good blog post (http://www.androidenea.com/2009/12/adding-system-server-to-android.html) that explains how to add a system service, but I cannot get it completely working.
First of all, the post mentions that an "appropriate" Android.mk file should be used to write the client/test application, but does not give an example of this. When I try to build it, I get build errors saying it can't find the service I have added. Could someone give an example of what this might look like?
Also, I'd like to implement this in the vendor directory (or device directory in froyo) rather than in the Android open source code. The blog post mentions that the proper place for this is the vendor directory, but does not give an example of what this should look like. Anyone know?
ANY additional information on implementing your own system service in Android would be helpful. Again my specific workflow is:
Android App -> System Service -> JNI (native) library -> Device Driver
Texas instruments has provided a nice example:
http://processors.wiki.ti.com/index.php/Android-Adding_SystemService
Additionally, the CyanogenMod SystemServer.java has also code for dynamically loading system services as defined in the array "config_vendorServices" in config.xml (see core/res/res/values/config.xml), which I believe can be overwritten in the vendor or device directories using the overlays. This is a CyanogenMod-specific addition, added in this commit:
https://github.com/CyanogenMod/android_frameworks_base/commit/88fff90131f54d45dc496c45127ac1d16ad257df
There are multiply way (or 6 ways, just to be explicit) of adding a system service.
What you tried (Android App -> System Service -> JNI (native) library -> Device Driver) is one of them. You might want check out this article for an in-depth explanation regarding system service implementation patterns.
Follow the below steps for writing your own System Service in android framework.
Write your Own Service/Manager with API's exposed by inheriting the stub.
Create an aidl file for your service to expose & include in build.
Add your service in System Server, you service will start along with all core services.
Register your service context in context impl file.
Use your service in application by calling getSystemService(Context of your service)
PS; if your service get some fatal exception, device will soft reboot, as your service is running under system service.
Here is an example of an Android.mk used to compile a JNItest.c located at system/extras/JNITest. The Android.mk is also inside system/extras/JNITest directory.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= JNITest1.c
LOCAL_MODULE:= JNITest
#LOCAL_FORCE_STATIC_EXECUTABLE := true
#LOCAL_STATIC_LIBRARIES := libc
LOCAL_SHARED_LIBRARIES := libc
#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := eng
include $(BUILD_EXECUTABLE)