安卓插件化续篇:加载native库、共享私有文件

上一回实现了一个插件的皮毛,本打算兼并火狐浏览器的GeckoView,作为webview的又一个可选替代,但没能成功,加载动态库时总是失败。怪只怪功力不够深厚。最近又要给tesseract做一个插件,作为安卓的文本识别之心。需小试一番,记录如下。

上一篇 > 巧用createPackageContext,实现插件化

Github : Plugin101Plugin Invoker 101

共享 Tesseract 动态库

chromium.googlesource.com/chromium/sr…

介绍安卓webview的加载机制,没看懂,只看明白“只要是库APP中的类,就可以像往常一样加载动态库”, so easy。

github.com/adaptech-cz…

这个Tesseract Android版本通过maven { url "https://jitpack.io" }api 'cz.adaptech:tesseract4android:4.1.1'提供了编译好的库(也可自行编译),在插件项目中直接引用,测试识别处于 raw 目录下的图片文件。调用者无需集成Tesseract的Java/c++代码即可拥有高大上的OCR光学识别能力

public class TesseractPluginTest { ...

public static void Test(Context context) {
   //CMN.rt();
   TessBaseAPI tess = new TessBaseAPI();
   
   String dataPath = new File(Environment.getExternalStorageDirectory(), "tesseract").getAbsolutePath();
   
   tess.init(dataPath, "eng");
   
   tess.setImage(getBitmapFromAsset(context, R.raw.text));
   String text = tess.getUTF8Text(); // 纯文本
   String textFormatted = tess.getHOCRText(0); // OCR标记html,每个单词隔开,各种信息
   //CMN.pt("test_done", text); // 总共需要一秒不到的时间,不快不慢
   
   Toast.makeText(context, text, 1).show();
   
   tess.recycle();
}
复制代码

美中的不足是模型文件需要自己下载然后放到sd卡,这意味着调用者需要sd卡的读写权限,其实可以避免 ——

通过 contentProvider 共享私有目录的文件

参考:(其代码…总是胡乱换行,是不是屏幕太小了,或者不知道有个快捷键叫做Shift + 鼠标滚轮?)

通过ContentProvider访问应用的data区files的文件

写在插件里的 ContentProvider :

public class PluginFileProvider extends ContentProvider {...

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
   //CMN.Log("PluginFileProvider_openFile::", uri);
   File file = new File(getContext().getExternalFilesDir(null), uri.getPath());
   if (file.exists()) {
      //CMN.Log("PluginFileProvider_openFile::exists");
      return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
   }
   //CMN.Log("PluginFileProvider_openFile::not exist!!");
   throw new FileNotFoundException(uri.getPath());
}
复制代码

需在清单文件中注册:(其中name是实现类的路径,authorities是uri的getAuthority,中文不知道怎么说,主域名?)

<application ...

<provider
   android:name="com.knziha.plugin101.PluginFileProvider"
   android:authorities="com.knziha.plugin101"
   android:exported="true" >
</provider>
复制代码

测试项目以只读方式共享了sd卡外部私有目录getExternalFilesDir(/sdcard/Android/data/…)下的data.txt。调用者无需获取整个sd卡的读写权限,即可访问并读取插件私有目录下data.txt中的内容。Tesseract的模型文件可以下载或者解压到这个目录中,会随插件的卸载而自动删除。

public class PrivatePathTest { ...

public static void Test(Context context) {
   try {
      //File dataFile = new File(context.getExternalFilesDir(null), "data.txt");
      //FileInputStream fint = new FileInputStream(dataFile);//不行
      //FileInputStream fin = context.openFileInput(dataFile.getName()); //不行
      
      //fin.getFD()
      
      Uri uri = Uri.parse("content://com.knziha.plugin101/data.txt");
      InputStream fin = context.getContentResolver().openInputStream(uri);
      
      byte[] data=new byte[512];
      int len=fin.read(data);
      fin.close();
      //CMN.Log("PrivatePathTest::", new String(data, 0, len));
   } catch (Exception e) {
      //CMN.Log(e);
   }
}
复制代码

下一步是实现图文之心插件 —— Tesseraction

未完待续……

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享