diff --git a/android/build.gradle b/android/build.gradle index b500b2bc..407a17f8 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -63,7 +63,7 @@ repositories { dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) compile 'com.android.support:appcompat-v7:25.1.0' - compile 'io.anyline:anylinesdk:3.8.1@aar' + compile 'io.anyline:anylinesdk:3.9.0@aar' compile 'com.google.android.gms:play-services-vision:10.0.1' compile 'com.android.support:design:25.1.0' compile "com.facebook.react:react-native:+" // From node_modules diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 7b2477b1..dd717ab3 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -11,5 +11,6 @@ + diff --git a/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java b/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java index 6a2670e1..131c0c7e 100644 --- a/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java +++ b/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java @@ -41,6 +41,7 @@ class AnylineSDKPlugin extends ReactContextBaseJavaModule implements ResultRepor public static final int ANYLINE_OCR = 5; public static final int BARCODE = 6; public static final int ANYLINE_MRZ = 7; + public static final int ANYLINE_DOCUMENT = 8; private JSONObject configObject; @@ -84,7 +85,7 @@ public void setupScanViewWithConfigJson(String config, String scanMode, Callback scan(MrzActivity.class, config, scanMode, ANYLINE_MRZ); break; case "DOCUMENT": - onErrorCallback.invoke("Not implemented yet"); + scan(DocumentActivity.class, config, scanMode, ANYLINE_DOCUMENT); break; default: onErrorCallback.invoke("Wrong ScanMode"); diff --git a/android/src/main/java/com/anyline/reactnative/DocumentActivity.java b/android/src/main/java/com/anyline/reactnative/DocumentActivity.java new file mode 100644 index 00000000..0e3ff9a4 --- /dev/null +++ b/android/src/main/java/com/anyline/reactnative/DocumentActivity.java @@ -0,0 +1,390 @@ +package com.anyline.reactnative; + +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.app.ProgressDialog; +import android.graphics.Bitmap; +import android.graphics.PointF; +import android.os.Bundle; +import android.os.Environment; +import android.support.v4.content.ContextCompat; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + + +import org.json.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import at.nineyards.anyline.camera.AnylineViewConfig; +import at.nineyards.anyline.camera.CameraController; +import at.nineyards.anyline.camera.CameraOpenListener; +import at.nineyards.anyline.models.AnylineImage; +import at.nineyards.anyline.modules.document.DocumentResultListener; +import at.nineyards.anyline.modules.document.DocumentScanView; + +/** + * Example activity for the Anyline-Document-Detection-Module + */ +public class DocumentActivity extends AnylineBaseActivity implements CameraOpenListener { + + private static final String TAG = DocumentActivity.class.getSimpleName(); + private DocumentScanView documentScanView; + private Toast notificationToast; + private ImageView imageViewResult; + private ProgressDialog progressDialog; + private List lastOutline; + private ObjectAnimator errorMessageAnimator; + private FrameLayout errorMessageLayout; + private TextView errorMessage; + private long lastErrorRecieved = 0; + + private android.os.Handler handler = new android.os.Handler(); + + // takes care of fading the error message out after some time with no error reported from the SDK + private Runnable errorMessageCleanup = new Runnable() { + @Override + public void run() { + if (System.currentTimeMillis() > lastErrorRecieved + getApplication().getResources().getIdentifier("error_message_delay", "integer", getPackageName())) { + if (errorMessage == null || errorMessageAnimator == null) { + return; + } + if (errorMessage.getAlpha() == 0f) { + errorMessage.setText(""); + } else if (!errorMessageAnimator.isRunning()) { + errorMessageAnimator = ObjectAnimator.ofFloat(errorMessage, "alpha", errorMessage.getAlpha(), 0f); + errorMessageAnimator.setDuration(getResources().getIdentifier("error_message_delay", "integer", getPackageName())); + errorMessageAnimator.setInterpolator(new AccelerateInterpolator()); + errorMessageAnimator.start(); + } + } + handler.postDelayed(errorMessageCleanup, getResources().getIdentifier("error_message_delay", "integer", getPackageName())); + + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(getResources().getIdentifier("activity_scan_document", "layout", getPackageName())); + //Set the flag to keep the screen on (otherwise the screen may go dark during scanning) + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + imageViewResult = (ImageView) findViewById(getResources().getIdentifier("image_result", "id", getPackageName())); + errorMessageLayout = (FrameLayout) findViewById(getResources().getIdentifier("error_message_layout", "id", getPackageName())); + errorMessage = (TextView) findViewById(getResources().getIdentifier("error_message", "id", getPackageName())); + + documentScanView = (DocumentScanView) findViewById(getResources().getIdentifier("document_scan_view", "id", getPackageName())); + // add a camera open listener that will be called when the camera is opened or an error occurred + // this is optional (if not set a RuntimeException will be thrown if an error occurs) + documentScanView.setCameraOpenListener(this); + // the view can be configured via a json file in the assets, and this config is set here + // (alternatively it can be configured via xml, see the Energy Example for that) + JSONObject jsonObject; + try { + jsonObject = new JSONObject(configJson); + } catch (Exception e) { + //JSONException or IllegalArgumentException is possible, return it to javascript + finishWithError("error_invalid_json_data"); + return; + } + + documentScanView.setConfig(new AnylineViewConfig(this, jsonObject)); + + // Optional: Set a ratio you want the documents to be restricted to. default is set to DIN_AX + documentScanView.setDocumentRatios(DocumentScanView.DocumentRatio.DIN_AX_PORTRAIT.getRatio()); + + // Optional: Set a maximum deviation for the ratio. 0.15 is the default + documentScanView.setMaxDocumentRatioDeviation(0.15); + + // initialize Anyline with the license key and a Listener that is called if a result is found + documentScanView.initAnyline(licenseKey, new DocumentResultListener() { + @Override + public void onResult(AnylineImage transformedImage, AnylineImage fullFrame, List documentOutline) { + + // handle the result document images here + if (progressDialog != null && progressDialog.isShowing()) { + progressDialog.dismiss(); + } + + imageViewResult.setImageBitmap(Bitmap.createScaledBitmap(transformedImage.getBitmap(), 100, 160, false)); + + /** + * IMPORTANT: cache provided frames here, and release them at the end of this onResult. Because + * keeping them in memory (e.g. setting the full frame to an ImageView) + * will result in a OutOfMemoryError soon. This error is reported in {@link #onTakePictureError + * (Throwable)} + * + * Use a DiskCache http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#disk-cache + * for example + * + */ + File outDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "ok"); + outDir.mkdir(); + // change the file ending to png if you want a png + File outFile = new File(outDir, "" + System.currentTimeMillis() + ".jpg"); + try { + // convert the transformed image into a gray scaled image internally + // transformedImage.getGrayCvMat(false); + // get the transformed image as bitmap + // Bitmap bmp = transformedImage.getBitmap(); + // save the image with quality 100 (only used for jpeg, ignored for png) + transformedImage.save(outFile, 100); + showToast(getString(getResources().getIdentifier("document_image_saved_to", "string", getPackageName())) + " " + outFile.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + } + + // release the images + transformedImage.release(); + fullFrame.release(); + + + JSONObject jsonResult = new JSONObject(); + try { + jsonResult.put("imagePath", outFile.getAbsolutePath()); + } catch (Exception jsonException) { + //should not be possible + Log.e(TAG, "Error while putting image path to json.", jsonException); + } + + Boolean cancelOnResult = true; + + JSONObject jsonObject; + try { + jsonObject = new JSONObject(configJson); + cancelOnResult = jsonObject.getBoolean("cancelOnResult"); + }catch(Exception e){ + + } + + if (cancelOnResult) { + ResultReporter.onResult(jsonResult, true); + setResult(AnylineSDKPlugin.RESULT_OK); + finish(); + } else { + ResultReporter.onResult(jsonResult, false); + } + + + + } + + + @Override + public void onPreviewProcessingSuccess(AnylineImage anylineImage) { + // this is called after the preview of the document is completed, and a full picture will be + // processed automatically + } + + @Override + public void onPreviewProcessingFailure(DocumentScanView.DocumentError documentError) { + // this is called on any error while processing the document image + // Note: this is called every time an error occurs in a run, so that might be quite often + // An error message should only be presented to the user after some time + + showErrorMessageFor(documentError); + } + + @Override + public void onPictureProcessingFailure(DocumentScanView.DocumentError documentError) { + + showErrorMessageFor(documentError, true); + if (progressDialog != null && progressDialog.isShowing()) { + progressDialog.dismiss(); + } + + // if there is a problem, here is how images could be saved in the error case + // this will be a full, not cropped, not transformed image + AnylineImage image = documentScanView.getCurrentFullImage(); + + if (image != null) { + File outDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "error"); + outDir.mkdir(); + File outFile = new File(outDir, "" + System.currentTimeMillis() + documentError.name() + ".jpg"); + try { + image.save(outFile, 100); + Log.d(TAG, "error image saved to " + outFile.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + } + image.release(); + } + } + + @Override + public boolean onDocumentOutlineDetected(List list, boolean documentShapeAndBrightnessValid) { + // is called when the outline of the document is detected. return true if the outline is consumed by + // the implementation here, false if the outline should be drawn by the DocumentScanView + lastOutline = list; // saving the outline for the animations + return false; + } + + @Override + public void onTakePictureSuccess() { + // this is called after the image has been captured from the camera and is about to be processed + progressDialog = ProgressDialog.show(DocumentActivity.this, getString(getResources().getIdentifier("document_processing_picture_header", "string", getPackageName())), + getString(getResources().getIdentifier("document_processing_picture", "string", getPackageName())), + true); + + if (errorMessageAnimator != null && errorMessageAnimator.isRunning()) { + + handler.post(new Runnable() { + @Override + public void run() { + errorMessageAnimator.cancel(); + errorMessageLayout.setVisibility(View.GONE); + } + }); + + } + } + + @Override + public void onTakePictureError(Throwable throwable) { + // This is called if the image could not be captured from the camera (most probably because of an + // OutOfMemoryError) + throw new RuntimeException(throwable); + } + + }); + + + + // optionally stop the scan once a valid result was returned +// documentScanView.setCancelOnResult(cancelOnResult); + + } + + + private void showErrorMessageFor(DocumentScanView.DocumentError documentError) { + showErrorMessageFor(documentError, false); + } + + private void showErrorMessageFor(DocumentScanView.DocumentError documentError, boolean highlight) { + String text = getString(getResources().getIdentifier("document_picture_error", "string", getPackageName())); + switch (documentError) { + case DOCUMENT_NOT_SHARP: + text += getString(getResources().getIdentifier("document_error_not_sharp", "string", getPackageName())); + break; + case DOCUMENT_SKEW_TOO_HIGH: + text += getString(getResources().getIdentifier("document_error_skew_too_high", "string", getPackageName())); + break; + case DOCUMENT_OUTLINE_NOT_FOUND: + //text += getString(R.string.document_error_outline_not_found); + return; // exit and show no error message for now! + case IMAGE_TOO_DARK: + text += getString(getResources().getIdentifier("document_error_too_dark", "string", getPackageName())); + break; + case SHAKE_DETECTED: + text += getString(getResources().getIdentifier("document_error_shake", "string", getPackageName())); + break; + case DOCUMENT_BOUNDS_OUTSIDE_OF_TOLERANCE: + text += getString(getResources().getIdentifier("document_error_closer", "string", getPackageName())); + break; + case DOCUMENT_RATIO_OUTSIDE_OF_TOLERANCE: + text += getString(getResources().getIdentifier("document_error_format", "string", getPackageName())); + break; + case UNKNOWN: + break; + default: + text += getString(getResources().getIdentifier("document_error_unknown", "string", getPackageName())); + return; // exit and show no error message for now! + } + + if (highlight) { + showHighlightErrorMessageUiAnimated(text); + } else { + showErrorMessageUiAnimated(text); + } + } + + private void showErrorMessageUiAnimated(String message) { + if (lastErrorRecieved == 0) { + // the cleanup takes care of removing the message after some time if the error did not show up again + handler.post(errorMessageCleanup); + } + lastErrorRecieved = System.currentTimeMillis(); + if (errorMessageAnimator != null && (errorMessageAnimator.isRunning() || errorMessage.getText().equals + (message))) { + return; + } + + errorMessageLayout.setVisibility(View.VISIBLE); + errorMessage.setBackgroundColor(ContextCompat.getColor(this, getResources().getIdentifier("anyline_blue_darker", "color", getPackageName()))); + errorMessage.setAlpha(0f); + errorMessage.setText(message); + errorMessageAnimator = ObjectAnimator.ofFloat(errorMessage, "alpha", 0f, 1f); + errorMessageAnimator.setDuration(getResources().getInteger(getResources().getIdentifier("error_message_delay", "integer", getPackageName()))); + errorMessageAnimator.setInterpolator(new DecelerateInterpolator()); + errorMessageAnimator.start(); + } + + private void showHighlightErrorMessageUiAnimated(String message) { + lastErrorRecieved = System.currentTimeMillis(); + errorMessageLayout.setVisibility(View.VISIBLE); + errorMessage.setBackgroundColor(ContextCompat.getColor(this, getResources().getIdentifier("anyline_red", "color", getPackageName()))); + errorMessage.setAlpha(0f); + errorMessage.setText(message); + + if (errorMessageAnimator != null && errorMessageAnimator.isRunning()) { + errorMessageAnimator.cancel(); + } + + errorMessageAnimator = ObjectAnimator.ofFloat(errorMessage, "alpha", 0f, 1f); + errorMessageAnimator.setDuration(getResources().getInteger(getResources().getIdentifier("error_message_delay", "integer", getPackageName()))); + errorMessageAnimator.setInterpolator(new DecelerateInterpolator()); + errorMessageAnimator.setRepeatMode(ValueAnimator.REVERSE); + errorMessageAnimator.setRepeatCount(1); + errorMessageAnimator.start(); + } + + private void showToast(String text) { + try { + notificationToast.setText(text); + } catch (Exception e) { + notificationToast = Toast.makeText(this, text, Toast.LENGTH_SHORT); + } + notificationToast.show(); + } + + @Override + protected void onResume() { + super.onResume(); + //start the actual scanning + documentScanView.startScanning(); + } + + @Override + protected void onPause() { + super.onPause(); + //stop the scanning + documentScanView.cancelScanning(); + //release the camera (must be called in onPause, because there are situations where + // it cannot be auto-detected that the camera should be released) + documentScanView.releaseCameraInBackground(); + } + + @Override + public void onCameraOpened(CameraController cameraController, int width, int height) { + //the camera is opened async and this is called when the opening is finished + Log.d(TAG, "Camera opened successfully. Frame resolution " + width + " x " + height); + } + + @Override + public void onCameraError(Exception e) { + //This is called if the camera could not be opened. + // (e.g. If there is no camera or the permission is denied) + // This is useful to present an alternative way to enter the required data if no camera exists. + throw new RuntimeException(e); + } +} \ No newline at end of file diff --git a/example/Anyline/.gitignore b/example/Anyline/.gitignore index 11cc77fe..e8ca583a 100644 --- a/example/Anyline/.gitignore +++ b/example/Anyline/.gitignore @@ -4,7 +4,6 @@ # Xcode # -build/ *.pbxuser !default.pbxuser *.mode1v3 @@ -14,13 +13,10 @@ build/ *.perspectivev3 !default.perspectivev3 xcuserdata -*.xccheckout *.moved-aside DerivedData *.hmap *.ipa -*.xcuserstate -project.xcworkspace # Android/IntelliJ # @@ -34,6 +30,7 @@ local.properties # node_modules/ npm-debug.log +yarn-error.log # BUCK buck-out/ @@ -41,5 +38,13 @@ buck-out/ android/app/libs *.keystore -ios/Pods -ios/Podfile.lock +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots diff --git a/example/Anyline/android/app/BUCK b/example/Anyline/android/app/BUCK deleted file mode 100644 index 0c3ce8ec..00000000 --- a/example/Anyline/android/app/BUCK +++ /dev/null @@ -1,66 +0,0 @@ -import re - -# To learn about Buck see [Docs](https://buckbuild.com/). -# To run your application with Buck: -# - install Buck -# - `npm start` - to start the packager -# - `cd android` -# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` -# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck -# - `buck install -r android/app` - compile, install and run application -# - -lib_deps = [] -for jarfile in glob(['libs/*.jar']): - name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) - lib_deps.append(':' + name) - prebuilt_jar( - name = name, - binary_jar = jarfile, - ) - -for aarfile in glob(['libs/*.aar']): - name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) - lib_deps.append(':' + name) - android_prebuilt_aar( - name = name, - aar = aarfile, - ) - -android_library( - name = 'all-libs', - exported_deps = lib_deps -) - -android_library( - name = 'app-code', - srcs = glob([ - 'src/main/java/**/*.java', - ]), - deps = [ - ':all-libs', - ':build_config', - ':res', - ], -) - -android_build_config( - name = 'build_config', - package = 'com.anyline', -) - -android_resource( - name = 'res', - res = 'src/main/res', - package = 'com.anyline', -) - -android_binary( - name = 'app', - package_type = 'debug', - manifest = 'src/main/AndroidManifest.xml', - keystore = '//android/keystores:debug', - deps = [ - ':app-code', - ], -) diff --git a/example/Anyline/android/app/build.gradle b/example/Anyline/android/app/build.gradle index eb2fa4eb..a70b86a8 100644 --- a/example/Anyline/android/app/build.gradle +++ b/example/Anyline/android/app/build.gradle @@ -130,6 +130,9 @@ android { } dependencies { + compile project(':react-native-vector-icons') + compile project(':react-native-permissions') + compile project(':react-native-android-permissions') compile project(':anyline-ocr-react-native-module') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:25.0.1" diff --git a/example/Anyline/android/app/src/main/AndroidManifest.xml b/example/Anyline/android/app/src/main/AndroidManifest.xml index e968674c..aa23d8b3 100644 --- a/example/Anyline/android/app/src/main/AndroidManifest.xml +++ b/example/Anyline/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="com.anyline" + android:versionCode="1" + android:versionName="1.0"> @@ -9,25 +9,25 @@ + android:minSdkVersion="18" + android:targetSdkVersion="22" /> - - - - - - - + android:name=".MainApplication" + android:allowBackup="true" + android:label="@string/app_name" + android:icon="@mipmap/ic_launcher" + android:theme="@style/AppTheme"> + + + + + + + diff --git a/example/Anyline/android/app/src/main/java/com/anyline/MainApplication.java b/example/Anyline/android/app/src/main/java/com/anyline/MainApplication.java index f8a63214..3cceb007 100644 --- a/example/Anyline/android/app/src/main/java/com/anyline/MainApplication.java +++ b/example/Anyline/android/app/src/main/java/com/anyline/MainApplication.java @@ -4,6 +4,9 @@ import android.util.Log; import com.facebook.react.ReactApplication; +import com.oblador.vectoricons.VectorIconsPackage; +import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage; +import com.burnweb.rnpermissions.RNPermissionsPackage; import com.anyline.reactnative.AnylinePackage; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; @@ -18,7 +21,7 @@ public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override - protected boolean getUseDeveloperSupport() { + public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @@ -26,6 +29,9 @@ protected boolean getUseDeveloperSupport() { protected List getPackages() { return Arrays.asList( new MainReactPackage(), + new VectorIconsPackage(), + new ReactNativePermissionsPackage(), + new RNPermissionsPackage(), new AnylinePackage() ); } diff --git a/example/Anyline/android/settings.gradle b/example/Anyline/android/settings.gradle index 1549562c..ba5ffa75 100644 --- a/example/Anyline/android/settings.gradle +++ b/example/Anyline/android/settings.gradle @@ -1,4 +1,10 @@ rootProject.name = 'Anyline' +include ':react-native-vector-icons' +project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') +include ':react-native-permissions' +project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android') +include ':react-native-android-permissions' +project(':react-native-android-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-permissions/android') include ':anyline-ocr-react-native-module' project(':anyline-ocr-react-native-module').projectDir = new File(rootProject.projectDir, '../node_modules/anyline-ocr-react-native-module/android') diff --git a/example/Anyline/config.js b/example/Anyline/config.js index a2fb3e37..2d2d6e5e 100644 --- a/example/Anyline/config.js +++ b/example/Anyline/config.js @@ -1,5 +1,5 @@ export default { - license: 'eyAiYW5kcm9pZElkZW50aWZpZXIiOiBbICJlb24ucmVhY3QucHJvdG90eXBlIiBdLCAiZGVidWdSZXBvcnRpbmciOiAib3B0LW91dCIsICJpb3NJZGVudGlmaWVyIjogWyAiZW9uLnJlYWN0LnByb3RvdHlwZSIgXSwgImxpY2Vuc2VLZXlWZXJzaW9uIjogMiwgIm1ham9yVmVyc2lvbiI6ICIzIiwgInBpbmdSZXBvcnRpbmciOiB0cnVlLCAicGxhdGZvcm0iOiBbICJpT1MiLCAiQW5kcm9pZCIgXSwgInNjb3BlIjogWyAiRU5FUkdZIiBdLCAic2hvd1dhdGVybWFyayI6IGZhbHNlLCAidG9sZXJhbmNlRGF5cyI6IDkwLCAidmFsaWQiOiAiMjAxNy0xMi0wNyIgfQpoVThydDFaWE9iTk9aVEVQaklMN2hYUC9ZanorVHFrYVU3L1JNek1CbG1ScUtZcXNFekpjZ0lLWCswalUyNGJKCnp6elErMXhDa0dZaWREZ1ZqTFY3SnY3ZjZUU1NSSWdCSXozb2VwemEybExvbFNZQ1JQZXNrNi9tM0xiRUlBSTYKV2xqc1pEbHFMSVBiQVVHcWJxVjlxZ0o4a1lrdHlYRHBlalFoelJHYk5mancxS05xNjgybitTMU01MWI2MS8rRApvMHFscmF1VWhaYWliYWNtZ3hpMisxWmpHTE51WHVsMmsyWHkyZVNkVWRxNW1aSlp1U0JEbWwrbWh3Uy8rUk1XClIzVjIvMVExU3VQZUVNcmo0dEJzQXBtTmh0ZVlZK1ZEaFpBTzNRWExsTDdTSUhVWUc2LzBXSnJZSmk5MFNvNjgKMzB4YS9uZXhMQTJYa0FkcUdDVTh2dz09Cg', + license: 'eyAiYW5kcm9pZElkZW50aWZpZXIiOiBbICJjb20uYW55bGluZSIgXSwgImRlYnVn\nUmVwb3J0aW5nIjogIm9uIiwgImlvc0lkZW50aWZpZXIiOiBbICJjb20uYW55bGlu\nZSIgXSwgImxpY2Vuc2VLZXlWZXJzaW9uIjogMiwgIm1ham9yVmVyc2lvbiI6ICIz\nIiwgInBpbmdSZXBvcnRpbmciOiB0cnVlLCAicGxhdGZvcm0iOiBbICJBbmRyb2lk\nIiwgImlPUyIgXSwgInNjb3BlIjogWyAiQUxMIiBdLCAic2hvd1dhdGVybWFyayI6\nIHRydWUsICJ0b2xlcmFuY2VEYXlzIjogMywgInZhbGlkIjogIjIwMTctMTItMzEi\nIH0KcGNRSXBOU0MzdGZ5QVV1RkRtSEMyMGo0TElXSGVTMnNxRmJybllqOWZDOWZm\nS1ZpaWVGSitLUGZGY2tTWm9YUgpMVmZvWGx2QmZDOVVaaUErZzZtTGNTV3owUVVl\nSkVuRHBGcWJVU0cxVGVBN1NJenR2aU9BOGg2bFlnNXFSZmw0CjQ5d0IvNXVtL2Ir\nUDhHaXRLUzMzaFNacVhTbEdjbnkxYUVRaWxCRjFHL2NCeitIcUFtUEFMaVpBVzFQ\nZDkxdDYKZXZTcU1XdkNtMk01blZUaVNDd2dDZnR6Zkg3WENnQlVCU2hOb2ZoWlFJ\nVCtiUE5ycTE3SGg1YkVWa2ZoUlZBSQpSc0d1YlM4SEpvVlAvaEs5a2FMdzliRWYx\nZXpYZVpVOXFUbCswSXZKUy9lSlBrazJmV0IxcS9CUzM4ZFBVOTZHClpqVXIyRmlQ\nRjNSc1FxRC9UU244Q0E9PQo=', options: { captureResolution: '720p', cutout: { diff --git a/example/Anyline/ios/Anyline.xcodeproj/project.pbxproj b/example/Anyline/ios/Anyline.xcodeproj/project.pbxproj index d7a1aebc..625a9568 100644 --- a/example/Anyline/ios/Anyline.xcodeproj/project.pbxproj +++ b/example/Anyline/ios/Anyline.xcodeproj/project.pbxproj @@ -479,11 +479,11 @@ TargetAttributes = { 00E356ED1AD99517003FC87E = { CreatedOnToolsVersion = 6.2; - DevelopmentTeam = PJL7DA2X5F; + DevelopmentTeam = 35RHL53WRE; TestTargetID = 13B07F861A680F5B00A75B9A; }; 13B07F861A680F5B00A75B9A = { - DevelopmentTeam = PJL7DA2X5F; + DevelopmentTeam = 35RHL53WRE; }; }; }; @@ -749,7 +749,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; D2F1758ED6F41FAEDD8C23EE /* [CP] Embed Pods Frameworks */ = { @@ -814,14 +814,15 @@ isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - DEVELOPMENT_TEAM = PJL7DA2X5F; + DEVELOPMENT_TEAM = 35RHL53WRE; ENABLE_BITCODE = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); + HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/React/**"; INFOPLIST_FILE = AnylineTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -837,10 +838,11 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; - DEVELOPMENT_TEAM = PJL7DA2X5F; + DEVELOPMENT_TEAM = 35RHL53WRE; ENABLE_BITCODE = NO; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/React/**"; INFOPLIST_FILE = AnylineTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -858,8 +860,16 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; - DEVELOPMENT_TEAM = PJL7DA2X5F; + DEVELOPMENT_TEAM = 35RHL53WRE; ENABLE_BITCODE = NO; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/Anyline\"", + "\"${PODS_ROOT}/Headers/Public/AnylineReact\"", + "\"${PODS_ROOT}/Headers/Public/React\"", + "$(SRCROOT)/../node_modules/react-native/React/**", + ); INFOPLIST_FILE = Anyline/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = ( @@ -867,7 +877,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = eon.react.prototype; + PRODUCT_BUNDLE_IDENTIFIER = com.anyline; PRODUCT_NAME = Anyline; VERSIONING_SYSTEM = "apple-generic"; }; @@ -879,8 +889,16 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = PJL7DA2X5F; + DEVELOPMENT_TEAM = 35RHL53WRE; ENABLE_BITCODE = NO; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/Anyline\"", + "\"${PODS_ROOT}/Headers/Public/AnylineReact\"", + "\"${PODS_ROOT}/Headers/Public/React\"", + "$(SRCROOT)/../node_modules/react-native/React/**", + ); INFOPLIST_FILE = Anyline/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = ( @@ -888,7 +906,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = eon.react.prototype; + PRODUCT_BUNDLE_IDENTIFIER = com.anyline; PRODUCT_NAME = Anyline; VERSIONING_SYSTEM = "apple-generic"; }; @@ -928,12 +946,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../node_modules/react-native/React/**", - "$(SRCROOT)/../node_modules/react-native/ReactCommon/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/React/**"; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -968,12 +982,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../node_modules/react-native/React/**", - "$(SRCROOT)/../node_modules/react-native/ReactCommon/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/React/**"; + IPHONEOS_DEPLOYMENT_TARGET = 8.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; diff --git a/example/Anyline/ios/Podfile b/example/Anyline/ios/Podfile index be6323e4..8eafaf08 100644 --- a/example/Anyline/ios/Podfile +++ b/example/Anyline/ios/Podfile @@ -1,3 +1,5 @@ +project 'Anyline.xcodeproj' + target 'Anyline' do pod 'React', subspecs: [ 'RCTActionSheet', diff --git a/example/Anyline/package.json b/example/Anyline/package.json index 838cdf42..efc2f772 100644 --- a/example/Anyline/package.json +++ b/example/Anyline/package.json @@ -1,25 +1,28 @@ { - "name": "anyline-ocr-react-native-module", - "version": "0.0.1", - "main": "index.js", - "scripts": { - "start": "node node_modules/react-native/local-cli/cli.js start", - "reinstall": "rm -rf node_modules/anyline-ocr-react-native-module && npm i && rnpm link", - "reinstall-pods": "cd ios/ && rm -rf Pods Podfile.lock && pod install", - "test": "jest" - }, - "dependencies": { - "react": "15.4.1", - "react-native": "0.39.2", - "anyline-ocr-react-native-module" : "../.." - }, - "devDependencies": { - "babel-jest": "18.0.0", - "babel-preset-react-native": "1.9.1", - "jest": "18.0.0", - "react-test-renderer": "15.4.1" - }, - "jest": { - "preset": "react-native" - } + "name": "anyline-ocr-react-native-module", + "version": "0.0.1", + "main": "index.js", + "scripts": { + "start": "node node_modules/react-native/local-cli/cli.js start", + "reinstall": "rm -rf node_modules/anyline-ocr-react-native-module && npm i && react-native link", + "reinstall-pods": "cd ios/ && rm -rf Pods Podfile.lock && pod install", + "test": "jest" + }, + "dependencies": { + "anyline-ocr-react-native-module": "../..", + "react": "15.4.2", + "react-native": "0.39.2", + "react-native-android-permissions": "0.0.7", + "react-native-permissions": "^0.2.7", + "react-native-vector-icons": "^4.0.0" + }, + "devDependencies": { + "babel-jest": "19.0.0", + "babel-preset-react-native": "1.9.1", + "jest": "19.0.2", + "react-test-renderer": "15.4.2" + }, + "jest": { + "preset": "react-native" + } } diff --git a/example/Anyline/src/index.js b/example/Anyline/src/index.js index 79c9b422..b1409985 100644 --- a/example/Anyline/src/index.js +++ b/example/Anyline/src/index.js @@ -32,7 +32,7 @@ class Anyline extends Component { openOCR = () => { AnylineOCR.setupScanViewWithConfigJson( JSON.stringify(config), - 'ANALOG_METER', + 'DOCUMENT', this.onResult, this.onError ); @@ -42,8 +42,13 @@ class Anyline extends Component { try { - const granted = await PermissionsAndroid.request( - PermissionsAndroid.PERMISSIONS.CAMERA + const granted = await PermissionsAndroid.requestPermission( + PermissionsAndroid.PERMISSIONS.CAMERA, + { + 'title': 'Cool Photo App Camera Permission', + 'message': 'Cool Photo App needs access to your camera ' + + 'so you can take awesome pictures.' + } ); if (granted === PermissionsAndroid.RESULTS.GRANTED) { console.log('Camera permission allowed'); @@ -58,11 +63,9 @@ class Anyline extends Component { hasCameraPermission = async() => { try { - const result = await PermissionsAndroid.check( - PermissionsAndroid.PERMISSIONS.CAMERA); - return result; + return await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.CAMERA); } catch (err) { - console.warn(err); + console.warn(err, 'PERMISSION CHECK'); } }; @@ -79,6 +82,7 @@ class Anyline extends Component { }; onResult = (dataString) => { + console.log(dataString); const data = JSON.parse(dataString); this.setState({ @@ -111,9 +115,9 @@ class Anyline extends Component { fullImageBase64, } = this.state; - const platformText = (Platform.OS === 'android') ? - (Open OCR reader!) : - (Open OCR reader!); + // const platformText = (Platform.OS === 'android') ? + {/*(Open OCR reader!) :*/} + {/*(Open OCR reader!);*/} return ( @@ -128,9 +132,7 @@ class Anyline extends Component { cutoutBase64={cutoutBase64} fullImageBase64={fullImageBase64} /> - ) : ( - platformText - )} + ) : Open OCR reader!} ); }