I created a simple application using the tesseract library:

File manifest:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.skolos.sum"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="true" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

Main Activity Code:

 import android.content.Context; import android.content.Intent; import android.os.Environment; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import com.googlecode.tesseract.android.TessBaseAPI; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.widget.TextView; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class MainActivity extends AppCompatActivity { private ImageView imageView; private TessBaseAPI mTess; Bitmap imageBitmap; Bitmap image; String datapath = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (ImageView) findViewById(R.id.imageView); Context context = MainActivity.this; //init image image = BitmapFactory.decodeResource(getResources(), R.drawable.test_image); //initialize Tesseract API String language = "eng"; datapath = context.getFilesDir()+ "/tesseract/"; mTess = new TessBaseAPI(); checkFile(new File(datapath + "tessdata/")); mTess.init(datapath, language); } public boolean init(String datapath, String language) { if (datapath == null) { throw new IllegalArgumentException("Data path must not be null!"); } if (!datapath.endsWith(File.separator)) { datapath += File.separator; } File tessdata = new File(datapath + "tessdata"); if (!tessdata.exists() || !tessdata.isDirectory()) { throw new IllegalArgumentException("Data path must contain subfolder tessdata!"); } return init(datapath, language); } static final int REQUEST_IMAGE_CAPTURE = 1; public void getImage(View view) { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); imageView.setImageBitmap(imageBitmap); String OCRresult = null; mTess.setImage(imageBitmap); OCRresult = mTess.getUTF8Text(); EditText OCRTextView = (EditText) findViewById(R.id.OCRTextView); OCRTextView.setText(OCRresult); } } private void checkFile(File dir) { if (!dir.exists() && dir.mkdirs()) { copyFiles(); } if (dir.exists()) { String datafilepath = datapath + "/tessdata/eng.traineddata"; File datafile = new File(datafilepath); if (!datafile.exists()) { copyFiles(); } } } private void copyFiles() { try { String filepath = datapath + "/tessdata/eng.traineddata"; AssetManager assetManager = getAssets(); InputStream instream = assetManager.open("tessdata/eng.traineddata"); OutputStream outstream = new FileOutputStream(filepath); byte[] buffer = new byte[1024]; int read; while ((read = instream.read(buffer)) != -1) { outstream.write(buffer, 0, read); } outstream.flush(); outstream.close(); instream.close(); File file = new File(filepath); if (!file.exists()) { throw new FileNotFoundException(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 

The code works in an emulator with API 24:

Android 7.0 - works

Does not work with API 22 and below:

Android 5.1 - crash without errors in the console

I have an assumption that the cant can be in this piece of code in the main activity:

  //initialize Tesseract API String language = "eng"; datapath = context.getFilesDir()+ "/tesseract/"; mTess = new TessBaseAPI(); checkFile(new File(datapath + "tessdata/")); mTess.init(datapath, language); 

Obviously, it crashes on initialization, apparently, the library cannot open the language file at datapath. Attention, experts! Question: What could be the difference in different versions of Android and how to make it work in older versions of the firmware?

    1 answer 1

    Add <uses-sdk android:minSdkVersion="21"/> manifest file, then the error should disappear when working with API 22 .

    • not. The result is the same. It crashes without issuing errors to the console, it works with API 24 ( - larrymacbarry
    • @larrymacbarry, then please add logs with an error to the message - Ksenia
    • E / AndroidRuntime: FATAL EXCEPTION: main Process: com.example.skolos.sum, PID: 2794 java.lang.RuntimeException: Unable to start activity ComponentInfo {com.example.skolos.sum / com.example.skolos.sum.MainActivity }: java.lang.IllegalArgumentException: Data file not found at /data/data/com.example.skolos.sum/files/tesseract/tessdata/eng.traineddata at android.app.ActivityThread.performLaunchActivity (ActivityThread.java Land325) In one of the launches issued that does not find the file with the language. Almost all other times, the application crashes without any errors in the log - larrymacbarry