3

I want to use open alpr (automatic licences plate recognition) library in my android project. I compiled everything successfully and now it is time to use open alpr in app but...

to create Alpr class object properly I have to provide path to config file and path to runtime_data folder which contains some mandatory files needed by open alpr (ocr and trained data).

I tried something like:

Alpr alpr = new Alpr("eu", "android_assets/alpr.conf", "android_assets/runtime_data");

but Alpr.isLoaded() returns false which means that config or runtime_data have not been found.

Path to assets folder in project is: src/main/assets.

Can someone explain to me how path to "runtime_data" directory and "alpr.conf" should looks to be visible by open alpr?

Thanks in advance.

Kushal
  • 8,100
  • 9
  • 63
  • 82
user2311165
  • 53
  • 1
  • 8
  • Did you ever end up finding the solution ? – Arthur Attout Sep 17 '19 at 09:59
  • @ArthurAttout, I've just implemented and tested this library in Lenovo K10a40, I did nothing but follow the steps in my answer below. Please, check if it works for you. If not, let me know. – Farid Sep 20 '19 at 16:16

3 Answers3

1

I am not familiar with the specific library, but on newer Android devices (Android 6 and up), you can not rely on your application files residing under /data/data/your.package.name

The actual library name still includes the package name of your app, but also has some identifier appended to it in base64 format. This identifier is unique per installation, and it will change if you uninstall and reinstall the app on the same device.

So, if your library needs to use a configuration file with a path to some other files, there are 2 options:

  1. The right way:
    Get the real address of your application files folder using Context.getFilesDir().
    Unpack you files from the assets folder of the APK on the device using AssetManager.
    Programmatically rewrite your configuration file with the path returned by getFilesDir().

  2. The "hacky" but simpler way: Use public storage to unpack your files.
    You will need to add WRITE_EXTERNAL_STORAGE permission to your app, and unpack the assets files to the external storage.
    For backwards compatibility this will be available under /sdcard folder on most Android devices, even with the latest Android version.

The second method is not recommended since using /sdcard directly is deprecated and strongly discouraged by Google.
Also, not all Android devices have /sdcard link to their public storage, but this is the only way to avoid dynamically editing the configuration file after installation.

Lev M.
  • 6,088
  • 1
  • 10
  • 23
  • The solution I managed to find involves indeed moving the content of the assets file to the files directory programmatically. And it is linked to another question [I brought up later](https://stackoverflow.com/questions/57971178/where-is-the-runtime-directory-for-so-android-libs/57973866#57973866). Although I ended up finding this on my own, I think this answer would've helped me, so I'll give the bounty. – Arthur Attout Sep 21 '19 at 12:31
  • @ArthurAttout thanks, finding out about this ALPR library helped me too, as it may turn out useful for a future project I am planning. – Lev M. Sep 21 '19 at 12:34
  • This lib made me loose an enormous amount of time, between compilation problems and OpenCV memory issues. The CLI is ok, but the bindings are an absolute nightmare (at least in Java). If you ever end up getting something good out of it, would you mind sharing it ? – Arthur Attout Sep 21 '19 at 12:52
0

Important note before you start implementing those steps. This library supports only arm CPU architecture. Good news is, most probably, your physical device is using arm architecture but to make sure just double-check it before implemting those steps.

I've recompiled this library to a new wrapper library. In original library, you need to manually configure openalpr.conf file and edit its content with correct path to your data directory. Manual configuration is cumbersome because since Android 5 multiple user accounts is supported and we can't simply hardcode data directory as /data/data/com.your.packagename/..... Because every user gets their symlink to data directory as /data/user/0/com.your.packagename/..... All those manual steps are gone in recompiled wrapper library.

Implementation

Add this in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Add the dependency into app module:

dependencies {
    ...
    implementation 'com.github.mecoFarid:openalpr:1.0.0'
}

And you're done. Please check this sample app to get started with UI.


Troubleshooting:

If your target sdk is targetSdkVersion >= 24 and you're running your app on a device with Android API 24+ you'll get following error:

android.os.FileUriExposedException: file:///storage/emulated/0/OpenALPR/2019-09-21-01-32-13.jpg exposed beyond app through ClipData.Item.getUri()

To solve this error: you can add following lines into onCreate() of your Activity as a workaround or you may use this thread for offical solution:

if(Build.VERSION.SDK_INT>=24){
        try{
            Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
            m.invoke(null);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

TEST:

You can use this image to test your app.

Farid
  • 2,317
  • 1
  • 20
  • 34
  • Using the original code from OpenALPR is something I was already doing, so unfortunately this doesn't bring up any further information. – Arthur Attout Sep 21 '19 at 12:29
-3
"/data/data/yourpackagename" + File.separatorChar + "runtime_data"
                             + File.separatorChar + "openalpr.conf"; 
Laurel
  • 5,965
  • 14
  • 31
  • 57