Full Code of wzx54321/LockDemo for AI

master 92dbd5f47881 cached
161 files
542.1 KB
129.1k tokens
1073 symbols
1 requests
Download .txt
Showing preview only (601K chars total). Download the full file or copy to clipboard to get everything.
Repository: wzx54321/LockDemo
Branch: master
Commit: 92dbd5f47881
Files: 161
Total size: 542.1 KB

Directory structure:
gitextract__z3swy7w/

├── .gitignore
├── LICENSE
├── README.md
├── aliocrlib/
│   ├── .gitignore
│   ├── README.MD
│   ├── build.gradle
│   ├── libs/
│   │   └── BASE64Encoder.jar
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── api14/
│           │   └── cameraview/
│           │       ├── Camera1.java
│           │       └── TextureViewPreview.java
│           ├── api21/
│           │   └── cameraview/
│           │       └── Camera2.java
│           ├── api23/
│           │   └── cameraview/
│           │       └── Camera2Api23.java
│           ├── api9/
│           │   └── cameraview/
│           │       └── SurfaceViewPreview.java
│           ├── base/
│           │   └── cameraview/
│           │       ├── AspectRatio.java
│           │       ├── CameraViewImpl.java
│           │       ├── Constants.java
│           │       ├── PreviewImpl.java
│           │       ├── Size.java
│           │       └── SizeMap.java
│           ├── java/
│           │   ├── cameraview/
│           │   │   ├── CameraView.java
│           │   │   └── DisplayOrientationDetector.java
│           │   └── com/
│           │       └── lib/
│           │           └── aliocr/
│           │               ├── api/
│           │               │   ├── HttpCustomConfig.java
│           │               │   └── MyApiManager.java
│           │               ├── bean/
│           │               │   ├── RepOutput.java
│           │               │   └── ReqInput.java
│           │               ├── callback/
│           │               │   └── OcrCallback.java
│           │               ├── common/
│           │               │   └── Api.java
│           │               ├── contact/
│           │               │   └── OcrContact.java
│           │               ├── http/
│           │               │   ├── config/
│           │               │   │   └── HttpConfig.java
│           │               │   ├── helper/
│           │               │   │   └── HttpHelper.java
│           │               │   ├── https/
│           │               │   │   └── HttpsUtils.java
│           │               │   └── interceptor/
│           │               │       └── HttpLog.java
│           │               ├── modle/
│           │               │   └── OCRModel.java
│           │               ├── presenter/
│           │               │   └── OCRPresenter.java
│           │               ├── utils/
│           │               │   ├── Base64.java
│           │               │   ├── Ocr.java
│           │               │   ├── OcrUtils.java
│           │               │   ├── io/
│           │               │   │   ├── Charsets.java
│           │               │   │   ├── FileUtil.java
│           │               │   │   ├── IOUtils.java
│           │               │   │   ├── SdCardUtil.java
│           │               │   │   └── StringCodingUtils.java
│           │               │   └── stream/
│           │               │       ├── ByteArrayOutputStream.java
│           │               │       ├── ClosedInputStream.java
│           │               │       └── StringBuilderWriter.java
│           │               ├── view/
│           │               │   ├── OCRMainActivity.java
│           │               │   └── OcrLaunchFragment.java
│           │               └── widget/
│           │                   ├── crop/
│           │                   │   ├── Crop.java
│           │                   │   ├── CropImageActivity.java
│           │                   │   ├── CropImageView.java
│           │                   │   ├── CropUtil.java
│           │                   │   ├── HighlightView.java
│           │                   │   ├── ImageViewTouchBase.java
│           │                   │   ├── Log.java
│           │                   │   ├── MonitoredActivity.java
│           │                   │   └── RotateBitmap.java
│           │                   └── popup/
│           │                       └── XinPopWindow.java
│           └── res/
│               ├── anim/
│               │   ├── push_bottom_in.xml
│               │   └── push_bottom_out.xml
│               ├── drawable/
│               │   ├── common_btn_pop_choose_pic_down.xml
│               │   ├── common_btn_pop_choose_pic_mid.xml
│               │   ├── common_btn_pop_choose_pic_up.xml
│               │   ├── crop__selectable_background.xml
│               │   ├── crop__texture.xml
│               │   └── ic_camera.xml
│               ├── drawable-v21/
│               │   └── crop__selectable_background.xml
│               ├── layout/
│               │   ├── activity_ocr_main.xml
│               │   ├── common_item_popup.xml
│               │   ├── common_popwindow.xml
│               │   ├── crop__activity_crop.xml
│               │   ├── crop__layout_done_cancel.xml
│               │   ├── fragment_ocr_launch.xml
│               │   └── surface_view.xml
│               ├── layout-v14/
│               │   └── texture_view.xml
│               └── values/
│                   ├── attrs.xml
│                   ├── colors.xml
│                   ├── dimens.xml
│                   ├── public.xml
│                   ├── strings.xml
│                   └── styles.xml
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── xin/
│           │           └── lockdemo/
│           │               ├── App.java
│           │               ├── GesturePswMainActivity.java
│           │               ├── MainActivity.java
│           │               └── dialog/
│           │                   └── CustomDialog.java
│           └── res/
│               ├── drawable/
│               │   ├── ic_launcher_background.xml
│               │   └── login_shape_bg_finger_change_dialog.xml
│               ├── layout/
│               │   ├── activity_gesture_psw_main.xml
│               │   ├── activity_main.xml
│               │   ├── common_dialog_custom_view_layout.xml
│               │   └── login_finger_change_dialog.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── build.gradle
├── config.gradle
├── fingerprintlib/
│   ├── README.MD
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── lib/
│           │           └── lock/
│           │               └── fingerprint/
│           │                   ├── activities/
│           │                   │   └── FingerprintPswMainActivity.java
│           │                   ├── core/
│           │                   │   ├── CryptoObjectCreator.java
│           │                   │   ├── FingerprintCore.java
│           │                   │   └── MyListener.java
│           │                   ├── dialog/
│           │                   │   └── FingerDialog.java
│           │                   └── utils/
│           │                       ├── FingerContext.java
│           │                       ├── FingerprintUtil.java
│           │                       └── KeyguardLockScreenManager.java
│           └── res/
│               ├── anim/
│               │   ├── anim_shake.xml
│               │   └── cycle.xml
│               ├── drawable/
│               │   └── bg_finger_change_dialog.xml
│               ├── layout/
│               │   ├── activity_fingerprint_psw_main.xml
│               │   ├── finger_dialog_custom_view_layout.xml
│               │   ├── finger_dialog_error.xml
│               │   └── finger_dialog_icon_info.xml
│               └── values/
│                   ├── strings.xml
│                   └── style.xml
├── gesturepswlib/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── lib/
│           │           └── lock/
│           │               └── gesture/
│           │                   ├── activities/
│           │                   │   ├── GestureSettingsActivity.java
│           │                   │   └── GestureVerifyActivity.java
│           │                   ├── bean/
│           │                   │   ├── CellBean.java
│           │                   │   └── CellFactory.java
│           │                   ├── config/
│           │                   │   └── Config.java
│           │                   ├── content/
│           │                   │   ├── DataKeeper.java
│           │                   │   ├── SPManager.java
│           │                   │   ├── SharedPreferencesKeys.java
│           │                   │   └── readme.txt
│           │                   ├── customView/
│           │                   │   ├── DefaultIndicatorHitCellView.java
│           │                   │   ├── DefaultIndicatorLinkedLineView.java
│           │                   │   ├── DefaultIndicatorNormalCellView.java
│           │                   │   ├── DefaultLockerHitCellView.java
│           │                   │   ├── DefaultLockerLinkedLineView.java
│           │                   │   ├── DefaultLockerNormalCellView.java
│           │                   │   ├── DefaultLockerNormalCustomCellView.java
│           │                   │   ├── IHitCellView.java
│           │                   │   ├── IIndicatorLinkedLineView.java
│           │                   │   ├── ILockerLinkedLineView.java
│           │                   │   ├── INormalCellView.java
│           │                   │   ├── OnPatternChangeListener.java
│           │                   │   ├── PatternIndicatorView.java
│           │                   │   └── PatternLockerView.java
│           │                   └── utils/
│           │                       ├── ContextUtils.java
│           │                       ├── PatternHelper.java
│           │                       └── SecurityUtil.java
│           └── res/
│               ├── layout/
│               │   ├── activity_gesture_settings.xml
│               │   └── activity_gesture_verify.xml
│               └── values/
│                   ├── attrs.xml
│                   └── strings.xml
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
.idea/caches
.idea/
# Keystore files
# Uncomment the following line if you do not want to check your keystore files in.
#*.jks

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild

# Google Services (e.g. APIs or Firebase)
google-services.json

# Freeline
freeline.py
freeline/
freeline_project_description.json

# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# LockDemo
封装了:指纹识别、图形密码手势密码识别、aliOCR识别
个人使用,可根据需求添加。

  
 



 <div class='row'>
<img src="https://github.com/wzx54321/LockDemo/blob/master/imgs/take1.gif" title="指纹识别" width="25%" height="25%"/>  
<img src="https://github.com/wzx54321/LockDemo/blob/master/imgs/take2.gif" title="图形密码手势密码识别" width="25%" height="25%"/>  
  </div>
 <div class='row'>
 <img src="https://github.com/wzx54321/LockDemo/blob/master/imgs/take0.gif" title="aliOCR识别" width="25%" height="25%"/>
   
   <img src="https://github.com/wzx54321/LockDemo/blob/master/imgs/take.gif" title="aliOCR识别" width="25%" height="25%"/>
</div>


### Duang!!!轻量级APP开发框架,刚出炉:https://github.com/wzx54321/XinFrameworkLib
## 组件化框架demo请关注:https://github.com/wzx54321/XinframeworkSample   



================================================
FILE: aliocrlib/.gitignore
================================================
/build


================================================
FILE: aliocrlib/README.MD
================================================
## 基于阿里OCR封装的身份证识别功能

================================================
FILE: aliocrlib/build.gradle
================================================
apply plugin: 'com.android.library'

android {
    compileSdkVersion 27



    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"


    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }


    sourceSets {
        main.java.srcDirs += 'src/main/base'
        main.java.srcDirs += 'src/main/api9'
        main.java.srcDirs += 'src/main/api14'
        main.java.srcDirs += 'src/main/api21'
        main.java.srcDirs += 'src/main/api23'

    }

}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    implementation files('libs/BASE64Encoder.jar')
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
}


================================================
FILE: aliocrlib/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: aliocrlib/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lib.aliocr"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET"/>
    <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"/>
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false"/>

    <application>
        <activity android:name=".view.OCRMainActivity">
        </activity>
        <activity android:name=".widget.crop.CropImageActivity"/>

    </application>

</manifest>

================================================
FILE: aliocrlib/src/main/api14/cameraview/Camera1.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.annotation.SuppressLint;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Build;
import android.support.v4.util.SparseArrayCompat;
import android.view.SurfaceHolder;

import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.atomic.AtomicBoolean;


@SuppressWarnings("deprecation")
class Camera1 extends CameraViewImpl {

    private static final int INVALID_CAMERA_ID = -1;

    private static final SparseArrayCompat<String> FLASH_MODES = new SparseArrayCompat<>();

    static {
        FLASH_MODES.put(Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF);
        FLASH_MODES.put(Constants.FLASH_ON, Camera.Parameters.FLASH_MODE_ON);
        FLASH_MODES.put(Constants.FLASH_TORCH, Camera.Parameters.FLASH_MODE_TORCH);
        FLASH_MODES.put(Constants.FLASH_AUTO, Camera.Parameters.FLASH_MODE_AUTO);
        FLASH_MODES.put(Constants.FLASH_RED_EYE, Camera.Parameters.FLASH_MODE_RED_EYE);
    }

    private int mCameraId;

    private final AtomicBoolean isPictureCaptureInProgress = new AtomicBoolean(false);

    Camera mCamera;

    private Camera.Parameters mCameraParameters;

    private final Camera.CameraInfo mCameraInfo = new Camera.CameraInfo();

    private final SizeMap mPreviewSizes = new SizeMap();

    private final SizeMap mPictureSizes = new SizeMap();

    private AspectRatio mAspectRatio;

    private boolean mShowingPreview;

    private boolean mAutoFocus;

    private int mFacing;

    private int mFlash;

    private int mDisplayOrientation;

    Camera1(Callback callback, PreviewImpl preview) {
        super(callback, preview);
        preview.setCallback(new PreviewImpl.Callback() {
            @Override
            public void onSurfaceChanged() {
                if (mCamera != null) {
                    setUpPreview();
                    adjustCameraParameters();
                }
            }
        });
    }

    @Override
    boolean start() {
        chooseCamera();
        openCamera();
        if (mPreview.isReady()) {
            setUpPreview();
        }
        mShowingPreview = true;
        mCamera.startPreview();
        return true;
    }

    @Override
    void stop() {
        if (mCamera != null) {
            mCamera.stopPreview();
        }
        mShowingPreview = false;
        releaseCamera();
    }

    // Suppresses Camera#setPreviewTexture
    @SuppressLint("NewApi")
    void setUpPreview() {
        try {
            if (mPreview.getOutputClass() == SurfaceHolder.class) {
                final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14;
                if (needsToStopPreview) {
                    mCamera.stopPreview();
                }
                mCamera.setPreviewDisplay(mPreview.getSurfaceHolder());
                if (needsToStopPreview) {
                    mCamera.startPreview();
                }
            } else {
                mCamera.setPreviewTexture((SurfaceTexture) mPreview.getSurfaceTexture());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    boolean isCameraOpened() {
        return mCamera != null;
    }

    @Override
    void setFacing(int facing) {
        if (mFacing == facing) {
            return;
        }
        mFacing = facing;
        if (isCameraOpened()) {
            stop();
            start();
        }
    }

    @Override
    int getFacing() {
        return mFacing;
    }

    @Override
    Set<AspectRatio> getSupportedAspectRatios() {
        SizeMap idealAspectRatios = mPreviewSizes;
        for (AspectRatio aspectRatio : idealAspectRatios.ratios()) {
            if (mPictureSizes.sizes(aspectRatio) == null) {
                idealAspectRatios.remove(aspectRatio);
            }
        }
        return idealAspectRatios.ratios();
    }

    @Override
    boolean setAspectRatio(AspectRatio ratio) {
        if (mAspectRatio == null || !isCameraOpened()) {
            // Handle this later when camera is opened
            mAspectRatio = ratio;
            return true;
        } else if (!mAspectRatio.equals(ratio)) {
            final Set<Size> sizes = mPreviewSizes.sizes(ratio);
            if (sizes == null) {
                throw new UnsupportedOperationException(ratio + " is not supported");
            } else {
                mAspectRatio = ratio;
                adjustCameraParameters();
                return true;
            }
        }
        return false;
    }

    @Override
    AspectRatio getAspectRatio() {
        return mAspectRatio;
    }

    @Override
    void setAutoFocus(boolean autoFocus) {
        if (mAutoFocus == autoFocus) {
            return;
        }
        if (setAutoFocusInternal(autoFocus)) {
            mCamera.setParameters(mCameraParameters);
        }
    }

    @Override
    boolean getAutoFocus() {
        if (!isCameraOpened()) {
            return mAutoFocus;
        }
        String focusMode = mCameraParameters.getFocusMode();
        return focusMode != null && focusMode.contains("continuous");
    }

    @Override
    void setFlash(int flash) {
        if (flash == mFlash) {
            return;
        }
        if (setFlashInternal(flash)) {
            mCamera.setParameters(mCameraParameters);
        }
    }

    @Override
    int getFlash() {
        return mFlash;
    }

    @Override
    void takePicture() {
        if (!isCameraOpened()) {
            throw new IllegalStateException(
                    "Camera is not ready. Call start() before takePicture().");
        }
        if (getAutoFocus()) {
            mCamera.cancelAutoFocus();
            mCamera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    takePictureInternal();
                }
            });
        } else {
            takePictureInternal();
        }
    }

    void takePictureInternal() {
        if (!isPictureCaptureInProgress.getAndSet(true)) {
            mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    isPictureCaptureInProgress.set(false);
                    mCallback.onPictureTaken(data);
                    camera.cancelAutoFocus();
                    camera.startPreview();
                }
            });
        }
    }

    @Override
    void setDisplayOrientation(int displayOrientation) {
        if (mDisplayOrientation == displayOrientation) {
            return;
        }
        mDisplayOrientation = displayOrientation;
        if (isCameraOpened()) {
            mCameraParameters.setRotation(calcCameraRotation(displayOrientation));
            mCamera.setParameters(mCameraParameters);
            final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14;
            if (needsToStopPreview) {
                mCamera.stopPreview();
            }
            mCamera.setDisplayOrientation(calcDisplayOrientation(displayOrientation));
            if (needsToStopPreview) {
                mCamera.startPreview();
            }
        }
    }

    /**
     * This rewrites {@link #mCameraId} and {@link #mCameraInfo}.
     */
    private void chooseCamera() {
        for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) {
            Camera.getCameraInfo(i, mCameraInfo);
            if (mCameraInfo.facing == mFacing) {
                mCameraId = i;
                return;
            }
        }
        mCameraId = INVALID_CAMERA_ID;
    }

    private void openCamera() {
        if (mCamera != null) {
            releaseCamera();
        }
        mCamera = Camera.open(mCameraId);
        mCameraParameters = mCamera.getParameters();
        // Supported preview sizes
        mPreviewSizes.clear();
        for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()) {
            mPreviewSizes.add(new Size(size.width, size.height));
        }
        // Supported picture sizes;
        mPictureSizes.clear();
        for (Camera.Size size : mCameraParameters.getSupportedPictureSizes()) {
            mPictureSizes.add(new Size(size.width, size.height));
        }
        // AspectRatio
        if (mAspectRatio == null) {
            mAspectRatio = Constants.DEFAULT_ASPECT_RATIO;
        }
        adjustCameraParameters();
        mCamera.setDisplayOrientation(calcDisplayOrientation(mDisplayOrientation));
        mCallback.onCameraOpened();
    }

    private AspectRatio chooseAspectRatio() {
        AspectRatio r = null;
        for (AspectRatio ratio : mPreviewSizes.ratios()) {
            r = ratio;
            if (ratio.equals(Constants.DEFAULT_ASPECT_RATIO)) {
                return ratio;
            }
        }
        return r;
    }

    void adjustCameraParameters() {
        SortedSet<Size> sizes = mPreviewSizes.sizes(mAspectRatio);
        if (sizes == null) { // Not supported
            mAspectRatio = chooseAspectRatio();
            sizes = mPreviewSizes.sizes(mAspectRatio);
        }
        Size size = chooseOptimalSize(sizes);

        // Always re-apply camera parameters
        // Largest picture size in this ratio
        final Size pictureSize = mPictureSizes.sizes(mAspectRatio).last();
        if (mShowingPreview) {
            mCamera.stopPreview();
        }
        mCameraParameters.setPreviewSize(size.getWidth(), size.getHeight());
        mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
        mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation));
        setAutoFocusInternal(mAutoFocus);
        setFlashInternal(mFlash);
        mCamera.setParameters(mCameraParameters);
        if (mShowingPreview) {
            mCamera.startPreview();
        }
    }

    @SuppressWarnings("SuspiciousNameCombination")
    private Size chooseOptimalSize(SortedSet<Size> sizes) {
        if (!mPreview.isReady()) { // Not yet laid out
            return sizes.first(); // Return the smallest size
        }
        int desiredWidth;
        int desiredHeight;
        final int surfaceWidth = mPreview.getWidth();
        final int surfaceHeight = mPreview.getHeight();
        if (isLandscape(mDisplayOrientation)) {
            desiredWidth = surfaceHeight;
            desiredHeight = surfaceWidth;
        } else {
            desiredWidth = surfaceWidth;
            desiredHeight = surfaceHeight;
        }
        Size result = null;
        for (Size size : sizes) { // Iterate from small to large
            if (desiredWidth <= size.getWidth() && desiredHeight <= size.getHeight()) {
                return size;

            }
            result = size;
        }
        return result;
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
            mCallback.onCameraClosed();
        }
    }

    /**
     * Calculate display orientation
     * https://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
     *
     * This calculation is used for orienting the preview
     *
     * Note: This is not the same calculation as the camera rotation
     *
     * @param screenOrientationDegrees Screen orientation in degrees
     * @return Number of degrees required to rotate preview
     */
    private int calcDisplayOrientation(int screenOrientationDegrees) {
        if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            return (360 - (mCameraInfo.orientation + screenOrientationDegrees) % 360) % 360;
        } else {  // back-facing
            return (mCameraInfo.orientation - screenOrientationDegrees + 360) % 360;
        }
    }

    /**
     * Calculate camera rotation
     *
     * This calculation is applied to the output JPEG either via Exif Orientation tag
     * or by actually transforming the bitmap. (Determined by vendor camera API implementation)
     *
     * Note: This is not the same calculation as the display orientation
     *
     * @param screenOrientationDegrees Screen orientation in degrees
     * @return Number of degrees to rotate image in order for it to view correctly.
     */
    private int calcCameraRotation(int screenOrientationDegrees) {
        if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            return (mCameraInfo.orientation + screenOrientationDegrees) % 360;
        } else {  // back-facing
            final int landscapeFlip = isLandscape(screenOrientationDegrees) ? 180 : 0;
            return (mCameraInfo.orientation + screenOrientationDegrees + landscapeFlip) % 360;
        }
    }

    /**
     * Test if the supplied orientation is in landscape.
     *
     * @param orientationDegrees Orientation in degrees (0,90,180,270)
     * @return True if in landscape, false if portrait
     */
    private boolean isLandscape(int orientationDegrees) {
        return (orientationDegrees == Constants.LANDSCAPE_90 ||
                orientationDegrees == Constants.LANDSCAPE_270);
    }

    /**
     * @return {@code true} if {@link #mCameraParameters} was modified.
     */
    private boolean setAutoFocusInternal(boolean autoFocus) {
        mAutoFocus = autoFocus;
        if (isCameraOpened()) {
            final List<String> modes = mCameraParameters.getSupportedFocusModes();
            if (autoFocus && modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
            } else if (modes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) {
                mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
            } else if (modes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
                mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
            } else {
                mCameraParameters.setFocusMode(modes.get(0));
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return {@code true} if {@link #mCameraParameters} was modified.
     */
    private boolean setFlashInternal(int flash) {
        if (isCameraOpened()) {
            List<String> modes = mCameraParameters.getSupportedFlashModes();
            String mode = FLASH_MODES.get(flash);
            if (modes != null && modes.contains(mode)) {
                mCameraParameters.setFlashMode(mode);
                mFlash = flash;
                return true;
            }
            String currentMode = FLASH_MODES.get(mFlash);
            if (modes == null || !modes.contains(currentMode)) {
                mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                mFlash = Constants.FLASH_OFF;
                return true;
            }
            return false;
        } else {
            mFlash = flash;
            return false;
        }
    }

}


================================================
FILE: aliocrlib/src/main/api14/cameraview/TextureViewPreview.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;

import com.lib.aliocr.R;


@TargetApi(14)
class TextureViewPreview extends PreviewImpl {

    private final TextureView mTextureView;

    private int mDisplayOrientation;

    TextureViewPreview(Context context, ViewGroup parent) {
        final View view = View.inflate(context, R.layout.texture_view, parent);
        mTextureView = view.findViewById(R.id.texture_view);
        mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {

            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                setSize(width, height);
                configureTransform();
                dispatchSurfaceChanged();
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                setSize(width, height);
                configureTransform();
                dispatchSurfaceChanged();
            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                setSize(0, 0);
                return true;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            }
        });
    }

    // This method is called only from Camera2.
    @TargetApi(15)
    @Override
    void setBufferSize(int width, int height) {
        mTextureView.getSurfaceTexture().setDefaultBufferSize(width, height);
    }

    @Override
    Surface getSurface() {
        return new Surface(mTextureView.getSurfaceTexture());
    }

    @Override
    SurfaceTexture getSurfaceTexture() {
        return mTextureView.getSurfaceTexture();
    }

    @Override
    View getView() {
        return mTextureView;
    }

    @Override
    Class getOutputClass() {
        return SurfaceTexture.class;
    }

    @Override
    void setDisplayOrientation(int displayOrientation) {
        mDisplayOrientation = displayOrientation;
        configureTransform();
    }

    @Override
    boolean isReady() {
        return mTextureView.getSurfaceTexture() != null;
    }

    /**
     * Configures the transform matrix for TextureView based on {@link #mDisplayOrientation} and
     * the surface size.
     */
    void configureTransform() {
        Matrix matrix = new Matrix();
        if (mDisplayOrientation % 180 == 90) {
            final int width = getWidth();
            final int height = getHeight();
            // Rotate the camera preview when the screen is landscape.
            matrix.setPolyToPoly(
                    new float[]{
                            0.f, 0.f, // top left
                            width, 0.f, // top right
                            0.f, height, // bottom left
                            width, height, // bottom right
                    }, 0,
                    mDisplayOrientation == 90 ?
                            // Clockwise
                            new float[]{
                                    0.f, height, // top left
                                    0.f, 0.f, // top right
                                    width, height, // bottom left
                                    width, 0.f, // bottom right
                            } : // mDisplayOrientation == 270
                            // Counter-clockwise
                            new float[]{
                                    width, 0.f, // top left
                                    width, height, // top right
                                    0.f, 0.f, // bottom left
                                    0.f, height, // bottom right
                            }, 0,
                    4);
        } else if (mDisplayOrientation == 180) {
            matrix.postRotate(180, getWidth() / 2, getHeight() / 2);
        }
        mTextureView.setTransform(matrix);
    }

}


================================================
FILE: aliocrlib/src/main/api21/cameraview/Camera2.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.support.annotation.NonNull;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Surface;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Set;
import java.util.SortedSet;

@SuppressWarnings("MissingPermission")
@TargetApi(21)
class Camera2 extends CameraViewImpl {

    private static final String TAG = "Camera2";

    private static final SparseIntArray INTERNAL_FACINGS = new SparseIntArray();

    static {
        INTERNAL_FACINGS.put(Constants.FACING_BACK, CameraCharacteristics.LENS_FACING_BACK);
        INTERNAL_FACINGS.put(Constants.FACING_FRONT, CameraCharacteristics.LENS_FACING_FRONT);
    }

    /**
     * Max preview width that is guaranteed by Camera2 API
     */
    private static final int MAX_PREVIEW_WIDTH = 1920;

    /**
     * Max preview height that is guaranteed by Camera2 API
     */
    private static final int MAX_PREVIEW_HEIGHT = 1080;

    private final CameraManager mCameraManager;

    private final CameraDevice.StateCallback mCameraDeviceCallback
            = new CameraDevice.StateCallback() {

        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            mCamera = camera;
            mCallback.onCameraOpened();
            startCaptureSession();
        }

        @Override
        public void onClosed(@NonNull CameraDevice camera) {
            mCallback.onCameraClosed();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            mCamera = null;
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            Log.e(TAG, "onError: " + camera.getId() + " (" + error + ")");
            mCamera = null;
        }

    };

    private final CameraCaptureSession.StateCallback mSessionCallback
            = new CameraCaptureSession.StateCallback() {

        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            if (mCamera == null) {
                return;
            }
            mCaptureSession = session;
            updateAutoFocus();
            updateFlash();
            try {
                mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(),
                        mCaptureCallback, null);
            } catch (CameraAccessException e) {
                Log.e(TAG, "Failed to start camera preview because it couldn't access camera", e);
            } catch (IllegalStateException e) {
                Log.e(TAG, "Failed to start camera preview.", e);
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
            Log.e(TAG, "Failed to configure capture session.");
        }

        @Override
        public void onClosed(@NonNull CameraCaptureSession session) {
            if (mCaptureSession != null && mCaptureSession.equals(session)) {
                mCaptureSession = null;
            }
        }

    };

    PictureCaptureCallback mCaptureCallback = new PictureCaptureCallback() {

        @Override
        public void onPrecaptureRequired() {
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
            setState(STATE_PRECAPTURE);
            try {
                mCaptureSession.capture(mPreviewRequestBuilder.build(), this, null);
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                        CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
            } catch (CameraAccessException e) {
                Log.e(TAG, "Failed to run precapture sequence.", e);
            }
        }

        @Override
        public void onReady() {
            captureStillPicture();
        }

    };

    private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
            = new ImageReader.OnImageAvailableListener() {

        @Override
        public void onImageAvailable(ImageReader reader) {
            try (Image image = reader.acquireNextImage()) {
                Image.Plane[] planes = image.getPlanes();
                if (planes.length > 0) {
                    ByteBuffer buffer = planes[0].getBuffer();
                    byte[] data = new byte[buffer.remaining()];
                    buffer.get(data);
                    mCallback.onPictureTaken(data);
                }
            }
        }

    };


    private String mCameraId;

    private CameraCharacteristics mCameraCharacteristics;

    CameraDevice mCamera;

    CameraCaptureSession mCaptureSession;

    CaptureRequest.Builder mPreviewRequestBuilder;

    private ImageReader mImageReader;

    private final SizeMap mPreviewSizes = new SizeMap();

    private final SizeMap mPictureSizes = new SizeMap();

    private int mFacing;

    private AspectRatio mAspectRatio = Constants.DEFAULT_ASPECT_RATIO;

    private boolean mAutoFocus;

    private int mFlash;

    private int mDisplayOrientation;

    Camera2(Callback callback, PreviewImpl preview, Context context) {
        super(callback, preview);
        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
        mPreview.setCallback(new PreviewImpl.Callback() {
            @Override
            public void onSurfaceChanged() {
                startCaptureSession();
            }
        });
    }

    @Override
    boolean start() {
        if (!chooseCameraIdByFacing()) {
            return false;
        }
        collectCameraInfo();
        prepareImageReader();
        startOpeningCamera();
        return true;
    }

    @Override
    void stop() {
        if (mCaptureSession != null) {
            mCaptureSession.close();
            mCaptureSession = null;
        }
        if (mCamera != null) {
            mCamera.close();
            mCamera = null;
        }
        if (mImageReader != null) {
            mImageReader.close();
            mImageReader = null;
        }
    }

    @Override
    boolean isCameraOpened() {
        return mCamera != null;
    }

    @Override
    void setFacing(int facing) {
        if (mFacing == facing) {
            return;
        }
        mFacing = facing;
        if (isCameraOpened()) {
            stop();
            start();
        }
    }

    @Override
    int getFacing() {
        return mFacing;
    }

    @Override
    Set<AspectRatio> getSupportedAspectRatios() {
        return mPreviewSizes.ratios();
    }

    @Override
    boolean setAspectRatio(AspectRatio ratio) {
        if (ratio == null || ratio.equals(mAspectRatio) ||
                !mPreviewSizes.ratios().contains(ratio)) {
            // TODO: Better error handling
            return false;
        }
        mAspectRatio = ratio;
        prepareImageReader();
        if (mCaptureSession != null) {
            mCaptureSession.close();
            mCaptureSession = null;
            startCaptureSession();
        }
        return true;
    }

    @Override
    AspectRatio getAspectRatio() {
        return mAspectRatio;
    }

    @Override
    void setAutoFocus(boolean autoFocus) {
        if (mAutoFocus == autoFocus) {
            return;
        }
        mAutoFocus = autoFocus;
        if (mPreviewRequestBuilder != null) {
            updateAutoFocus();
            if (mCaptureSession != null) {
                try {
                    mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(),
                            mCaptureCallback, null);
                } catch (CameraAccessException e) {
                    mAutoFocus = !mAutoFocus; // Revert
                }
            }
        }
    }

    @Override
    boolean getAutoFocus() {
        return mAutoFocus;
    }

    @Override
    void setFlash(int flash) {
        if (mFlash == flash) {
            return;
        }
        int saved = mFlash;
        mFlash = flash;
        if (mPreviewRequestBuilder != null) {
            updateFlash();
            if (mCaptureSession != null) {
                try {
                    mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(),
                            mCaptureCallback, null);
                } catch (CameraAccessException e) {
                    mFlash = saved; // Revert
                }
            }
        }
    }

    @Override
    int getFlash() {
        return mFlash;
    }

    @Override
    void takePicture() {
        if (mAutoFocus) {
            lockFocus();
        } else {
            captureStillPicture();
        }
    }

    @Override
    void setDisplayOrientation(int displayOrientation) {
        mDisplayOrientation = displayOrientation;
        mPreview.setDisplayOrientation(mDisplayOrientation);
    }

    /**
     * <p>Chooses a camera ID by the specified camera facing ({@link #mFacing}).</p>
     * <p>This rewrites {@link #mCameraId}, {@link #mCameraCharacteristics}, and optionally
     * {@link #mFacing}.</p>
     */
    private boolean chooseCameraIdByFacing() {
        try {
            int internalFacing = INTERNAL_FACINGS.get(mFacing);
            final String[] ids = mCameraManager.getCameraIdList();
            if (ids.length == 0) { // No camera
                throw new RuntimeException("No camera available.");
            }
            for (String id : ids) {
                CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(id);
                Integer level = characteristics.get(
                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
                if (level == null ||
                        level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
                    continue;
                }
                Integer internal = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (internal == null) {
                    throw new NullPointerException("Unexpected state: LENS_FACING null");
                }
                if (internal == internalFacing) {
                    mCameraId = id;
                    mCameraCharacteristics = characteristics;
                    return true;
                }
            }
            // Not found
            mCameraId = ids[0];
            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId);
            Integer level = mCameraCharacteristics.get(
                    CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
            if (level == null ||
                    level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
                return false;
            }
            Integer internal = mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
            if (internal == null) {
                throw new NullPointerException("Unexpected state: LENS_FACING null");
            }
            for (int i = 0, count = INTERNAL_FACINGS.size(); i < count; i++) {
                if (INTERNAL_FACINGS.valueAt(i) == internal) {
                    mFacing = INTERNAL_FACINGS.keyAt(i);
                    return true;
                }
            }
            // The operation can reach here when the only camera device is an external one.
            // We treat it as facing back.
            mFacing = Constants.FACING_BACK;
            return true;
        } catch (CameraAccessException e) {
            throw new RuntimeException("Failed to get a list of camera devices", e);
        }
    }

    /**
     * <p>Collects some information from {@link #mCameraCharacteristics}.</p>
     * <p>This rewrites {@link #mPreviewSizes}, {@link #mPictureSizes}, and optionally,
     * {@link #mAspectRatio}.</p>
     */
    private void collectCameraInfo() {
        StreamConfigurationMap map = mCameraCharacteristics.get(
                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        if (map == null) {
            throw new IllegalStateException("Failed to get configuration map: " + mCameraId);
        }
        mPreviewSizes.clear();
        for (android.util.Size size : map.getOutputSizes(mPreview.getOutputClass())) {
            int width = size.getWidth();
            int height = size.getHeight();
            if (width <= MAX_PREVIEW_WIDTH && height <= MAX_PREVIEW_HEIGHT) {
                mPreviewSizes.add(new Size(width, height));
            }
        }
        mPictureSizes.clear();
        collectPictureSizes(mPictureSizes, map);
        for (AspectRatio ratio : mPreviewSizes.ratios()) {
            if (!mPictureSizes.ratios().contains(ratio)) {
                mPreviewSizes.remove(ratio);
            }
        }

        if (!mPreviewSizes.ratios().contains(mAspectRatio)) {
            mAspectRatio = mPreviewSizes.ratios().iterator().next();
        }
    }

    protected void collectPictureSizes(SizeMap sizes, StreamConfigurationMap map) {
        for (android.util.Size size : map.getOutputSizes(ImageFormat.JPEG)) {
            mPictureSizes.add(new Size(size.getWidth(), size.getHeight()));
        }
    }

    private void prepareImageReader() {
        if (mImageReader != null) {
            mImageReader.close();
        }
        Size largest = mPictureSizes.sizes(mAspectRatio).last();
        mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                ImageFormat.JPEG, /* maxImages */ 2);
        mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
    }

    /**
     * <p>Starts opening a camera device.</p>
     * <p>The result will be processed in {@link #mCameraDeviceCallback}.</p>
     */
    private void startOpeningCamera() {
        try {
            mCameraManager.openCamera(mCameraId, mCameraDeviceCallback, null);
        } catch (CameraAccessException e) {
            throw new RuntimeException("Failed to open camera: " + mCameraId, e);
        }
    }

    /**
     * <p>Starts a capture session for camera preview.</p>
     * <p>This rewrites {@link #mPreviewRequestBuilder}.</p>
     * <p>The result will be continuously processed in {@link #mSessionCallback}.</p>
     */
    void startCaptureSession() {
        if (!isCameraOpened() || !mPreview.isReady() || mImageReader == null) {
            return;
        }
        Size previewSize = chooseOptimalSize();
        mPreview.setBufferSize(previewSize.getWidth(), previewSize.getHeight());
        Surface surface = mPreview.getSurface();
        try {
            mPreviewRequestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mPreviewRequestBuilder.addTarget(surface);
            mCamera.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                    mSessionCallback, null);
        } catch (CameraAccessException e) {
            throw new RuntimeException("Failed to start camera session");
        }
    }

    /**
     * Chooses the optimal preview size based on {@link #mPreviewSizes} and the surface size.
     *
     * @return The picked size for camera preview.
     */
    private Size chooseOptimalSize() {
        int surfaceLonger, surfaceShorter;
        final int surfaceWidth = mPreview.getWidth();
        final int surfaceHeight = mPreview.getHeight();
        if (surfaceWidth < surfaceHeight) {
            surfaceLonger = surfaceHeight;
            surfaceShorter = surfaceWidth;
        } else {
            surfaceLonger = surfaceWidth;
            surfaceShorter = surfaceHeight;
        }
        SortedSet<Size> candidates = mPreviewSizes.sizes(mAspectRatio);

        // Pick the smallest of those big enough
        for (Size size : candidates) {
            if (size.getWidth() >= surfaceLonger && size.getHeight() >= surfaceShorter) {
                return size;
            }
        }
        // If no size is big enough, pick the largest one.
        return candidates.last();
    }

    /**
     * Updates the internal state of auto-focus to {@link #mAutoFocus}.
     */
    void updateAutoFocus() {
        if (mAutoFocus) {
            int[] modes = mCameraCharacteristics.get(
                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
            // Auto focus is not supported
            if (modes == null || modes.length == 0 ||
                    (modes.length == 1 && modes[0] == CameraCharacteristics.CONTROL_AF_MODE_OFF)) {
                mAutoFocus = false;
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                        CaptureRequest.CONTROL_AF_MODE_OFF);
            } else {
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            }
        } else {
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_OFF);
        }
    }

    /**
     * Updates the internal state of flash to {@link #mFlash}.
     */
    void updateFlash() {
        switch (mFlash) {
            case Constants.FLASH_OFF:
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                        CaptureRequest.CONTROL_AE_MODE_ON);
                mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                        CaptureRequest.FLASH_MODE_OFF);
                break;
            case Constants.FLASH_ON:
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                        CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
                mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                        CaptureRequest.FLASH_MODE_OFF);
                break;
            case Constants.FLASH_TORCH:
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                        CaptureRequest.CONTROL_AE_MODE_ON);
                mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                        CaptureRequest.FLASH_MODE_TORCH);
                break;
            case Constants.FLASH_AUTO:
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                        CaptureRequest.FLASH_MODE_OFF);
                break;
            case Constants.FLASH_RED_EYE:
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE);
                mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                        CaptureRequest.FLASH_MODE_OFF);
                break;
        }
    }

    /**
     * Locks the focus as the first step for a still image capture.
     */
    private void lockFocus() {
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                CaptureRequest.CONTROL_AF_TRIGGER_START);
        try {
            mCaptureCallback.setState(PictureCaptureCallback.STATE_LOCKING);
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, null);
        } catch (CameraAccessException e) {
            Log.e(TAG, "Failed to lock focus.", e);
        }
    }

    /**
     * Captures a still picture.
     */
    void captureStillPicture() {
        try {
            CaptureRequest.Builder captureRequestBuilder = mCamera.createCaptureRequest(
                    CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureRequestBuilder.addTarget(mImageReader.getSurface());
            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    mPreviewRequestBuilder.get(CaptureRequest.CONTROL_AF_MODE));
            switch (mFlash) {
                case Constants.FLASH_OFF:
                    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                            CaptureRequest.CONTROL_AE_MODE_ON);
                    captureRequestBuilder.set(CaptureRequest.FLASH_MODE,
                            CaptureRequest.FLASH_MODE_OFF);
                    break;
                case Constants.FLASH_ON:
                    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                            CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
                    break;
                case Constants.FLASH_TORCH:
                    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                            CaptureRequest.CONTROL_AE_MODE_ON);
                    captureRequestBuilder.set(CaptureRequest.FLASH_MODE,
                            CaptureRequest.FLASH_MODE_TORCH);
                    break;
                case Constants.FLASH_AUTO:
                    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                            CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                    break;
                case Constants.FLASH_RED_EYE:
                    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                            CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                    break;
            }
            // Calculate JPEG orientation.
            @SuppressWarnings("ConstantConditions")
            int sensorOrientation = mCameraCharacteristics.get(
                    CameraCharacteristics.SENSOR_ORIENTATION);
            captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,
                    (sensorOrientation +
                            mDisplayOrientation * (mFacing == Constants.FACING_FRONT ? 1 : -1) +
                            360) % 360);
            // Stop preview and capture a still picture.
            mCaptureSession.stopRepeating();
            mCaptureSession.capture(captureRequestBuilder.build(),
                    new CameraCaptureSession.CaptureCallback() {
                        @Override
                        public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                @NonNull CaptureRequest request,
                                @NonNull TotalCaptureResult result) {
                            unlockFocus();
                        }
                    }, null);
        } catch (CameraAccessException e) {
            Log.e(TAG, "Cannot capture a still picture.", e);
        }
    }

    /**
     * Unlocks the auto-focus and restart camera preview. This is supposed to be called after
     * capturing a still picture.
     */
    void unlockFocus() {
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
        try {
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, null);
            updateAutoFocus();
            updateFlash();
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
            mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
                    null);
            mCaptureCallback.setState(PictureCaptureCallback.STATE_PREVIEW);
        } catch (CameraAccessException e) {
            Log.e(TAG, "Failed to restart camera preview.", e);
        }
    }

    /**
     * A {@link CameraCaptureSession.CaptureCallback} for capturing a still picture.
     */
    private static abstract class PictureCaptureCallback
            extends CameraCaptureSession.CaptureCallback {

        static final int STATE_PREVIEW = 0;
        static final int STATE_LOCKING = 1;
        static final int STATE_LOCKED = 2;
        static final int STATE_PRECAPTURE = 3;
        static final int STATE_WAITING = 4;
        static final int STATE_CAPTURING = 5;

        private int mState;

        PictureCaptureCallback() {
        }

        void setState(int state) {
            mState = state;
        }

        @Override
        public void onCaptureProgressed(@NonNull CameraCaptureSession session,
                @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
            process(partialResult);
        }

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
            process(result);
        }

        private void process(@NonNull CaptureResult result) {
            switch (mState) {
                case STATE_LOCKING: {
                    Integer af = result.get(CaptureResult.CONTROL_AF_STATE);
                    if (af == null) {
                        break;
                    }
                    if (af == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
                            af == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
                        Integer ae = result.get(CaptureResult.CONTROL_AE_STATE);
                        if (ae == null || ae == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                            setState(STATE_CAPTURING);
                            onReady();
                        } else {
                            setState(STATE_LOCKED);
                            onPrecaptureRequired();
                        }
                    }
                    break;
                }
                case STATE_PRECAPTURE: {
                    Integer ae = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (ae == null || ae == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
                            ae == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED ||
                            ae == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                        setState(STATE_WAITING);
                    }
                    break;
                }
                case STATE_WAITING: {
                    Integer ae = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (ae == null || ae != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
                        setState(STATE_CAPTURING);
                        onReady();
                    }
                    break;
                }
            }
        }

        /**
         * Called when it is ready to take a still picture.
         */
        public abstract void onReady();

        /**
         * Called when it is necessary to run the precapture sequence.
         */
        public abstract void onPrecaptureRequired();

    }

}


================================================
FILE: aliocrlib/src/main/api23/cameraview/Camera2Api23.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.camera2.params.StreamConfigurationMap;


@TargetApi(23)
class Camera2Api23 extends Camera2 {

    Camera2Api23(Callback callback, PreviewImpl preview, Context context) {
        super(callback, preview, context);
    }

    @Override
    protected void collectPictureSizes(SizeMap sizes, StreamConfigurationMap map) {
        // Try to get hi-res output sizes
        android.util.Size[] outputSizes = map.getHighResolutionOutputSizes(ImageFormat.JPEG);
        if (outputSizes != null) {
            for (android.util.Size size : map.getHighResolutionOutputSizes(ImageFormat.JPEG)) {
                sizes.add(new Size(size.getWidth(), size.getHeight()));
            }
        }
        if (sizes.isEmpty()) {
            super.collectPictureSizes(sizes, map);
        }
    }

}


================================================
FILE: aliocrlib/src/main/api9/cameraview/SurfaceViewPreview.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;

import com.lib.aliocr.R;

class SurfaceViewPreview extends PreviewImpl {

    final SurfaceView mSurfaceView;

    SurfaceViewPreview(Context context, ViewGroup parent) {
        final View view = View.inflate(context, R.layout.surface_view, parent);
        mSurfaceView = view.findViewById(R.id.surface_view);
        final SurfaceHolder holder = mSurfaceView.getHolder();
        //noinspection deprecation
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder h) {
            }

            @Override
            public void surfaceChanged(SurfaceHolder h, int format, int width, int height) {
                setSize(width, height);
                if (!ViewCompat.isInLayout(mSurfaceView)) {
                    dispatchSurfaceChanged();
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder h) {
                setSize(0, 0);
            }
        });
    }

    @Override
    Surface getSurface() {
        return getSurfaceHolder().getSurface();
    }

    @Override
    SurfaceHolder getSurfaceHolder() {
        return mSurfaceView.getHolder();
    }

    @Override
    View getView() {
        return mSurfaceView;
    }

    @Override
    Class getOutputClass() {
        return SurfaceHolder.class;
    }

    @Override
    void setDisplayOrientation(int displayOrientation) {
    }

    @Override
    boolean isReady() {
        return getWidth() != 0 && getHeight() != 0;
    }

}


================================================
FILE: aliocrlib/src/main/base/cameraview/AspectRatio.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.v4.util.SparseArrayCompat;

/**
 * Immutable class for describing proportional relationship between width and height.
 */
public class AspectRatio implements Comparable<AspectRatio>, Parcelable {

    private final static SparseArrayCompat<SparseArrayCompat<AspectRatio>> sCache
            = new SparseArrayCompat<>(16);

    private final int mX;
    private final int mY;

    /**
     * Returns an instance of {@link AspectRatio} specified by {@code x} and {@code y} values.
     * The values {@code x} and {@code} will be reduced by their greatest common divider.
     *
     * @param x The width
     * @param y The height
     * @return An instance of {@link AspectRatio}
     */
    public static AspectRatio of(int x, int y) {
        int gcd = gcd(x, y);
        x /= gcd;
        y /= gcd;
        SparseArrayCompat<AspectRatio> arrayX = sCache.get(x);
        if (arrayX == null) {
            AspectRatio ratio = new AspectRatio(x, y);
            arrayX = new SparseArrayCompat<>();
            arrayX.put(y, ratio);
            sCache.put(x, arrayX);
            return ratio;
        } else {
            AspectRatio ratio = arrayX.get(y);
            if (ratio == null) {
                ratio = new AspectRatio(x, y);
                arrayX.put(y, ratio);
            }
            return ratio;
        }
    }

    /**
     * Parse an {@link AspectRatio} from a {@link String} formatted like "4:3".
     *
     * @param s The string representation of the aspect ratio
     * @return The aspect ratio
     * @throws IllegalArgumentException when the format is incorrect.
     */
    public static AspectRatio parse(String s) {
        int position = s.indexOf(':');
        if (position == -1) {
            throw new IllegalArgumentException("Malformed aspect ratio: " + s);
        }
        try {
            int x = Integer.parseInt(s.substring(0, position));
            int y = Integer.parseInt(s.substring(position + 1));
            return AspectRatio.of(x, y);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Malformed aspect ratio: " + s, e);
        }
    }

    private AspectRatio(int x, int y) {
        mX = x;
        mY = y;
    }

    public int getX() {
        return mX;
    }

    public int getY() {
        return mY;
    }

    public boolean matches(Size size) {
        int gcd = gcd(size.getWidth(), size.getHeight());
        int x = size.getWidth() / gcd;
        int y = size.getHeight() / gcd;
        return mX == x && mY == y;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true;
        }
        if (o instanceof AspectRatio) {
            AspectRatio ratio = (AspectRatio) o;
            return mX == ratio.mX && mY == ratio.mY;
        }
        return false;
    }

    @Override
    public String toString() {
        return mX + ":" + mY;
    }

    public float toFloat() {
        return (float) mX / mY;
    }

    @Override
    public int hashCode() {
        // assuming most sizes are <2^16, doing a rotate will give us perfect hashing
        return mY ^ ((mX << (Integer.SIZE / 2)) | (mX >>> (Integer.SIZE / 2)));
    }

    @Override
    public int compareTo(@NonNull AspectRatio another) {
        if (equals(another)) {
            return 0;
        } else if (toFloat() - another.toFloat() > 0) {
            return 1;
        }
        return -1;
    }

    /**
     * @return The inverse of this {@link AspectRatio}.
     */
    public AspectRatio inverse() {
        //noinspection SuspiciousNameCombination
        return AspectRatio.of(mY, mX);
    }

    private static int gcd(int a, int b) {
        while (b != 0) {
            int c = b;
            b = a % b;
            a = c;
        }
        return a;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mX);
        dest.writeInt(mY);
    }

    public static final Parcelable.Creator<AspectRatio> CREATOR
            = new Parcelable.Creator<AspectRatio>() {

        @Override
        public AspectRatio createFromParcel(Parcel source) {
            int x = source.readInt();
            int y = source.readInt();
            return AspectRatio.of(x, y);
        }

        @Override
        public AspectRatio[] newArray(int size) {
            return new AspectRatio[size];
        }
    };

}


================================================
FILE: aliocrlib/src/main/base/cameraview/CameraViewImpl.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.view.View;

import java.util.Set;

abstract class CameraViewImpl {

    protected final Callback mCallback;

    protected final PreviewImpl mPreview;

    CameraViewImpl(Callback callback, PreviewImpl preview) {
        mCallback = callback;
        mPreview = preview;
    }

    View getView() {
        return mPreview.getView();
    }

    /**
     * @return {@code true} if the implementation was able to start the camera session.
     */
    abstract boolean start();

    abstract void stop();

    abstract boolean isCameraOpened();

    abstract void setFacing(int facing);

    abstract int getFacing();

    abstract Set<AspectRatio> getSupportedAspectRatios();

    /**
     * @return {@code true} if the aspect ratio was changed.
     */
    abstract boolean setAspectRatio(AspectRatio ratio);

    abstract AspectRatio getAspectRatio();

    abstract void setAutoFocus(boolean autoFocus);

    abstract boolean getAutoFocus();

    abstract void setFlash(int flash);

    abstract int getFlash();

    abstract void takePicture();

    abstract void setDisplayOrientation(int displayOrientation);

    interface Callback {

        void onCameraOpened();

        void onCameraClosed();

        void onPictureTaken(byte[] data);

    }

}


================================================
FILE: aliocrlib/src/main/base/cameraview/Constants.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;


public interface Constants {

    AspectRatio DEFAULT_ASPECT_RATIO = AspectRatio.of(4, 3);

    int FACING_BACK = 0;
    int FACING_FRONT = 1;

    int FLASH_OFF = 0;
    int FLASH_ON = 1;
    int FLASH_TORCH = 2;
    int FLASH_AUTO = 3;
    int FLASH_RED_EYE = 4;

    int LANDSCAPE_90 = 90;
    int LANDSCAPE_270 = 270;
}


================================================
FILE: aliocrlib/src/main/base/cameraview/PreviewImpl.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;


/**
 * Encapsulates all the operations related to camera preview in a backward-compatible manner.
 */
abstract class PreviewImpl {

    interface Callback {
        void onSurfaceChanged();
    }

    private Callback mCallback;

    private int mWidth;

    private int mHeight;

    void setCallback(Callback callback) {
        mCallback = callback;
    }

    abstract Surface getSurface();

    abstract View getView();

    abstract Class getOutputClass();

    abstract void setDisplayOrientation(int displayOrientation);

    abstract boolean isReady();

    protected void dispatchSurfaceChanged() {
        mCallback.onSurfaceChanged();
    }

    SurfaceHolder getSurfaceHolder() {
        return null;
    }

    Object getSurfaceTexture() {
        return null;
    }

    void setBufferSize(int width, int height) {
    }

    void setSize(int width, int height) {
        mWidth = width;
        mHeight = height;
    }

    int getWidth() {
        return mWidth;
    }

    int getHeight() {
        return mHeight;
    }

}


================================================
FILE: aliocrlib/src/main/base/cameraview/Size.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.support.annotation.NonNull;

/**
 * Immutable class for describing width and height dimensions in pixels.
 */
public class Size implements Comparable<Size> {

    private final int mWidth;
    private final int mHeight;

    /**
     * Create a new immutable Size instance.
     *
     * @param width  The width of the size, in pixels
     * @param height The height of the size, in pixels
     */
    public Size(int width, int height) {
        mWidth = width;
        mHeight = height;
    }

    public int getWidth() {
        return mWidth;
    }

    public int getHeight() {
        return mHeight;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true;
        }
        if (o instanceof Size) {
            Size size = (Size) o;
            return mWidth == size.mWidth && mHeight == size.mHeight;
        }
        return false;
    }

    @Override
    public String toString() {
        return mWidth + "x" + mHeight;
    }

    @Override
    public int hashCode() {
        // assuming most sizes are <2^16, doing a rotate will give us perfect hashing
        return mHeight ^ ((mWidth << (Integer.SIZE / 2)) | (mWidth >>> (Integer.SIZE / 2)));
    }

    @Override
    public int compareTo(@NonNull Size another) {
        return mWidth * mHeight - another.mWidth * another.mHeight;
    }

}


================================================
FILE: aliocrlib/src/main/base/cameraview/SizeMap.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.support.v4.util.ArrayMap;

import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * A collection class that automatically groups {@link Size}s by their {@link AspectRatio}s.
 */
class SizeMap {

    private final ArrayMap<AspectRatio, SortedSet<Size>> mRatios = new ArrayMap<>();

    /**
     * Add a new {@link Size} to this collection.
     *
     * @param size The size to add.
     * @return {@code true} if it is added, {@code false} if it already exists and is not added.
     */
    public boolean add(Size size) {
        for (AspectRatio ratio : mRatios.keySet()) {
            if (ratio.matches(size)) {
                final SortedSet<Size> sizes = mRatios.get(ratio);
                if (sizes.contains(size)) {
                    return false;
                } else {
                    sizes.add(size);
                    return true;
                }
            }
        }
        // None of the existing ratio matches the provided size; add a new key
        SortedSet<Size> sizes = new TreeSet<>();
        sizes.add(size);
        mRatios.put(AspectRatio.of(size.getWidth(), size.getHeight()), sizes);
        return true;
    }

    /**
     * Removes the specified aspect ratio and all sizes associated with it.
     *
     * @param ratio The aspect ratio to be removed.
     */
    public void remove(AspectRatio ratio) {
        mRatios.remove(ratio);
    }

    Set<AspectRatio> ratios() {
        return mRatios.keySet();
    }

    SortedSet<Size> sizes(AspectRatio ratio) {
        return mRatios.get(ratio);
    }

    void clear() {
        mRatios.clear();
    }

    boolean isEmpty() {
        return mRatios.isEmpty();
    }

}


================================================
FILE: aliocrlib/src/main/java/cameraview/CameraView.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.os.ParcelableCompat;
import android.support.v4.os.ParcelableCompatCreatorCallbacks;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.widget.FrameLayout;

import com.lib.aliocr.R;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Set;

public class CameraView extends FrameLayout {

    /** The camera device faces the opposite direction as the device's screen. */
    public static final int FACING_BACK = Constants.FACING_BACK;

    /** The camera device faces the same direction as the device's screen. */
    public static final int FACING_FRONT = Constants.FACING_FRONT;

    /** Direction the camera faces relative to device screen. */
    @IntDef({FACING_BACK, FACING_FRONT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Facing {
    }

    /** Flash will not be fired. */
    public static final int FLASH_OFF = Constants.FLASH_OFF;

    /** Flash will always be fired during snapshot. */
    public static final int FLASH_ON = Constants.FLASH_ON;

    /** Constant emission of light during preview, auto-focus and snapshot. */
    public static final int FLASH_TORCH = Constants.FLASH_TORCH;

    /** Flash will be fired automatically when required. */
    public static final int FLASH_AUTO = Constants.FLASH_AUTO;

    /** Flash will be fired in red-eye reduction mode. */
    public static final int FLASH_RED_EYE = Constants.FLASH_RED_EYE;

    /** The mode for for the camera device's flash control */
    @IntDef({FLASH_OFF, FLASH_ON, FLASH_TORCH, FLASH_AUTO, FLASH_RED_EYE})
    public @interface Flash {
    }

    CameraViewImpl mImpl;

    private final CallbackBridge mCallbacks;

    private boolean mAdjustViewBounds;

    private final DisplayOrientationDetector mDisplayOrientationDetector;

    public CameraView(Context context) {
        this(context, null);
    }

    public CameraView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @SuppressWarnings("WrongConstant")
    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (isInEditMode()){
            mCallbacks = null;
            mDisplayOrientationDetector = null;
            return;
        }
        // Internal setup
        final PreviewImpl preview = createPreviewImpl(context);
        mCallbacks = new CallbackBridge();
        if (Build.VERSION.SDK_INT < 21) {
            mImpl = new Camera1(mCallbacks, preview);
        } else if (Build.VERSION.SDK_INT < 23) {
            mImpl = new Camera2(mCallbacks, preview, context);
        } else {
            mImpl = new Camera2Api23(mCallbacks, preview, context);
        }
        // Attributes
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView, defStyleAttr,
                R.style.Widget_CameraView);
        mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, false);
        setFacing(a.getInt(R.styleable.CameraView_facing, FACING_BACK));
        String aspectRatio = a.getString(R.styleable.CameraView_aspectRatio);
        if (aspectRatio != null) {
            setAspectRatio(AspectRatio.parse(aspectRatio));
        } else {
            setAspectRatio(Constants.DEFAULT_ASPECT_RATIO);
        }
        setAutoFocus(a.getBoolean(R.styleable.CameraView_autoFocus, true));
        setFlash(a.getInt(R.styleable.CameraView_flash, Constants.FLASH_AUTO));
        a.recycle();
        // Display orientation detector
        mDisplayOrientationDetector = new DisplayOrientationDetector(context) {
            @Override
            public void onDisplayOrientationChanged(int displayOrientation) {
                mImpl.setDisplayOrientation(displayOrientation);
            }
        };
    }

    @NonNull
    private PreviewImpl createPreviewImpl(Context context) {
        PreviewImpl preview;
        if (Build.VERSION.SDK_INT < 14) {
            preview = new SurfaceViewPreview(context, this);
        } else {
            preview = new TextureViewPreview(context, this);
        }
        return preview;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (!isInEditMode()) {
            mDisplayOrientationDetector.enable(ViewCompat.getDisplay(this));
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        if (!isInEditMode()) {
            mDisplayOrientationDetector.disable();
        }
        super.onDetachedFromWindow();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (isInEditMode()){
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        // Handle android:adjustViewBounds
        if (mAdjustViewBounds) {
            if (!isCameraOpened()) {
                mCallbacks.reserveRequestLayoutOnOpen();
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                return;
            }
            final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
                final AspectRatio ratio = getAspectRatio();
                assert ratio != null;
                int height = (int) (MeasureSpec.getSize(widthMeasureSpec) * ratio.toFloat());
                if (heightMode == MeasureSpec.AT_MOST) {
                    height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec));
                }
                super.onMeasure(widthMeasureSpec,
                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
            } else if (widthMode != MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
                final AspectRatio ratio = getAspectRatio();
                assert ratio != null;
                int width = (int) (MeasureSpec.getSize(heightMeasureSpec) * ratio.toFloat());
                if (widthMode == MeasureSpec.AT_MOST) {
                    width = Math.min(width, MeasureSpec.getSize(widthMeasureSpec));
                }
                super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                        heightMeasureSpec);
            } else {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
        // Measure the TextureView
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        AspectRatio ratio = getAspectRatio();
        if (mDisplayOrientationDetector.getLastKnownDisplayOrientation() % 180 == 0) {
            ratio = ratio.inverse();
        }
        assert ratio != null;
        if (height < width * ratio.getY() / ratio.getX()) {
            mImpl.getView().measure(
                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(width * ratio.getY() / ratio.getX(),
                            MeasureSpec.EXACTLY));
        } else {
            mImpl.getView().measure(
                    MeasureSpec.makeMeasureSpec(height * ratio.getX() / ratio.getY(),
                            MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
        }
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        SavedState state = new SavedState(super.onSaveInstanceState());
        state.facing = getFacing();
        state.ratio = getAspectRatio();
        state.autoFocus = getAutoFocus();
        state.flash = getFlash();
        return state;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        setFacing(ss.facing);
        setAspectRatio(ss.ratio);
        setAutoFocus(ss.autoFocus);
        setFlash(ss.flash);
    }

    /**
     * Open a camera device and start showing camera preview. This is typically called from
     * {@link Activity#onResume()}.
     */
    public void start() {
        if (!mImpl.start()) {
            //store the state ,and restore this state after fall back o Camera1
            Parcelable state=onSaveInstanceState();
            // Camera2 uses legacy hardware layer; fall back to Camera1
            mImpl = new Camera1(mCallbacks, createPreviewImpl(getContext()));
            onRestoreInstanceState(state);
            mImpl.start();
        }
    }

    /**
     * Stop camera preview and close the device. This is typically called from
     * {@link Activity#onPause()}.
     */
    public void stop() {
        mImpl.stop();
    }

    /**
     * @return {@code true} if the camera is opened.
     */
    public boolean isCameraOpened() {
        return mImpl.isCameraOpened();
    }

    /**
     * Add a new callback.
     *
     * @param callback The {@link Callback} to add.
     * @see #removeCallback(Callback)
     */
    public void addCallback(@NonNull Callback callback) {
        mCallbacks.add(callback);
    }

    /**
     * Remove a callback.
     *
     * @param callback The {@link Callback} to remove.
     * @see #addCallback(Callback)
     */
    public void removeCallback(@NonNull Callback callback) {
        mCallbacks.remove(callback);
    }

    /**
     * @param adjustViewBounds {@code true} if you want the CameraView to adjust its bounds to
     *                         preserve the aspect ratio of camera.
     * @see #getAdjustViewBounds()
     */
    public void setAdjustViewBounds(boolean adjustViewBounds) {
        if (mAdjustViewBounds != adjustViewBounds) {
            mAdjustViewBounds = adjustViewBounds;
            requestLayout();
        }
    }

    /**
     * @return True when this CameraView is adjusting its bounds to preserve the aspect ratio of
     * camera.
     * @see #setAdjustViewBounds(boolean)
     */
    public boolean getAdjustViewBounds() {
        return mAdjustViewBounds;
    }

    /**
     * Chooses camera by the direction it faces.
     *
     * @param facing The camera facing. Must be either {@link #FACING_BACK} or
     *               {@link #FACING_FRONT}.
     */
    public void setFacing(@Facing int facing) {
        mImpl.setFacing(facing);
    }

    /**
     * Gets the direction that the current camera faces.
     *
     * @return The camera facing.
     */
    @Facing
    public int getFacing() {
        //noinspection WrongConstant
        return mImpl.getFacing();
    }

    /**
     * Gets all the aspect ratios supported by the current camera.
     */
    public Set<AspectRatio> getSupportedAspectRatios() {
        return mImpl.getSupportedAspectRatios();
    }

    /**
     * Sets the aspect ratio of camera.
     *
     * @param ratio The {@link AspectRatio} to be set.
     */
    public void setAspectRatio(@NonNull AspectRatio ratio) {
        if (mImpl.setAspectRatio(ratio)) {
            requestLayout();
        }
    }

    /**
     * Gets the current aspect ratio of camera.
     *
     * @return The current {@link AspectRatio}. Can be {@code null} if no camera is opened yet.
     */
    @Nullable
    public AspectRatio getAspectRatio() {
        return mImpl.getAspectRatio();
    }

    /**
     * Enables or disables the continuous auto-focus mode. When the current camera doesn't support
     * auto-focus, calling this method will be ignored.
     *
     * @param autoFocus {@code true} to enable continuous auto-focus mode. {@code false} to
     *                  disable it.
     */
    public void setAutoFocus(boolean autoFocus) {
        mImpl.setAutoFocus(autoFocus);
    }

    /**
     * Returns whether the continuous auto-focus mode is enabled.
     *
     * @return {@code true} if the continuous auto-focus mode is enabled. {@code false} if it is
     * disabled, or if it is not supported by the current camera.
     */
    public boolean getAutoFocus() {
        return mImpl.getAutoFocus();
    }

    /**
     * Sets the flash mode.
     *
     * @param flash The desired flash mode.
     */
    public void setFlash(@Flash int flash) {
        mImpl.setFlash(flash);
    }

    /**
     * Gets the current flash mode.
     *
     * @return The current flash mode.
     */
    @Flash
    public int getFlash() {
        //noinspection WrongConstant
        return mImpl.getFlash();
    }

    /**
     * Take a picture. The result will be returned to
     * {@link Callback#onPictureTaken(CameraView, byte[])}.
     */
    public void takePicture() {
        mImpl.takePicture();
    }

    private class CallbackBridge implements CameraViewImpl.Callback {

        private final ArrayList<Callback> mCallbacks = new ArrayList<>();

        private boolean mRequestLayoutOnOpen;

        CallbackBridge() {
        }

        public void add(Callback callback) {
            mCallbacks.add(callback);
        }

        public void remove(Callback callback) {
            mCallbacks.remove(callback);
        }

        @Override
        public void onCameraOpened() {
            if (mRequestLayoutOnOpen) {
                mRequestLayoutOnOpen = false;
                requestLayout();
            }
            for (Callback callback : mCallbacks) {
                callback.onCameraOpened(CameraView.this);
            }
        }

        @Override
        public void onCameraClosed() {
            for (Callback callback : mCallbacks) {
                callback.onCameraClosed(CameraView.this);
            }
        }

        @Override
        public void onPictureTaken(byte[] data) {
            for (Callback callback : mCallbacks) {
                callback.onPictureTaken(CameraView.this, data);
            }
        }

        public void reserveRequestLayoutOnOpen() {
            mRequestLayoutOnOpen = true;
        }
    }

    protected static class SavedState extends BaseSavedState {

        @Facing
        int facing;

        AspectRatio ratio;

        boolean autoFocus;

        @Flash
        int flash;

        @SuppressWarnings("WrongConstant")
        public SavedState(Parcel source, ClassLoader loader) {
            super(source);
            facing = source.readInt();
            ratio = source.readParcelable(loader);
            autoFocus = source.readByte() != 0;
            flash = source.readInt();
        }

        public SavedState(Parcelable superState) {
            super(superState);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeInt(facing);
            out.writeParcelable(ratio, 0);
            out.writeByte((byte) (autoFocus ? 1 : 0));
            out.writeInt(flash);
        }

        public static final Parcelable.Creator<SavedState> CREATOR
                = ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks<SavedState>() {

            @Override
            public SavedState createFromParcel(Parcel in, ClassLoader loader) {
                return new SavedState(in, loader);
            }

            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }

        });

    }

    /**
     * Callback for monitoring events about {@link CameraView}.
     */
    @SuppressWarnings("UnusedParameters")
    public abstract static class Callback {

        /**
         * Called when camera is opened.
         *
         * @param cameraView The associated {@link CameraView}.
         */
        public void onCameraOpened(CameraView cameraView) {
        }

        /**
         * Called when camera is closed.
         *
         * @param cameraView The associated {@link CameraView}.
         */
        public void onCameraClosed(CameraView cameraView) {
        }

        /**
         * Called when a picture is taken.
         *
         * @param cameraView The associated {@link CameraView}.
         * @param data       JPEG data.
         */
        public void onPictureTaken(CameraView cameraView, byte[] data) {
        }
    }

}


================================================
FILE: aliocrlib/src/main/java/cameraview/DisplayOrientationDetector.java
================================================
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cameraview;

import android.content.Context;
import android.util.SparseIntArray;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.Surface;


/**
 * Monitors the value returned from {@link Display#getRotation()}.
 */
abstract class DisplayOrientationDetector {

    private final OrientationEventListener mOrientationEventListener;

    /** Mapping from Surface.Rotation_n to degrees. */
    static final SparseIntArray DISPLAY_ORIENTATIONS = new SparseIntArray();

    static {
        DISPLAY_ORIENTATIONS.put(Surface.ROTATION_0, 0);
        DISPLAY_ORIENTATIONS.put(Surface.ROTATION_90, 90);
        DISPLAY_ORIENTATIONS.put(Surface.ROTATION_180, 180);
        DISPLAY_ORIENTATIONS.put(Surface.ROTATION_270, 270);
    }

    Display mDisplay;

    private int mLastKnownDisplayOrientation = 0;

    public DisplayOrientationDetector(Context context) {
        mOrientationEventListener = new OrientationEventListener(context) {

            /** This is either Surface.Rotation_0, _90, _180, _270, or -1 (invalid). */
            private int mLastKnownRotation = -1;

            @Override
            public void onOrientationChanged(int orientation) {
                if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN ||
                        mDisplay == null) {
                    return;
                }
                final int rotation = mDisplay.getRotation();
                if (mLastKnownRotation != rotation) {
                    mLastKnownRotation = rotation;
                    dispatchOnDisplayOrientationChanged(DISPLAY_ORIENTATIONS.get(rotation));
                }
            }
        };
    }

    public void enable(Display display) {
        mDisplay = display;
        mOrientationEventListener.enable();
        // Immediately dispatch the first callback
        dispatchOnDisplayOrientationChanged(DISPLAY_ORIENTATIONS.get(display.getRotation()));
    }

    public void disable() {
        mOrientationEventListener.disable();
        mDisplay = null;
    }

    public int getLastKnownDisplayOrientation() {
        return mLastKnownDisplayOrientation;
    }

    void dispatchOnDisplayOrientationChanged(int displayOrientation) {
        mLastKnownDisplayOrientation = displayOrientation;
        onDisplayOrientationChanged(displayOrientation);
    }

    /**
     * Called when display orientation is changed.
     *
     * @param displayOrientation One of 0, 90, 180, and 270.
     */
    public abstract void onDisplayOrientationChanged(int displayOrientation);

}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/api/HttpCustomConfig.java
================================================
package com.lib.aliocr.api;

import com.lib.aliocr.http.config.HttpConfig;

import okhttp3.OkHttpClient;

/**
 * 作者:xin on 2018/6/7 0007 17:40
 * <p>
 * 邮箱:ittfxin@126.com
 * <P>
 * https://github.com/wzx54321/XinFrameworkLib
 */

public class HttpCustomConfig extends HttpConfig {
    @Override
    public OkHttpClient.Builder getCustomBuilder() {
        // 根据个人需要配置
        return null;
    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/api/MyApiManager.java
================================================
package com.lib.aliocr.api;


import com.lib.aliocr.bean.RepOutput;
import com.lib.aliocr.common.Api;

import io.reactivex.Observable;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;

import static com.lib.aliocr.common.Api.path;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
public interface MyApiManager {


    @POST(path)
    @Headers({"Authorization: APPCODE " + Api.APPCODE})
    Observable<RepOutput> authCard(@Body RequestBody body);
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/bean/RepOutput.java
================================================
package com.lib.aliocr.bean;

import java.io.Serializable;

/**
 * 作者:xin on 2018/7/9 0009 13:50
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */

public class RepOutput implements Serializable {


    private static final long serialVersionUID = 2694028643765036256L;

    private String address;// 地址信息
    private String config_str;// 配置信息,同输入configure
    private faceRect face_rect;// 信息
    private String name;// 姓名
    private String nationality;//  民族
    private String num;//  身份证号
    private String sex;//  性别
    private String birth;//  出生日期
    private String start_date;// 有效期起始时间
    private String end_date;// 有效期结束时间
    private String issue;// 签发机关
    private boolean success;// true表示成功,false表示失败

    static class faceRect implements Serializable {
        private static final long serialVersionUID = -7765350923476725941L;
        private double angle;
        private Center center;
        private Size size;

        public double getAngle() {
            return angle;
        }

        public void setAngle(int angle) {
            this.angle = angle;
        }

        public Center getCenter() {
            return center;
        }

        public void setCenter(Center center) {
            this.center = center;
        }

        public Size getSize() {
            return size;
        }

        public void setSize(Size size) {
            this.size = size;
        }

        static class Center implements Serializable {
            private static final long serialVersionUID = 3232617470096971014L;
            private double x;
            private double y;

            public double getX() {
                return x;
            }

            public void setX(double x) {
                this.x = x;
            }

            public double getY() {
                return y;
            }

            public void setY(double y) {
                this.y = y;
            }

            @Override
            public String toString() {
                return "Center{" +
                        "x=" + x +
                        ", y=" + y +
                        '}';
            }
        }

        static class Size implements Serializable {
            private static final long serialVersionUID = -3276942859242710227L;
            private double height;
            private double width;

            public double getHeight() {
                return height;
            }

            public void setHeight(double height) {
                this.height = height;
            }

            public double getWidth() {
                return width;
            }

            public void setWidth(double width) {
                this.width = width;
            }


            @Override
            public String toString() {
                return "Size{" +
                        "height=" + height +
                        ", width=" + width +
                        '}';
            }
        }

        @Override
        public String toString() {
            return "faceRect{" +
                    "angle=" + angle +
                    ", center=" + center +
                    ", size=" + size +
                    '}';
        }
    }


    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getConfig_str() {
        return config_str;
    }

    public void setConfig_str(String config_str) {
        this.config_str = config_str;
    }

    public faceRect getFace_rect() {
        return face_rect;
    }

    public void setFace_rect(faceRect face_rect) {
        this.face_rect = face_rect;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNationality() {
        return nationality;
    }

    public void setNationality(String nationality) {
        this.nationality = nationality;
    }

    public String getNum() {
        return num;
    }

    public void setNum(String num) {
        this.num = num;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getBirth() {
        return birth;
    }

    public void setBirth(String birth) {
        this.birth = birth;
    }

    public String getStart_date() {
        return start_date;
    }

    public void setStart_date(String start_date) {
        this.start_date = start_date;
    }

    public String getEnd_date() {
        return end_date;
    }

    public void setEnd_date(String end_date) {
        this.end_date = end_date;
    }

    public String getIssue() {
        return issue;
    }

    public void setIssue(String issue) {
        this.issue = issue;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }


    @Override
    public String toString() {
        return "RepOutput{" +
                "address='" + address + '\'' +
                ", config_str='" + config_str + '\'' +
                ", face_rect=" + face_rect +
                ", name='" + name + '\'' +
                ", nationality='" + nationality + '\'' +
                ", num='" + num + '\'' +
                ", sex='" + sex + '\'' +
                ", birth='" + birth + '\'' +
                ", start_date='" + start_date + '\'' +
                ", end_date='" + end_date + '\'' +
                ", issue='" + issue + '\'' +
                ", success=" + success +
                '}';
    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/bean/ReqInput.java
================================================
package com.lib.aliocr.bean;

import java.io.Serializable;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <P>
 * https://github.com/wzx54321/XinFrameworkLib
 */

public class ReqInput implements Serializable {
    private static final long serialVersionUID = 7540344538333996814L;

    private String image;// 图片的 base64
    private String configure;//  "{\"side\":\"face\"}"   身份证正反面类型:face/back


    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getConfigure() {
        return configure;
    }

    public void setConfigure(String configure) {
        this.configure = configure;
    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/callback/OcrCallback.java
================================================
package com.lib.aliocr.callback;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */


public interface OcrCallback {


    void onPicResult(String picPath);

    void onPicError();
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/common/Api.java
================================================
package com.lib.aliocr.common;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */

public interface Api {


    String host = "http://dm-51.data.aliyun.com";
    String path = "/rest/160601/ocr/ocr_idcard.json";
   // 注册的APP code
    String APPCODE = "17b5e0d488564592868ed002e4e282c4";
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/contact/OcrContact.java
================================================
package com.lib.aliocr.contact;

import android.app.Activity;

import com.lib.aliocr.bean.RepOutput;

import io.reactivex.Observable;

/**
 * 作者:xin on 2018/7/12 0012 16:55
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */

public interface OcrContact {

    interface V {

        Activity getActivity();
    }

    interface P {
        void onPictureTaken(final byte[] data );

        void request(boolean isFace, String imgPath);
    }


    interface M {

        Observable<RepOutput> AuthCard(boolean isFace, String imgPath);
    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/http/config/HttpConfig.java
================================================
package com.lib.aliocr.http.config;

import android.annotation.SuppressLint;

import com.lib.aliocr.http.https.HttpsUtils;
import com.lib.aliocr.http.interceptor.HttpLog;

import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import okhttp3.OkHttpClient;


/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */

public abstract class HttpConfig {

    private OkHttpClient httpClient;
    private static final long DEFAULT_MILLISECONDS = 60000; // 默认时间

    /**
     * 获取默认的{@link OkHttpClient.Builder}
     * <p>
     */
    private OkHttpClient.Builder getDefaultBuilder() {

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        // log相关
        HttpLog httpLog = new HttpLog();
        httpLog.setPrintLevel(HttpLog.Level.BODY); // log打印级别,决定了log显示的详细程度
        //  httpLog.setPrintBinaryBody(true);// 打印二进制Log ,默认不打印
        builder.addInterceptor(httpLog);

        // 超时时间设置,默认60秒
        builder.readTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);      // 全局的读取超时时间
        builder.writeTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);     // 全局的写入超时时间
        builder.connectTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);   // 全局的连接超时时间

        //  builder.cookieJar(new CookieJarImpl(new SPCookieStore(app)));          // 使用sp保持cookie,如果cookie不过期,则一直有效
        //   builder.cookieJar(new CookieJarImpl(new DBCookieStore(ContextUtils.getActivity())));             // 使用数据库保持cookie,如果cookie不过期,则一直有效

        // https相关设置,以下几种方案根据需要自己设置
        // 方法一:信任所有证书,不安全有风险
        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
        // 方法二:自定义信任规则,校验服务端证书
        //  HttpsUtils.SSLParams sslParams2 = HttpsUtils.getSslSocketFactory(new SafeTrustManager());
        // 方法三:使用预埋证书,校验服务端证书(自签名证书)
       /* try {
            HttpsUtils.SSLParams sslParams3 = HttpsUtils.getSslSocketFactory(app.getAssets().open("srca.cer"));
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        // 方法四:使用bks证书和密码管理客户端证书(双向认证),使用预埋证书,校验服务端证书(自签名证书)
        // HttpsUtils.SSLParams sslParams4 = HttpsUtils.getSslSocketFactory(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"));
        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
        // 配置https的域名匹配规则,详细看demo的初始化介绍,不需要就不要加入,使用不当会导致https握手失败
        builder.hostnameVerifier(new SafeHostnameVerifier());
        return builder;

    }


    /**
     * 获取默认的{@link OkHttpClient.Builder}
     * <p>
     * 可以根据个人需要创建项目需求的Builder
     */

    @SuppressWarnings("SameReturnValue")
    protected abstract OkHttpClient.Builder getCustomBuilder();


    /**
     * 创建OkHttpClient
     */
    public OkHttpClient build() {

        OkHttpClient.Builder builder = getCustomBuilder();

        if (builder == null) {
            builder = getDefaultBuilder();
        }

        httpClient = builder.build();
        return httpClient;
    }


    /**
     * 获取OKHttp
     * <p>
     * OkHttpClient
     */
    public OkHttpClient getHttpClient() {

        if (httpClient == null) {
            throw new NullPointerException("OkHttpClient is null,you must call HttpConfig.build(); or set a OkHttpClient  object  first");
        }

        return httpClient;
    }

    public void setHttpClient(OkHttpClient httpClient) {
        this.httpClient = httpClient;
    }



    /**
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 这里只是我谁便写的认证规则,具体每个业务是否需要验证,以及验证规则是什么,请与服务端或者leader确定
     * 重要的事情说三遍,以下代码不要直接使用
     */
    private static class SafeHostnameVerifier implements HostnameVerifier {
        @SuppressLint("BadHostnameVerifier")
        @Override
        public boolean verify(String hostname, SSLSession session) {
            // 验证主机名是否匹配
            // return hostname.equals(RestApiPath.REST_URI_HOST);
            return true;
        }
    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/http/helper/HttpHelper.java
================================================
package com.lib.aliocr.http.helper;


import com.lib.aliocr.api.HttpCustomConfig;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
public class HttpHelper {


    private OkHttpClient mOkHttpClient;
    private RxJava2CallAdapterFactory mAdapterFactory;
    private GsonConverterFactory mGsonConverterFactory;

    private HttpHelper() {

        mGsonConverterFactory = GsonConverterFactory.create();
        mAdapterFactory = RxJava2CallAdapterFactory.create();
        //设置超时时间
        mOkHttpClient = new HttpCustomConfig().build();
    }

    public static HttpHelper getInstance() {
        return LazyHolder.INSTANCE;
    }

    public  Retrofit getRetrofit(String url) {

        return new Retrofit.Builder()
                .baseUrl(url)
                .addCallAdapterFactory(mAdapterFactory)
                .addConverterFactory(mGsonConverterFactory)
                .client(mOkHttpClient)
                .build();
    }

    private static final class LazyHolder {
        static final HttpHelper INSTANCE = new HttpHelper();
    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/http/https/HttpsUtils.java
================================================

package com.lib.aliocr.http.https;


import android.annotation.SuppressLint;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
@SuppressWarnings("WeakerAccess")
public class HttpsUtils {

    public static class SSLParams {
        public SSLSocketFactory sSLSocketFactory;
        public X509TrustManager trustManager;
    }

    public static SSLParams getSslSocketFactory() {
        return getSslSocketFactoryBase(null, null, null);
    }

    /**
     * https单向认证
     * 可以额外配置信任服务端的证书策略,否则默认是按CA证书去验证的,若不是CA可信任的证书,则无法通过验证
     */
    public static SSLParams getSslSocketFactory(X509TrustManager trustManager) {
        return getSslSocketFactoryBase(trustManager, null, null);
    }

    /**
     * https单向认证
     * 用含有服务端公钥的证书校验服务端证书
     */
    public static SSLParams getSslSocketFactory(InputStream... certificates) {
        return getSslSocketFactoryBase(null, null, null, certificates);
    }

    /**
     * https双向认证
     * bksFile 和 password -> 客户端使用bks证书校验服务端证书
     * certificates -> 用含有服务端公钥的证书校验服务端证书
     */
    public static SSLParams getSslSocketFactory(InputStream bksFile, String password, InputStream... certificates) {
        return getSslSocketFactoryBase(null, bksFile, password, certificates);
    }

    /**
     * https双向认证
     * bksFile 和 password -> 客户端使用bks证书校验服务端证书
     * X509TrustManager -> 如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可
     */
    public static SSLParams getSslSocketFactory(InputStream bksFile, String password, X509TrustManager trustManager) {
        return getSslSocketFactoryBase(trustManager, bksFile, password);
    }

    private static SSLParams getSslSocketFactoryBase(X509TrustManager trustManager, InputStream bksFile, String password, InputStream... certificates) {
        SSLParams sslParams = new SSLParams();
        try {
            KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
            TrustManager[] trustManagers = prepareTrustManager(certificates);
            X509TrustManager manager;
            if (trustManager != null) {
                //优先使用用户自定义的TrustManager
                manager = trustManager;
            } else if (trustManagers != null) {
                //然后使用默认的TrustManager
                manager = chooseTrustManager(trustManagers);
            } else {
                //否则使用不安全的TrustManager
                manager = UnSafeTrustManager;
            }
            // 创建TLS类型的SSLContext对象, that uses our TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            // 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书
            // 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书
            sslContext.init(keyManagers, new TrustManager[]{manager}, null);
            // 通过sslContext获取SSLSocketFactory对象
            sslParams.sSLSocketFactory = sslContext.getSocketFactory();
            sslParams.trustManager = manager;
            return sslParams;
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            throw new AssertionError(e);
        }
    }

    private static KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
        try {
            if (bksFile == null || password == null) return null;
            KeyStore clientKeyStore = KeyStore.getInstance("BKS");
            clientKeyStore.load(bksFile, password.toCharArray());
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientKeyStore, password.toCharArray());
            return kmf.getKeyManagers();
        } catch (Exception e) {
            Log.e("net","Https#prepareKeyManager error",e);
        }
        return null;
    }

    private static TrustManager[] prepareTrustManager(InputStream... certificates) {
        if (certificates == null || certificates.length <= 0) return null;
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            // 创建一个默认类型的KeyStore,存储我们信任的证书
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certStream : certificates) {
                String certificateAlias = Integer.toString(index++);
                // 证书工厂根据证书文件的流生成证书 cert
                Certificate cert = certificateFactory.generateCertificate(certStream);
                // 将 cert 作为可信证书放入到keyStore中
                keyStore.setCertificateEntry(certificateAlias, cert);
                try {
                    if (certStream != null) certStream.close();
                } catch (IOException e) {
                    Log.e("net","Https#prepareTrustManager error",e);
                }
            }
            //我们创建一个默认类型的TrustManagerFactory
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            //用我们之前的keyStore实例初始化TrustManagerFactory,这样tmf就会信任keyStore中的证书
            tmf.init(keyStore);
            //通过tmf获取TrustManager数组,TrustManager也会信任keyStore中的证书
            return tmf.getTrustManagers();
        } catch (Exception e) {
            Log.e("net","Https#prepareTrustManager error",e);
        }
        return null;
    }

    private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
        for (TrustManager trustManager : trustManagers) {
            if (trustManager instanceof X509TrustManager) {
                return (X509TrustManager) trustManager;
            }
        }
        return null;
    }

    /**
     * 为了解决客户端不信任服务器数字证书的问题,网络上大部分的解决方案都是让客户端不对证书做任何检查,
     * 这是一种有很大安全漏洞的办法
     */
    public static X509TrustManager UnSafeTrustManager = new X509TrustManager() {
        @SuppressLint("TrustAllX509TrustManager")
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @SuppressLint("TrustAllX509TrustManager")
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    };

    /**
     * 此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,
     * 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。
     * 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true
     */
    public static HostnameVerifier UnSafeHostnameVerifier = new HostnameVerifier() {
        @SuppressLint("BadHostnameVerifier")
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/http/interceptor/HttpLog.java
================================================
package com.lib.aliocr.http.interceptor;


import android.support.annotation.NonNull;
import android.util.Log;

import com.lib.aliocr.utils.io.IOUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

import okhttp3.Connection;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;


/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
public class HttpLog implements Interceptor {

    private boolean isPrintBinaryBody;

    public enum Level {
        NONE,       //不打印log
        BASIC,      //只打印 请求首行 和 响应首行
        HEADERS,    //打印请求和响应的所有 Header
        BODY        //所有数据全部打印
    }


    private volatile Level printLevel = Level.NONE;

    public void setPrintLevel(Level printLevel) {
        this.printLevel = printLevel;
    }

    public void setPrintBinaryBody(boolean printBinaryBody) {
        isPrintBinaryBody = printBinaryBody;
    }

    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request();
        if (printLevel == Level.NONE) {
            return chain.proceed(request);
        }

        //请求日志拦截
        logForRequest(request, chain.connection());
        // 执行请求,计算请求时间
        long startNs = System.nanoTime();
        Response response;
        try {
            response = chain.proceed(request);
        } catch (Exception e) {
            //  Log.e(e, "<-- HTTP FAILED: ");
            throw e;
        }
        long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);

        //响应日志拦截
        return logForResponse(response, tookMs);
    }


    private void logForRequest(Request request, Connection connection) {

        boolean logBody = (printLevel == Level.BODY);
        boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
        RequestBody requestBody = request.body();
        boolean hasRequestBody = requestBody != null;
        Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;

        StringBuilder requestMessage = new StringBuilder();
        try {
            requestMessage.append("--> ").append(request.method()).append(' ').append(request.url()).append(' ').append(protocol).append("\n");


            if (logHeaders) {
                if (hasRequestBody) {
                    // Request body headers are only present when installed as a network interceptor. Force
                    // them to be included (when available) so there values are known.
                    if (requestBody.contentType() != null) {
                        requestMessage.append("\tContent-Type: ").append(requestBody.contentType()).append("\n");
                    }
                    if (requestBody.contentLength() != -1) {
                        requestMessage.append("\tContent-Length: ").append(requestBody.contentLength()).append("\n");
                    }
                }
                Headers headers = request.headers();
                for (int i = 0, count = headers.size(); i < count; i++) {
                    String name = headers.name(i);
                    // Skip headers from the request body as they are explicitly logged above.
                    if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
                        requestMessage.append("\t").append(name).append(": ").append(headers.value(i)).append("\n");
                    }
                }


                if (logBody && hasRequestBody) {
                    if (isPlaintext(requestBody.contentType())) {
                        requestMessage.append(bodyToString(request));
                    } else {
                        requestMessage.append("\tbody: maybe [binary body], omitted!\n");
                    }
                }
            }
        } catch (Exception e) {
            Log.e("orc", "intercept");
        } finally {

            requestMessage.append("--> END ").append(request.method());

            Log.i("HTTPLOG", requestMessage.toString());
        }
    }


    private Response logForResponse(Response response, long tookMs) {
        StringBuilder responseMsg = new StringBuilder();
        Response.Builder builder = response.newBuilder();
        Response clone = builder.build();
        ResponseBody responseBody = clone.body();
        boolean logBody = (printLevel == Level.BODY);
        boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);

        try {
            responseMsg.append("<-- ").append(clone.code()).append(' ').append(clone.message()).append(' ').append(clone.request().url()).append(" (").append(tookMs).append("ms)" + "\n");
            if (logHeaders) {
                Headers headers = clone.headers();

                for (int i = 0, count = headers.size(); i < count; i++) {
                    responseMsg.append("\t").append(headers.name(i)).append(": ").append(headers.value(i)).append("\n");
                }

                if (logBody && HttpHeaders.hasBody(clone)) {
                    if (responseBody == null) return response;

                    if (isPrintBinaryBody || isPlaintext(responseBody.contentType())) {
                        byte[] bytes = IOUtils.toByteArray(responseBody.byteStream());
                        MediaType contentType = responseBody.contentType();
                        String body = new String(bytes, getCharset(contentType));
                        responseMsg.append("\tbody:").append(body);
                        responseBody = ResponseBody.create(responseBody.contentType(), bytes);
                        return response.newBuilder().body(responseBody).build();
                    } else {
                        responseMsg.append("\tbody: maybe [binary body], omitted! \n if you want to log it please call set isPrintBinaryBody is true");
                    }
                }
            }
        } catch (Exception e) {
            Log.e("", "logForResponse error");
        } finally {
            responseMsg.append("<-- END HTTP");

            Log.i("HTTPLOG", responseMsg.toString());
        }
        return response;
    }

    /**
     * Returns true if the body in question probably contains human readable text. Uses a small sample
     * of code points to detect unicode control characters commonly used in binary file signatures.
     */
    private static boolean isPlaintext(MediaType mediaType) {
        if (mediaType == null) return false;
        if (mediaType.type() != null && mediaType.type().equals("text")) {
            return true;
        }
        String subtype = mediaType.subtype();
        if (subtype != null) {
            subtype = subtype.toLowerCase();
            if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html")) //
                return true;
        }
        return false;
    }

    private String bodyToString(Request request) {

        try {
            Request copy = request.newBuilder().build();
            RequestBody body = copy.body();
            if (body == null) return "";
            Buffer buffer = new Buffer();
            body.writeTo(buffer);
            Charset charset = getCharset(body.contentType());
            return "\tbody:" + buffer.readString(charset) + "\n";
        } catch (Exception e) {
            Log.e("", "bodyToString error");
        }

        return "";
    }

    private static Charset getCharset(MediaType contentType) {
        Charset charset = contentType != null ? contentType.charset(UTF8) : UTF8;
        if (charset == null) charset = UTF8;
        return charset;
    }

    private static final Charset UTF8 = Charset.forName("UTF-8");

}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/modle/OCRModel.java
================================================
package com.lib.aliocr.modle;

import com.google.gson.Gson;
import com.lib.aliocr.api.MyApiManager;
import com.lib.aliocr.bean.RepOutput;
import com.lib.aliocr.bean.ReqInput;
import com.lib.aliocr.common.Api;
import com.lib.aliocr.contact.OcrContact;
import com.lib.aliocr.http.helper.HttpHelper;
import com.lib.aliocr.utils.OcrUtils;

import org.json.JSONObject;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.functions.Function;
import okhttp3.RequestBody;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */

public class OCRModel implements OcrContact.M{


    public Observable<RepOutput> AuthCard(final boolean isFace, final String imgPath) {

        return Observable.create(new ObservableOnSubscribe<ReqInput>() {
            @Override
            public void subscribe(ObservableEmitter<ReqInput> e) throws Exception {
                JSONObject configObj = new JSONObject();
                if (isFace) {
                    configObj.put("side", "face");
                } else {
                    configObj.put("side", "back");
                }
                ReqInput input = new ReqInput();
                input.setImage(OcrUtils.getImageStr(imgPath));
                input.setConfigure(configObj.toString());
                e.onNext(input);

            }
        }).flatMap(new Function<ReqInput, Observable<RepOutput>>() {
            @Override
            public Observable<RepOutput> apply(ReqInput reqInput) throws Exception {
                MyApiManager apiManager = HttpHelper.getInstance().getRetrofit(Api.host).create(MyApiManager.class);
                Gson gson = new Gson();
                String reqStr = gson.toJson(reqInput);
                RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), reqStr);
                return apiManager.authCard(body);
            }
        });


    }

}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/presenter/OCRPresenter.java
================================================
package com.lib.aliocr.presenter;

import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.lib.aliocr.bean.RepOutput;
import com.lib.aliocr.contact.OcrContact;
import com.lib.aliocr.modle.OCRModel;
import com.lib.aliocr.utils.OcrUtils;
import com.lib.aliocr.view.OCRMainActivity;

import java.io.File;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
public class OCRPresenter implements OcrContact.P {
    private OcrContact.M model;
    private OcrContact.V view;
    private static final String TAG = OCRMainActivity.class.getSimpleName();

    public OCRPresenter(OcrContact.V view) {
        this.view = view;
        model = new OCRModel();
    }

    public void onPictureTaken(final byte[] data) {



        Disposable disposable=  Observable .create(new ObservableOnSubscribe<File>() {
            @Override
            public void subscribe(ObservableEmitter<File> emitter) {

                String fileName = System.currentTimeMillis() + "picture.jpg";
                File file = new File(view.getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES),
                        fileName);
                Bitmap bitmap = OcrUtils.byte2bitmap(data);

                OcrUtils.saveBitmap(bitmap, file.getAbsolutePath());

                if (/*OcrUtils.compressSmallImage(bitmap, file, 4 * 1023)*/file.exists()) {
                    emitter.onNext(file);
                } else {
                    emitter.onError(new Exception("图片转换失败"));
                }
            }
        }).subscribeOn(Schedulers.io()).subscribeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<File>() {
            @Override
            public void accept(File file) throws Exception {
                if (file != null && file.exists()) {
                    OcrUtils.beginCrop(Uri.fromFile(file), view.getActivity(), null);

                }
            }
        });
    }

    public void request(boolean isFace, final String imgPath) {
        model.AuthCard(isFace, imgPath).subscribeOn(Schedulers.io()).
                observeOn(AndroidSchedulers.mainThread()).
                subscribe(new Observer<RepOutput>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(RepOutput repOutput) {
                        if (repOutput != null)
                            Log.i("HTTPLOG", repOutput.toString());

                        Toast.makeText(view.getActivity(), "" + repOutput.toString(), Toast.LENGTH_LONG).show();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i("HTTPLOG", e.toString());
                        Toast.makeText(view.getActivity(), "" + e.toString(), Toast.LENGTH_LONG).show();

                    }

                    @Override
                    public void onComplete() {

                    }
                });


    }

}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/Base64.java
================================================
package com.lib.aliocr.utils;

import sun.misc.BASE64Encoder;
/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
public class Base64 {


    public static String getAuthor(String secretKey,String author) {
        byte[] data = null;
        String s = secretKey + author;
        try {
            data = s.getBytes();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 加密
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data != null ? data : new byte[0]);
    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/Ocr.java
================================================
package com.lib.aliocr.utils;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;

import com.lib.aliocr.callback.OcrCallback;
import com.lib.aliocr.view.OCRMainActivity;
import com.lib.aliocr.widget.crop.Crop;
import com.lib.aliocr.widget.popup.XinPopWindow;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
public class Ocr {

    private static final int PICK_IMAGE_CHOOSER_REQUEST_CODE = 222;
    private static final int PICK_IMAGE_PERMISSIONS_REQUEST_CODE = 222222;
    private static final int IMAGE_CROP_CODE = 3333;


    /**
     * 发起验证
     *
     * @param activity
     * @param rootView
     */
    public static void doOcr(final Activity activity, final Fragment fragment, final View rootView, final boolean isFace) {
        List<XinPopWindow.MenuItem> menuItems = new ArrayList<>();
        menuItems.add(new XinPopWindow.MenuItem("拍照识别", 0));
        menuItems.add(new XinPopWindow.MenuItem("相册识别", 1));
        final XinPopWindow myPopWindow = new XinPopWindow(activity);
        myPopWindow.setData(menuItems);
        myPopWindow.setOnItemClickListener(new XinPopWindow.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id, int type) {
                if (type == 0) {
                    OCRMainActivity.Launcher(activity, isFace);
                } else {

                    if (fragment != null) {
                        Crop.pickImage(activity, fragment);
                    } else {

                        Crop.pickImage(activity);
                    }
                }
                myPopWindow.dismiss();
            }
        });
        myPopWindow.showAtLocation(rootView, Gravity.BOTTOM, 0, 0);
    }


    /**
     * activity回调
     *
     * @param activity
     * @param requestCode
     * @param resultCode
     * @param result
     * @param callback
     */
    public static void onCropImgResult(Activity activity, Fragment fragment, int requestCode, int resultCode, Intent result, OcrCallback callback) {
        if (requestCode == Crop.REQUEST_PICK && resultCode == Activity.RESULT_OK) {
            OcrUtils.beginCrop(result.getData(), activity, fragment);
        } else if (requestCode == Crop.REQUEST_CROP) {
            if (resultCode == Activity.RESULT_OK) {
                Uri imgUri = Crop.getOutput(result);

                if (callback != null) {
                    callback.onPicResult(OcrUtils.getPath(activity, imgUri));
                }
            } else if (resultCode == Crop.RESULT_ERROR) {
                if (callback != null) {

                    callback.onPicError();
                }
            }
        }
    }


    public static Uri onPickImgResult(Activity activity, int requestCode, int resultCode, Intent data) {

        Uri cropImageUri = null;
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == PICK_IMAGE_CHOOSER_REQUEST_CODE) {
                cropImageUri = data.getData();

                if (OcrUtils.isReadExternalStoragePermissionsRequired(activity, cropImageUri)) {// 需要权限处理
                    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                            PICK_IMAGE_PERMISSIONS_REQUEST_CODE);
                } else {
                    handleImgShot(activity, cropImageUri);
                }

            }

        }
        return cropImageUri;

    }


    public static void onBackResult(Activity activity, int requestCode, int resultCode, Intent data, boolean isFace) {
        //noinspection StatementWithEmptyBody
        if (resultCode == Activity.RESULT_OK && requestCode == IMAGE_CROP_CODE) {
            // TODO

            //    new OCRModel().AuthCard(isFace,)
        }
    }


    public static void onRequestPermissionsResult(Activity activity, int requestCode, String permissions[],
                                                  int[] grantResults, Uri cropImageUri) {

        if (requestCode == PICK_IMAGE_PERMISSIONS_REQUEST_CODE) {
            if (cropImageUri != null
                    && grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {


                handleImgShot(activity, cropImageUri);
            }
            // TODO  用户拒绝授权

        }
    }


    /**
     * Intent方式截图处理
     */
    public static void handleImgShot(Activity activity, Uri uri) {
        File file = new File(activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis() + ".jpg");
        String cropImagePath = file.getAbsolutePath();
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 500);
        intent.putExtra("outputY", 500);
        intent.putExtra("scale", true);
        intent.putExtra("scaleUpIfNeeded", true);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        activity.startActivityForResult(intent, IMAGE_CROP_CODE);

    }


}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/OcrUtils.java
================================================
package com.lib.aliocr.utils;

import android.Manifest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;

import com.lib.aliocr.R;
import com.lib.aliocr.widget.crop.Crop;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import sun.misc.BASE64Encoder;

/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */
@SuppressWarnings("ResultOfMethodCallIgnored")
public class OcrUtils {
    public static String getImageStr(String imgFile) {
        InputStream inputStream;
        byte[] data = null;
        try {
            inputStream = new FileInputStream(imgFile);
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 加密
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }

    public static Bitmap byte2bitmap(byte[] data) {

        if (null == data) {

            return null;

        }

        return BitmapFactory.decodeByteArray(data,
                0,
                data.length);

    }

    public static boolean saveBitmap(Bitmap bitmap,
                                     String path) {
        return saveBitmap(bitmap,
                path,
                100);
    }

    /**
     * 将bitmap位图保存到path路径下,图片格式为Bitmap.CompressFormat.JPEG,质量为100
     *
     * @param bitmap
     * @param path
     * @param quality 压缩的比率(1-100)
     */

    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static boolean saveBitmap(Bitmap bitmap,
                                     String path,
                                     int quality) {

        try {

            File file = new File(path);

            File parent = file.getParentFile();

            if (!parent.exists()) {

                parent.mkdirs();

            }

            // if(file.exists()){
            // FileUtil.deleteFile(file);
            // }

            FileOutputStream fos = new FileOutputStream(file);

            boolean b = bitmap.compress(Bitmap.CompressFormat.JPEG,
                    quality,
                    fos);
            fos.flush();

            fos.close();

            return b;

        } catch (IOException e) {

            e.printStackTrace();

        } finally {
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.isRecycled();
            }
        }

        return false;

    }


    /**
     * 图片压缩并保存到文件(是否压缩都保存)
     */
    public static boolean compressSmallImage(Bitmap image,
                                             File file,
                                             int kb) {
        return compressSmallImage(image,
                file,
                kb,
                true);
    }

    /**
     * 图片压缩并保存到文件
     *
     * @param image      源文件
     * @param file       要保存到的file
     * @param kb         限制的size
     * @param iSsaveFile (可为false,如File已存在但无压缩的情况下可设置为false)
     * @return 是否存储了文件
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static boolean compressSmallImage(Bitmap image,
                                             File file,
                                             int kb,
                                             boolean iSsaveFile) {
        if (image == null)
            return false;
        Boolean isCompressed = false;
        boolean isSaveFileSuccessed = false;// 是否存储成功了文件夹
        File parent = file.getParentFile();

        if (!parent.exists()) {

            parent.mkdirs();

        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        OutputStream out = null;
        image.compress(Bitmap.CompressFormat.JPEG,
                100,
                baos);

        int options = 100;
        Bitmap temp;
        while ((baos.size() <= 0 ? baos.toByteArray().length : baos.size()) / 1024 > kb) {
            isCompressed = true;
            baos.reset();
            options -= 10;// 每次都减少10
            image.compress(Bitmap.CompressFormat.JPEG,
                    options,
                    baos);
        }
        byte[] byteArray = baos.toByteArray();
        try {
            // 不管有无压缩,都写入文件
            if (iSsaveFile) {
                out = new FileOutputStream(file);
                out.write(byteArray,
                        0,
                        byteArray.length);
                isSaveFileSuccessed = true;
            } else {
                // iSsaveFile==false 时,只有压缩后写入文件
                if (isCompressed) {
                    out = new FileOutputStream(file);
                    out.write(byteArray,
                            0,
                            byteArray.length);
                    isSaveFileSuccessed = true;
                }
            }
        } catch (Exception e) {
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (isSaveFileSuccessed) {

        }
        return isSaveFileSuccessed;
    }


    public static String getPath(Context context,
                                 Uri uri) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (DocumentsContract.isDocumentUri(context, uri)) {
                String docId;
                String[] split;
                String type;
                if (isExternalStorageDocument(uri)) {
                    docId = DocumentsContract.getDocumentId(uri);
                    split = docId.split(":");
                    type = split[0];
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
                } else {
                    if (isDownloadsDocument(uri)) {
                        docId = DocumentsContract.getDocumentId(uri);
                        Uri split1 = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                                Long.valueOf(docId));
                        return getDataColumn(context,
                                split1,
                                null,
                                null);
                    }

                    if (isMediaDocument(uri)) {
                        docId = DocumentsContract.getDocumentId(uri);
                        split = docId.split(":");
                        type = split[0];
                        Uri contentUri = null;
                        if ("image".equals(type)) {
                            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                        } else if ("video".equals(type)) {
                            contentUri = android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                        } else if ("audio".equals(type)) {
                            contentUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                        }

                        String selection = "_id=?";
                        String[] selectionArgs = new String[]{split[1]};
                        return getDataColumn(context,
                                contentUri,
                                "_id=?",
                                selectionArgs);
                    }
                }
            }
        }

        if ("content".equalsIgnoreCase(uri.getScheme())) {
            if (isGooglePhotosUri(uri)) {
                return uri.getLastPathSegment();
            }

            return getDataColumn(context,
                    uri,
                    null,
                    null);
        }

        if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }


        return null;
    }

    public static String getDataColumn(Context context,
                                       Uri uri,
                                       String selection,
                                       String[] selectionArgs) {
        Cursor cursor = null;
        String column = "_data";
        String[] projection = new String[]{"_data"};

        try {
            cursor = context.getContentResolver()
                    .query(uri,
                            projection,
                            selection,
                            selectionArgs,
                            null);
            if (cursor != null && cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow("_data");
                String var9 = cursor.getString(index);
                return var9;
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }

        }

        return null;
    }


    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }


    private static Intent getGalleryIntent(Context context, boolean includeDocuments) {
        PackageManager packageManager = context.getPackageManager();
        List<Intent> galleryIntents = getGalleryIntents(packageManager, Intent.ACTION_GET_CONTENT, includeDocuments);

        if (galleryIntents.size() == 0) {
            // if no intents found for get-content try pick intent action (Huawei P9).
            galleryIntents = getGalleryIntents(packageManager, Intent.ACTION_PICK, includeDocuments);
        }
        Intent target;
        if (galleryIntents.isEmpty()) {
            target = new Intent();
        } else {
            target = galleryIntents.get(galleryIntents.size() - 1);
            galleryIntents.remove(galleryIntents.size() - 1);
        }

        // Create a chooser from the main  intent
        Intent chooserIntent = Intent.createChooser(target, context.getString(R.string.pick_image_intent_chooser_title));

        // Add all other intents
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, galleryIntents.toArray(new Parcelable[galleryIntents.size()]));

        return chooserIntent;
    }


    /**
     * Get all Gallery intents for getting image from one of the apps of the device that handle images.
     */
    private static List<Intent> getGalleryIntents(@NonNull
                                                          PackageManager packageManager, String action, boolean includeDocuments) {
        List<Intent> intents = new ArrayList<>();
        Intent galleryIntent = Intent.ACTION_GET_CONTENT.equals(action) ? new Intent(action)
                : new Intent(action, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        galleryIntent.setType("image/*");
        List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
        for (ResolveInfo res : listGallery) {
            Intent intent = new Intent(galleryIntent);
            intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
            intent.setPackage(res.activityInfo.packageName);
            intents.add(intent);
        }

        // remove documents intent
        if (!includeDocuments) {
            for (Intent intent : intents) {
                if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) {
                    intents.remove(intent);
                    break;
                }
            }
        }
        return intents;
    }


    public static boolean isReadExternalStoragePermissionsRequired(@NonNull Context context, @NonNull
            Uri uri) {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
                context.checkSelfPermission(
                        Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
                isUriRequiresPermissions(context, uri);
    }


    /**
     * Test if we can open the given Android URI to test if permission required error is thrown.<br>
     * Only relevant for API version 23 and above.
     *
     * @param context used to access Android APIs, like content resolve, it is your activity/fragment/widget.
     * @param uri     the result URI of image pick.
     */
    public static boolean isUriRequiresPermissions(@NonNull Context context, @NonNull Uri uri) {
        try {
            ContentResolver resolver = context.getContentResolver();
            InputStream stream = resolver.openInputStream(uri);
            stream.close();
            return false;
        } catch (Exception e) {
            return true;
        }
    }


    public static void beginCrop(Uri source, Activity activity, Fragment fragment) {
        Uri destination = Uri.fromFile(new File(activity.getCacheDir(), "cropped"));

        Crop crop = Crop.of(source, destination).withAspect(1, 1.3f);
        if (fragment == null)
            crop.start(activity);
        else
            crop.start(activity, fragment);

    }
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/Charsets.java
================================================

package com.lib.aliocr.utils.io;

import java.nio.charset.Charset;

/**
 * Charsets
 */
@SuppressWarnings("WeakerAccess")
public class Charsets {
    public static Charset toCharset(Charset charset) {
        return charset == null ? Charset.defaultCharset() : charset;
    }
    public static Charset toCharset(String charset) {
        return charset == null ? Charset.defaultCharset() : Charset.forName(charset);
    }
    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
    public static final Charset US_ASCII = Charset.forName("US-ASCII");
    public static final Charset UTF_16 = Charset.forName("UTF-16");
    public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
    public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
    public static final Charset UTF_8 = Charset.forName("UTF-8");
}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/FileUtil.java
================================================
package com.lib.aliocr.utils.io;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.DecimalFormat;
import java.util.Date;




/**
 * 作者:xin on 2018/7/9 0009 15:03
 * <p>
 * 邮箱:ittfxin@126.com
 * <p>
 * https://github.com/wzx54321/XinFrameworkLib
 */

@SuppressWarnings("WeakerAccess")
public class FileUtil {
    private static final String TAG = "FileUtil";
    public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;


    /*
      ********************************************读写***************************
     */

    /**
     * Returns a human-readable version of the file size, where the input
     * represents a specific number of bytes.
     *
     * @param size the number of bytes
     * @return a human-readable display value (includes units)
     */
    public static String formatSize(long size) {
        float ONE_KB = 1024F;
        float ONE_MB = ONE_KB * ONE_KB;
        float ONE_GB = ONE_KB * ONE_MB;
        String displaySize;
        DecimalFormat df = new DecimalFormat("0.0");
        if (size >= ONE_KB && size < ONE_MB) {
            displaySize = String.valueOf(df.format(size / ONE_KB)) + " KB";
        } else if (size >= ONE_MB && size < ONE_GB) {
            displaySize = String.valueOf(df.format(size / ONE_MB)) + " MB";
        } else if (size >= ONE_GB) {
            displaySize = String.valueOf(df.format(size / ONE_GB)) + " GB";
        } else if (size == 0) {
            displaySize = " 0KB";
        } else {
            displaySize = "1KB";
            Log.d("formatSize",
                    String.valueOf(df.format(size)) + " B");
        }
        /*
         * else {
         * displaySize = String.valueOf(df.format(size)) + " B";
         * }
         */
        return displaySize;
    }


    /**
     * 递归删除文件目录
     *
     * @param dir 文件目录
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static void deleteFileDir(File dir) {
        Log.d(TAG,
                "deleteFileDir.dir = " + dir);
        try {
            if (dir.exists() && dir.isDirectory()) {// 判断是文件还是目录
                if (dir.listFiles().length == 0) {// 若目录下没有文件则直接删除
                    dir.delete();
                } else {// 若有则把文件放进数组,并判断是否有下级目录
                    File delFile[] = dir.listFiles();
                    int len = dir.listFiles().length;
                    for (int j = 0; j < len; j++) {
                        if (delFile[j].isDirectory()) {
                            deleteFileDir(delFile[j]);// 递归调用deleteFileDir方法并取得子目录路径
                        } else {
                            boolean isDel = delFile[j].delete();// 删除文件
                            Log.d(TAG,
                                    "deleteFileDir.delFile[" + j + "] = " + delFile[j] + ", isDelete  = " + isDel);
                        }
                    }
                }
                deleteFileDir(dir);// 递归调用
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除单个文件
     *
     * @param file 文件目录
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static void deleteFile(File file) {

        try {
            Log.d(TAG,
                    "deleteFile.file = " + file);
            if (file != null && file.isFile() && file.exists()) {
                file.delete();
                Log.d(TAG,
                        "deleteFile.file = " + file + " Succeed");
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.d(TAG,
                    "deleteFile.file = " + file + " exception=" + e.toString());
        }
    }

    /**
     * 读取指定文件的输出
     */
    public static byte[] getFileOutputBytes(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b,
                        0,
                        n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     * 读取文件内容到字节数组
     *
     * @param file
     * @return
     */
    public static byte[] getFileOutputBytes(File file) {
        byte[] bytes = null;
        if (file.exists()) {
            byte[] buffer;
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            ByteArrayOutputStream byteArrayOutputStream = null;
            try {
                bis = new BufferedInputStream(new FileInputStream(file),
                        DEFAULT_BUFFER_SIZE);
                byteArrayOutputStream = new ByteArrayOutputStream();
                bos = new BufferedOutputStream(byteArrayOutputStream,
                        DEFAULT_BUFFER_SIZE);
                buffer = new byte[DEFAULT_BUFFER_SIZE];
                int len;
                while ((len = bis.read(buffer,
                        0,
                        DEFAULT_BUFFER_SIZE)) != -1) {
                    bos.write(buffer,
                            0,
                            len);
                }
                bos.flush();
                bytes = byteArrayOutputStream.toByteArray();
            } catch (Exception e) {
                return null;
            } finally {
                try {
                    if (bos != null) {
                        bos.close();
                    }
                    if (byteArrayOutputStream != null) {
                        byteArrayOutputStream.close();
                    }
                    if (bis != null) {
                        bis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        Log.d(TAG,
                "getFileOutputBytes.file = " + file + ", bytes.length = " + (bytes == null ? 0 : bytes.length));
        return bytes;
    }

    /**
     * 读取文件内容到字节数组
     *
     * @param file
     * @param offset
     * @param len
     * @return
     */
    public static byte[] getFileOutputBytes(File file,
                                            long offset,
                                            long len) {
        byte[] bytes = null;
        if (file.exists() && offset >= 0 && len > offset && offset < file.length()) {
            RandomAccessFile raf = null;
            ByteArrayOutputStream bos = null;
            try {
                raf = new RandomAccessFile(file,
                        "r");
                raf.seek(offset);
                bos = new ByteArrayOutputStream();
                int b;
                long count = offset;
                while ((b = raf.read()) != -1 && count < len) {
                    bos.write(b);
                    count++;
                }
                bos.flush();
                bytes = bos.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (raf != null) {
                        raf.close();
                    }
                    if (bos != null) {
                        bos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bytes;
    }


    /**
     * 读取指定文件的输出
     */
    public static String getFileOutputString(String path) {
        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(path), 8192);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append("\n").append(line);
            }
            bufferedReader.close();
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 读取指定文件的输出
     *
     * @param file
     * @param encoding
     * @return
     */
    public static String getFileOutputString(File file,
                                             String encoding) {
        String result = null;
        if (file.exists()) {
            char[] buffer;
            BufferedReader br = null;
            InputStreamReader isr = null;
            BufferedWriter bw = null;
            StringWriter sw = new StringWriter();
            try {
                isr = encoding == null ? new InputStreamReader(new FileInputStream(file)) : new InputStreamReader(new FileInputStream(file),
                        encoding);
                br = new BufferedReader(isr);
                bw = new BufferedWriter(sw);
                buffer = new char[DEFAULT_BUFFER_SIZE];
                int len;
                while ((len = br.read(buffer,
                        0,
                        DEFAULT_BUFFER_SIZE)) != -1) {
                    bw.write(buffer,
                            0,
                            len);
                }
                bw.flush();
                result = sw.toString();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bw != null) {
                        bw.close();
                    }
                    if (br != null) {
                        br.close();
                    }
                    if (isr != null) {
                        isr.close();
                    }
                    sw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        Log.d(TAG,
                "readFileToString.file = " + file + ", encoding = " + encoding + ", result = " + result);
        return result;
    }


    /**
     * 将字节写入到文件
     *
     * @param file
     * @param bytes
     * @param offset
     * @return
     */
    public static boolean writeBytesToFile(File file,
                                           byte[] bytes,
                                           long offset) {
        boolean isOk = false;
        if (!file.exists()) {
            try {
                // noinspection ResultOfMethodCallIgnored
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (file.exists() && bytes != null && offset >= 0) {
            RandomAccessFile raf = null;
            try {
                raf = new RandomAccessFile(file,
                        "rw");
                raf.seek(offset);
                raf.write(bytes);
                isOk = true;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (raf != null) {
                        raf.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return isOk;
    }

    /**
     * 写字符串到文件,文件父目录如果不存在,会自动创建
     *
     * @param file
     * @param content
     * @return
     */
    public static boolean writeStringToFile(File file,
                                            String content) {
        return writeStringToFile(file,
                content,
                false);
    }

    /**
     * 写字符串到文件,文件父目录如果不存在,会自动创建
     *
     * @param file
     * @param content
     * @param isAppend
     * @return
     */
    public static boolean writeStringToFile(File file,
                                            String content,
                                            boolean isAppend) {
        boolean isWriteOk = false;
        if (TextUtils.isEmpty(content))
            return false;

        char[] buffer;
        int count = 0;
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            if (!file.exists()) {
                createNewFileAndParentDir(file);
            }
            if (file.exists()) {
                br = new BufferedReader(new StringReader(content));
                bw = new BufferedWriter(new FileWriter(file,
                        isAppend));
                buffer = new char[DEFAULT_BUFFER_SIZE];
                int len;
                while ((len = br.read(buffer,
                        0,
                        DEFAULT_BUFFER_SIZE)) != -1) {
                    bw.write(buffer,
                            0,
                            len);
                    count += len;
                }
                bw.flush();
            }
            isWriteOk = content.length() == count;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return isWriteOk;
    }

    /**
     * 写字节数组到文件,文件父目录如果不存在,会自动创建
     *
     * @param file
     * @param bytes
     * @return
     */
    public static boolean writeBytesToFile(File file,
                                           byte[] bytes) {
        return writeBytesToFile(file,
                bytes,
                false);
    }

    /**
     * 写字节数组到文件,文件父目录如果不存在,会自动创建
     *
     * @param file
     * @param bytes
     * @param isAppend
     * @return
     */
    public static boolean writeBytesToFile(File file,
                                           byte[] bytes,
                                           boolean isAppend) {
        boolean isWriteOk = false;
        byte[] buffer;
        int count = 0;
        ByteArrayInputStream byteArrayInputStream = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            if (!file.exists()) {
                createNewFileAndParentDir(file);
            }
            if (file.exists()) {
                bos = new BufferedOutputStream(new FileOutputStream(file,
                        isAppend),
                        DEFAULT_BUFFER_SIZE);
                byteArrayInputStream = new ByteArrayInputStream(bytes);
                bis = new BufferedInputStream(byteArrayInputStream,
                        DEFAULT_BUFFER_SIZE);
                buffer = new byte[DEFAULT_BUFFER_SIZE];
                int len;
                while ((len = bis.read(buffer,
                        0,
                        DEFAULT_BUFFER_SIZE)) != -1) {
                    bos.write(buffer,
                            0,
                            len);
                    count += len;
                }
                bos.flush();
            }
            isWriteOk = bytes.length == count;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bos != null) {
                    bos.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (byteArrayInputStream != null) {
                    byteArrayInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Log.d(TAG,
                "writeByteArrayToFile.file = " + file + ", bytes.length = " + (bytes == null ? 0 : bytes.length) + ", isAppend = " + isAppend + ", isWriteOk = " + isWriteOk);
        return isWriteOk;
    }

    /**
     * ********************************************创建***************************
     * /**
     * 创建目录
     *
     * @param dir
     * @return
     */
    public static boolean createDir(File dir) {
        boolean isMkdirs = true;
        if (!dir.exists()) {
            isMkdirs = dir.mkdirs();
            Log.d(TAG,
                    "createDir = " + dir + ", isMkdirs = " + isMkdirs);
        }
        return isMkdirs;
    }

    /**
     * 创建文件父目录
     *
     * @param file
     * @return
     */
    public static boolean createParentDir(File file) {
        boolean isMkdirs = true;
        if (!file.exists()) {
            File dir = file.getParentFile();
            isMkdirs = createDir(dir);
        }
        return isMkdirs;
    }

    /**
     * 创建文件及其父目录
     *
     * @param file
     * @return
     */
    @SuppressWarnings("UnusedReturnValue")
    public static boolean createNewFileAndParentDir(File file) {
        @SuppressWarnings("UnusedAssignment")
        boolean isCreateNewFileOk = true;
        isCreateNewFileOk = createParentDir(file);
        // 创建父目录失败,直接返回false,不再创建子文件
        if (isCreateNewFileOk) {
            if (!file.exists()) {
                try {
                    isCreateNewFileOk = file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                    isCreateNewFileOk = false;
                }
            }
        }

        return isCreateNewFileOk;
    }

    /**
     * 根据文件名称获取文件的后缀字符串
     *
     * @param filename 文件的名称,可能带路径
     * @return 文件的后缀字符串
     */
    public static String getFileExtensionFromUrl(String filename) {
        if (!TextUtils.isEmpty(filename)) {
            int dotPos = filename.lastIndexOf('.');
            if (0 <= dotPos) {
                return filename.substring(dotPos + 1);
            }
        }
        return "";
    }

    /**
     * 拷贝文件
     *
     * @param sourceFile 源文件
     * @param destFile   目标文件
     * @return 是否拷贝成功
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static boolean copyFile(File sourceFile,
                                   File destFile) {
        boolean isCopyOk = false;
        byte[] buffer;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        // 如果此时没有文件夹目录就创建
        String canonicalPath = "";
        try {
            canonicalPath = destFile.getCanonicalPath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (!destFile.exists()) {
            if (canonicalPath.lastIndexOf(File.separator) >= 0) {
                canonicalPath = canonicalPath.substring(0,
                        canonicalPath.lastIndexOf(File.separator));
                File dir = new File(canonicalPath);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
            }
        }

        try {
            bis = new BufferedInputStream(new FileInputStream(sourceFile),
                    DEFAULT_BUFFER_SIZE);
            bos = new BufferedOutputStream(new FileOutputStream(destFile),
                    DEFAULT_BUFFER_SIZE);
            buffer = new byte[DEFAULT_BUFFER_SIZE];
            int len;
            while ((len = bis.read(buffer,
                    0,
                    DEFAULT_BUFFER_SIZE)) != -1) {
                bos.write(buffer,
                        0,
                        len);
            }
            bos.flush();
            isCopyOk = sourceFile.length() == destFile.length();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bos != null) {
                    bos.close();
                }
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Log.d(TAG,
                "copyFile.sourceFile = " + sourceFile + ", destFile = " + destFile + ", isCopyOk = " + isCopyOk);
        return isCopyOk;
    }

    /*** 获取文件夹大小 ***/
    public static long getFileSize(File f) {
        long size = 0;
        try {
            File fList[] = f.listFiles();
            for (File file : fList) {
                if (file.isDirectory()) {
                    size = size + getFileSize(file);
                } else {
                    size = size + file.length();
                }
            }
            return size;
        } catch (Exception e) {
            return size;
        }
    }

    /**
     * 获取内存设置
     *
     * @param context
     * @return
     */
    public static int getMemoryCacheSize(Context context) {
        int memoryCacheSize = 0;
        ActivityManager manager = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE));

        int memClass;
        if (manager != null){
            memClass = manager.getMemoryClass();
            memoryCacheSize = (memClass / 3) * 1024 * 1024; // 1/3 of app memory
        }
        // limit
        return memoryCacheSize;
    }

   /* /**
     * 保存APP资源文件到文件系统
     *
     * @param resID      drawable 资源文件
     * @param defineName 定义的文件名
     * @return 文件路径
     */
    /*public static String saveResImgToFile(int resID,
                                          String defineName) {
        String path = null;
        try {
            File Dir = FileConfig.getScreenShortCutDir();
            path = Dir.getAbsolutePath() + File.separator + defineName;
            File file = new File(path);
            // 文件已存在
            Bitmap bitmap = BitmapFactory.decodeResource(WithinApplication.getAppContext()
                            .getResources(),
                    resID);
            boolean isCompressed = ImageUtil.compressSmallImage(bitmap,
                    file,
                    FileConfig.FEED_TEMP_PIC_MAX_SIZE);
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
            }
            if (isCompressed) {
                return file.getAbsolutePath();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path;
    }
            */

    /**
     * 如果存在就文件名追加(count),如report(1)
     *
     * @param file
     * @return
     */
    public static File formatDownloadFileName(File file) {
        if (file.getName()
                .contains(".")) {
            String postfix = file.getName()
                    .substring(file.getName()
                            .lastIndexOf("."));
            if (file.exists() && file.getParentFile()
                    .exists()) {
                int count = 0;
                for (File child : file.getParentFile()
                        .listFiles()) {
                    if (child.getName()
                            .contains(file.getName()
                                    .replace(postfix,
                                            ""))) {
                        count++;
                    }
                }
                String fileName = String.format(file.getName()
                                .replace(postfix,
                                        "") +
                                "(%d)",
                        count) +
                        postfix;
                file = new File(file.getParentFile(),
                        fileName);
            }
        }
        return file;
    }


    public static Intent getFileIntent(File file) {
        Uri uri = Uri.fromFile(file);
        String type = getMIMEType(file);
        Log.i("tag",
                "type=" + type);
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(uri,
                type);
        return intent;
    }

    public static String getMIMEType(File f) {
        @SuppressWarnings("UnusedAssignment")
        String type = "";
        String fName = f.getName();
        /* 取得扩展名 */
        String end = fName.substring(fName.lastIndexOf(".") + 1,
                fName.length())
                .toLowerCase();

        /* 依扩展名的类型决定MimeType */
        switch (end) {
            case "pdf":
                type = "application/pdf";//

                break;
            case "m4a":
            case "mp3":
            case "mid":
            case "xmf":
            case "ogg":
            case "wav":
                type = "audio/*";
                break;
            case "3gp":
            case "mp4":
                type = "video/*";
                break;
            case "jpg":
            case "gif":
            case "png":
            case "jpeg":
            case "bmp":
                type = "image/*";
                break;
            case "apk":
            /* android.permission.INSTALL_PACKAGES */
                type = "application/vnd.android.package-archive";
                break;
            case "pptx":
            case "ppt":
                type = "application/vnd.ms-powerpoint";
                break;
            case "docx":
            case "doc":
                type = "application/vnd.ms-word";
                break;
            case "xlsx":
            case "xls":
                type = "application/vnd.ms-excel";
                break;
            case "txt":
                type = "text/plain";
                break;
            default:
            /* 如果无法直接打开,就跳出软件列表给用户选择 */
                type = "*/*";
                break;
        }
        return type;
    }

    public static int clearCacheFolder(final File dir,
                                       final int numDays) {

        int deletedFiles = 0;
        if (dir != null && dir.isDirectory()) {
            try {
                for (File child : dir.listFiles()) {

                    // first delete subdirectories recursively
                    if (child.isDirectory()) {
                        deletedFiles += clearCacheFolder(child,
                                numDays);
                    }

                    // then delete the files and subdirectories in this dir
                    // only empty directories can be deleted, so subDirs have
                    // been done first
                    if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) {
                        if (child.delete()) {
                            deletedFiles++;
                        }
                    }
                }
            } catch (Exception e) {

            }
        }
        return deletedFiles;
    }



    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static String getDiskCacheDir(Context context,
                                         String uniqueName) {
        // 检查是否安装或存储媒体是内置的,如果是这样的话,试着使用外部缓存dir否则使用内部缓存目录
        boolean isMounted = SdCardUtil.isSdCardAvailable();
        File cacheFile;
        if (isMounted) {
            cacheFile = getExternalCacheDir(context);
            if (!cacheFile.exists()) {
                cacheFile.mkdirs();
            }
            if (!cacheFile.canWrite()) {
                cacheFile = context.getCacheDir();
            }
        } else {
            cacheFile = context.getCacheDir();
        }
        File file = new File(cacheFile.getPath() + File.separator + uniqueName);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取外设的缓存目录:Android/data/cache....<br>
     * 在Froyo之前需要自己建立缓存目录
     */
    public static File getExternalCacheDir(Context context) {

        if (SdCardUtil.isSdCardAvailable()) {

            return context.getExternalCacheDir();


        } else {
            // 使用data/data文件夹
            return context.getCacheDir();
        }
    }


}


================================================
FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/IOUtils.java
================================================

package com.lib.aliocr.utils.io;

import android.annotation.SuppressLint;
import android.os.Build;
import android.util.Log;

import com.lib.aliocr.utils.stream.ByteArrayOutputStream;
import com.lib.aliocr.utils.stream.StringBuilderWriter;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.CharArrayWriter;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 * General IO stream manipulation utilities.
 * <p/>
 * This class provides static utility methods for input/output operations.
 * <ul>
 * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
 * <li>toXxx/read - these methods read data from a stream
 * <li>write - these methods write data to a stream
 * <li>copy - these methods copy all the data from one stream to another
 * <li>contentEquals - these methods compare the content of two streams
 * </ul>
 * <p/>
 * The byte-to-char methods and char-to-byte methods involve a conversion step.
 * Two methods are provided in each case, one that uses the platform default
 * encoding and the other which allows you to specify an encoding. You are
 * encouraged to always specify an encoding because relying on the platform
 * default can lead to unexpected results, for example when moving from
 * development to production.
 * <p/>
 * All the methods in this class that read a stream are buffered internally.
 * This means that there is no cause to use a <code>BufferedInputStream</code>
 * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
 * to be efficient in tests.
 * <p/>
 * Wherever possible, the methods in this class do <em>not</em> flush or close
 * the stream. This is to avoid making non-portable assumptions about the
 * streams' origin and further use. Thus the caller is still responsible for
 * closing streams after use.
 * <p/>
 * Origin of code: Excalibur.
 *
 * @version $Id: IOUtils.java 1326636 2012-04-16 14:54:53Z ggregory $
 */
@SuppressWarnings("WeakerAccess")
public class IOUtils {
    // NOTE: This class is focussed on InputStream, OutputStream, Reader and
    // Writer. Each method should take at least one of these as a parameter,
    // or return one of them.

    private static final int EOF = -1;
    /**
     * The Unix directory separator character.
     */
    public static final char DIR_SEPARATOR_UNIX = '/';
    /**
     * The Windows directory separator character.
     */
    public static final char DIR_SEPARATOR_WINDOWS = '\\';
    /**
     * The system directory separator character.
     */
    public static final char DIR_SEPARATOR = File.separatorChar;
    /**
     * The Unix line separator string.
     */
    public static final String LINE_SEPARATOR_UNIX = "\n";
    /**
     * The Windows line separator string.
     */
    public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
    /**
     * The system line separator string.
     */
    public static final String LINE_SEPARATOR;

    static {
        // avoid security issues
        StringBuilderWriter buf = new StringBuilderWriter(4);
        PrintWriter out = new PrintWriter(buf);
        out.println();
        LINE_SEPARATOR = buf.toString();
        out.close();
    }

    /**
     * The default buffer size ({@value}) to use for
     * {@link #copyLarge(InputStream, OutputStream)}
     * and
     * {@link #copyLarge(Reader, Writer)}
     */
    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

    /**
     * The default buffer size to use for the skip() methods.
     */
    private static final int SKIP_BUFFER_SIZE = 2048;

    // Allocated in the relevant skip method if necessary.
    /*
     * N.B. no need to synchronize these because:
     * - we don't care if the buffer is created multiple times (the data is ignored)
     * - we always use the same size buffer, so if it it is recreated it will still be OK
     * (if the buffer size were variable, we would need to sync. to ensure some other thread
     * did not create a smaller one)
     */
    private static char[] SKIP_CHAR_BUFFER;
    private static byte[] SKIP_BYTE_BUFFER;

    /**
     * Instances should NOT be constructed in standard programming.
     */
    public IOUtils() {
        super();
    }

    //-----------------------------------------------------------------------

    /**
     * Closes a URLConnection.
     *
     * @param conn the connection to close.
     * @since 2.4
     */
    public static void close(URLConnection conn) {
        if (conn instanceof HttpURLConnection) {
            ((HttpURLConnection) conn).disconnect();
        }
    }

    /**
     * Unconditionally close an <code>Reader</code>.
     * <p/>
     * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
     * This is typically used in finally blocks.
     * <p/>
     * Exa
Download .txt
gitextract__z3swy7w/

├── .gitignore
├── LICENSE
├── README.md
├── aliocrlib/
│   ├── .gitignore
│   ├── README.MD
│   ├── build.gradle
│   ├── libs/
│   │   └── BASE64Encoder.jar
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── api14/
│           │   └── cameraview/
│           │       ├── Camera1.java
│           │       └── TextureViewPreview.java
│           ├── api21/
│           │   └── cameraview/
│           │       └── Camera2.java
│           ├── api23/
│           │   └── cameraview/
│           │       └── Camera2Api23.java
│           ├── api9/
│           │   └── cameraview/
│           │       └── SurfaceViewPreview.java
│           ├── base/
│           │   └── cameraview/
│           │       ├── AspectRatio.java
│           │       ├── CameraViewImpl.java
│           │       ├── Constants.java
│           │       ├── PreviewImpl.java
│           │       ├── Size.java
│           │       └── SizeMap.java
│           ├── java/
│           │   ├── cameraview/
│           │   │   ├── CameraView.java
│           │   │   └── DisplayOrientationDetector.java
│           │   └── com/
│           │       └── lib/
│           │           └── aliocr/
│           │               ├── api/
│           │               │   ├── HttpCustomConfig.java
│           │               │   └── MyApiManager.java
│           │               ├── bean/
│           │               │   ├── RepOutput.java
│           │               │   └── ReqInput.java
│           │               ├── callback/
│           │               │   └── OcrCallback.java
│           │               ├── common/
│           │               │   └── Api.java
│           │               ├── contact/
│           │               │   └── OcrContact.java
│           │               ├── http/
│           │               │   ├── config/
│           │               │   │   └── HttpConfig.java
│           │               │   ├── helper/
│           │               │   │   └── HttpHelper.java
│           │               │   ├── https/
│           │               │   │   └── HttpsUtils.java
│           │               │   └── interceptor/
│           │               │       └── HttpLog.java
│           │               ├── modle/
│           │               │   └── OCRModel.java
│           │               ├── presenter/
│           │               │   └── OCRPresenter.java
│           │               ├── utils/
│           │               │   ├── Base64.java
│           │               │   ├── Ocr.java
│           │               │   ├── OcrUtils.java
│           │               │   ├── io/
│           │               │   │   ├── Charsets.java
│           │               │   │   ├── FileUtil.java
│           │               │   │   ├── IOUtils.java
│           │               │   │   ├── SdCardUtil.java
│           │               │   │   └── StringCodingUtils.java
│           │               │   └── stream/
│           │               │       ├── ByteArrayOutputStream.java
│           │               │       ├── ClosedInputStream.java
│           │               │       └── StringBuilderWriter.java
│           │               ├── view/
│           │               │   ├── OCRMainActivity.java
│           │               │   └── OcrLaunchFragment.java
│           │               └── widget/
│           │                   ├── crop/
│           │                   │   ├── Crop.java
│           │                   │   ├── CropImageActivity.java
│           │                   │   ├── CropImageView.java
│           │                   │   ├── CropUtil.java
│           │                   │   ├── HighlightView.java
│           │                   │   ├── ImageViewTouchBase.java
│           │                   │   ├── Log.java
│           │                   │   ├── MonitoredActivity.java
│           │                   │   └── RotateBitmap.java
│           │                   └── popup/
│           │                       └── XinPopWindow.java
│           └── res/
│               ├── anim/
│               │   ├── push_bottom_in.xml
│               │   └── push_bottom_out.xml
│               ├── drawable/
│               │   ├── common_btn_pop_choose_pic_down.xml
│               │   ├── common_btn_pop_choose_pic_mid.xml
│               │   ├── common_btn_pop_choose_pic_up.xml
│               │   ├── crop__selectable_background.xml
│               │   ├── crop__texture.xml
│               │   └── ic_camera.xml
│               ├── drawable-v21/
│               │   └── crop__selectable_background.xml
│               ├── layout/
│               │   ├── activity_ocr_main.xml
│               │   ├── common_item_popup.xml
│               │   ├── common_popwindow.xml
│               │   ├── crop__activity_crop.xml
│               │   ├── crop__layout_done_cancel.xml
│               │   ├── fragment_ocr_launch.xml
│               │   └── surface_view.xml
│               ├── layout-v14/
│               │   └── texture_view.xml
│               └── values/
│                   ├── attrs.xml
│                   ├── colors.xml
│                   ├── dimens.xml
│                   ├── public.xml
│                   ├── strings.xml
│                   └── styles.xml
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── xin/
│           │           └── lockdemo/
│           │               ├── App.java
│           │               ├── GesturePswMainActivity.java
│           │               ├── MainActivity.java
│           │               └── dialog/
│           │                   └── CustomDialog.java
│           └── res/
│               ├── drawable/
│               │   ├── ic_launcher_background.xml
│               │   └── login_shape_bg_finger_change_dialog.xml
│               ├── layout/
│               │   ├── activity_gesture_psw_main.xml
│               │   ├── activity_main.xml
│               │   ├── common_dialog_custom_view_layout.xml
│               │   └── login_finger_change_dialog.xml
│               └── values/
│                   ├── colors.xml
│                   ├── strings.xml
│                   └── styles.xml
├── build.gradle
├── config.gradle
├── fingerprintlib/
│   ├── README.MD
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── lib/
│           │           └── lock/
│           │               └── fingerprint/
│           │                   ├── activities/
│           │                   │   └── FingerprintPswMainActivity.java
│           │                   ├── core/
│           │                   │   ├── CryptoObjectCreator.java
│           │                   │   ├── FingerprintCore.java
│           │                   │   └── MyListener.java
│           │                   ├── dialog/
│           │                   │   └── FingerDialog.java
│           │                   └── utils/
│           │                       ├── FingerContext.java
│           │                       ├── FingerprintUtil.java
│           │                       └── KeyguardLockScreenManager.java
│           └── res/
│               ├── anim/
│               │   ├── anim_shake.xml
│               │   └── cycle.xml
│               ├── drawable/
│               │   └── bg_finger_change_dialog.xml
│               ├── layout/
│               │   ├── activity_fingerprint_psw_main.xml
│               │   ├── finger_dialog_custom_view_layout.xml
│               │   ├── finger_dialog_error.xml
│               │   └── finger_dialog_icon_info.xml
│               └── values/
│                   ├── strings.xml
│                   └── style.xml
├── gesturepswlib/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── lib/
│           │           └── lock/
│           │               └── gesture/
│           │                   ├── activities/
│           │                   │   ├── GestureSettingsActivity.java
│           │                   │   └── GestureVerifyActivity.java
│           │                   ├── bean/
│           │                   │   ├── CellBean.java
│           │                   │   └── CellFactory.java
│           │                   ├── config/
│           │                   │   └── Config.java
│           │                   ├── content/
│           │                   │   ├── DataKeeper.java
│           │                   │   ├── SPManager.java
│           │                   │   ├── SharedPreferencesKeys.java
│           │                   │   └── readme.txt
│           │                   ├── customView/
│           │                   │   ├── DefaultIndicatorHitCellView.java
│           │                   │   ├── DefaultIndicatorLinkedLineView.java
│           │                   │   ├── DefaultIndicatorNormalCellView.java
│           │                   │   ├── DefaultLockerHitCellView.java
│           │                   │   ├── DefaultLockerLinkedLineView.java
│           │                   │   ├── DefaultLockerNormalCellView.java
│           │                   │   ├── DefaultLockerNormalCustomCellView.java
│           │                   │   ├── IHitCellView.java
│           │                   │   ├── IIndicatorLinkedLineView.java
│           │                   │   ├── ILockerLinkedLineView.java
│           │                   │   ├── INormalCellView.java
│           │                   │   ├── OnPatternChangeListener.java
│           │                   │   ├── PatternIndicatorView.java
│           │                   │   └── PatternLockerView.java
│           │                   └── utils/
│           │                       ├── ContextUtils.java
│           │                       ├── PatternHelper.java
│           │                       └── SecurityUtil.java
│           └── res/
│               ├── layout/
│               │   ├── activity_gesture_settings.xml
│               │   └── activity_gesture_verify.xml
│               └── values/
│                   ├── attrs.xml
│                   └── strings.xml
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
Download .txt
SYMBOL INDEX (1073 symbols across 86 files)

FILE: aliocrlib/src/main/api14/cameraview/Camera1.java
  class Camera1 (line 33) | @SuppressWarnings("deprecation")
    method Camera1 (line 74) | Camera1(Callback callback, PreviewImpl preview) {
    method start (line 87) | @Override
    method stop (line 99) | @Override
    method setUpPreview (line 109) | @SuppressLint("NewApi")
    method isCameraOpened (line 129) | @Override
    method setFacing (line 134) | @Override
    method getFacing (line 146) | @Override
    method getSupportedAspectRatios (line 151) | @Override
    method setAspectRatio (line 162) | @Override
    method getAspectRatio (line 181) | @Override
    method setAutoFocus (line 186) | @Override
    method getAutoFocus (line 196) | @Override
    method setFlash (line 205) | @Override
    method getFlash (line 215) | @Override
    method takePicture (line 220) | @Override
    method takePictureInternal (line 239) | void takePictureInternal() {
    method setDisplayOrientation (line 253) | @Override
    method chooseCamera (line 276) | private void chooseCamera() {
    method openCamera (line 287) | private void openCamera() {
    method chooseAspectRatio (line 312) | private AspectRatio chooseAspectRatio() {
    method adjustCameraParameters (line 323) | void adjustCameraParameters() {
    method chooseOptimalSize (line 348) | @SuppressWarnings("SuspiciousNameCombination")
    method releaseCamera (line 375) | private void releaseCamera() {
    method calcDisplayOrientation (line 394) | private int calcDisplayOrientation(int screenOrientationDegrees) {
    method calcCameraRotation (line 413) | private int calcCameraRotation(int screenOrientationDegrees) {
    method isLandscape (line 428) | private boolean isLandscape(int orientationDegrees) {
    method setAutoFocusInternal (line 436) | private boolean setAutoFocusInternal(boolean autoFocus) {
    method setFlashInternal (line 458) | private boolean setFlashInternal(int flash) {

FILE: aliocrlib/src/main/api14/cameraview/TextureViewPreview.java
  class TextureViewPreview (line 31) | @TargetApi(14)
    method TextureViewPreview (line 38) | TextureViewPreview(Context context, ViewGroup parent) {
    method setBufferSize (line 70) | @TargetApi(15)
    method getSurface (line 76) | @Override
    method getSurfaceTexture (line 81) | @Override
    method getView (line 86) | @Override
    method getOutputClass (line 91) | @Override
    method setDisplayOrientation (line 96) | @Override
    method isReady (line 102) | @Override
    method configureTransform (line 111) | void configureTransform() {

FILE: aliocrlib/src/main/api21/cameraview/Camera2.java
  class Camera2 (line 43) | @SuppressWarnings("MissingPermission")
    method onOpened (line 71) | @Override
    method onClosed (line 78) | @Override
    method onDisconnected (line 83) | @Override
    method onError (line 88) | @Override
    method onConfigured (line 99) | @Override
    method onConfigureFailed (line 117) | @Override
    method onClosed (line 122) | @Override
    method onPrecaptureRequired (line 133) | @Override
    method onReady (line 147) | @Override
    method onImageAvailable (line 157) | @Override
    method Camera2 (line 199) | Camera2(Callback callback, PreviewImpl preview, Context context) {
    method start (line 210) | @Override
    method stop (line 221) | @Override
    method isCameraOpened (line 237) | @Override
    method setFacing (line 242) | @Override
    method getFacing (line 254) | @Override
    method getSupportedAspectRatios (line 259) | @Override
    method setAspectRatio (line 264) | @Override
    method getAspectRatio (line 281) | @Override
    method setAutoFocus (line 286) | @Override
    method getAutoFocus (line 305) | @Override
    method setFlash (line 310) | @Override
    method getFlash (line 330) | @Override
    method takePicture (line 335) | @Override
    method setDisplayOrientation (line 344) | @Override
    method chooseCameraIdByFacing (line 355) | private boolean chooseCameraIdByFacing() {
    method collectCameraInfo (line 413) | private void collectCameraInfo() {
    method collectPictureSizes (line 440) | protected void collectPictureSizes(SizeMap sizes, StreamConfigurationM...
    method prepareImageReader (line 446) | private void prepareImageReader() {
    method startOpeningCamera (line 460) | private void startOpeningCamera() {
    method startCaptureSession (line 473) | void startCaptureSession() {
    method chooseOptimalSize (line 495) | private Size chooseOptimalSize() {
    method updateAutoFocus (line 521) | void updateAutoFocus() {
    method updateFlash (line 544) | void updateFlash() {
    method lockFocus (line 582) | private void lockFocus() {
    method captureStillPicture (line 596) | void captureStillPicture() {
    method unlockFocus (line 657) | void unlockFocus() {
    class PictureCaptureCallback (line 677) | private static abstract class PictureCaptureCallback
      method PictureCaptureCallback (line 689) | PictureCaptureCallback() {
      method setState (line 692) | void setState(int state) {
      method onCaptureProgressed (line 696) | @Override
      method onCaptureCompleted (line 702) | @Override
      method process (line 708) | private void process(@NonNull CaptureResult result) {
      method onReady (line 751) | public abstract void onReady();
      method onPrecaptureRequired (line 756) | public abstract void onPrecaptureRequired();

FILE: aliocrlib/src/main/api23/cameraview/Camera2Api23.java
  class Camera2Api23 (line 25) | @TargetApi(23)
    method Camera2Api23 (line 28) | Camera2Api23(Callback callback, PreviewImpl preview, Context context) {
    method collectPictureSizes (line 32) | @Override

FILE: aliocrlib/src/main/api9/cameraview/SurfaceViewPreview.java
  class SurfaceViewPreview (line 29) | class SurfaceViewPreview extends PreviewImpl {
    method SurfaceViewPreview (line 33) | SurfaceViewPreview(Context context, ViewGroup parent) {
    method getSurface (line 59) | @Override
    method getSurfaceHolder (line 64) | @Override
    method getView (line 69) | @Override
    method getOutputClass (line 74) | @Override
    method setDisplayOrientation (line 79) | @Override
    method isReady (line 83) | @Override

FILE: aliocrlib/src/main/base/cameraview/AspectRatio.java
  class AspectRatio (line 27) | public class AspectRatio implements Comparable<AspectRatio>, Parcelable {
    method of (line 43) | public static AspectRatio of(int x, int y) {
    method parse (line 71) | public static AspectRatio parse(String s) {
    method AspectRatio (line 85) | private AspectRatio(int x, int y) {
    method getX (line 90) | public int getX() {
    method getY (line 94) | public int getY() {
    method matches (line 98) | public boolean matches(Size size) {
    method equals (line 105) | @Override
    method toString (line 120) | @Override
    method toFloat (line 125) | public float toFloat() {
    method hashCode (line 129) | @Override
    method compareTo (line 135) | @Override
    method inverse (line 148) | public AspectRatio inverse() {
    method gcd (line 153) | private static int gcd(int a, int b) {
    method describeContents (line 162) | @Override
    method writeToParcel (line 167) | @Override
    method createFromParcel (line 176) | @Override
    method newArray (line 183) | @Override

FILE: aliocrlib/src/main/base/cameraview/CameraViewImpl.java
  class CameraViewImpl (line 23) | abstract class CameraViewImpl {
    method CameraViewImpl (line 29) | CameraViewImpl(Callback callback, PreviewImpl preview) {
    method getView (line 34) | View getView() {
    method start (line 41) | abstract boolean start();
    method stop (line 43) | abstract void stop();
    method isCameraOpened (line 45) | abstract boolean isCameraOpened();
    method setFacing (line 47) | abstract void setFacing(int facing);
    method getFacing (line 49) | abstract int getFacing();
    method getSupportedAspectRatios (line 51) | abstract Set<AspectRatio> getSupportedAspectRatios();
    method setAspectRatio (line 56) | abstract boolean setAspectRatio(AspectRatio ratio);
    method getAspectRatio (line 58) | abstract AspectRatio getAspectRatio();
    method setAutoFocus (line 60) | abstract void setAutoFocus(boolean autoFocus);
    method getAutoFocus (line 62) | abstract boolean getAutoFocus();
    method setFlash (line 64) | abstract void setFlash(int flash);
    method getFlash (line 66) | abstract int getFlash();
    method takePicture (line 68) | abstract void takePicture();
    method setDisplayOrientation (line 70) | abstract void setDisplayOrientation(int displayOrientation);
    type Callback (line 72) | interface Callback {
      method onCameraOpened (line 74) | void onCameraOpened();
      method onCameraClosed (line 76) | void onCameraClosed();
      method onPictureTaken (line 78) | void onPictureTaken(byte[] data);

FILE: aliocrlib/src/main/base/cameraview/Constants.java
  type Constants (line 20) | public interface Constants {

FILE: aliocrlib/src/main/base/cameraview/PreviewImpl.java
  class PreviewImpl (line 27) | abstract class PreviewImpl {
    type Callback (line 29) | interface Callback {
      method onSurfaceChanged (line 30) | void onSurfaceChanged();
    method setCallback (line 39) | void setCallback(Callback callback) {
    method getSurface (line 43) | abstract Surface getSurface();
    method getView (line 45) | abstract View getView();
    method getOutputClass (line 47) | abstract Class getOutputClass();
    method setDisplayOrientation (line 49) | abstract void setDisplayOrientation(int displayOrientation);
    method isReady (line 51) | abstract boolean isReady();
    method dispatchSurfaceChanged (line 53) | protected void dispatchSurfaceChanged() {
    method getSurfaceHolder (line 57) | SurfaceHolder getSurfaceHolder() {
    method getSurfaceTexture (line 61) | Object getSurfaceTexture() {
    method setBufferSize (line 65) | void setBufferSize(int width, int height) {
    method setSize (line 68) | void setSize(int width, int height) {
    method getWidth (line 73) | int getWidth() {
    method getHeight (line 77) | int getHeight() {

FILE: aliocrlib/src/main/base/cameraview/Size.java
  class Size (line 24) | public class Size implements Comparable<Size> {
    method Size (line 35) | public Size(int width, int height) {
    method getWidth (line 40) | public int getWidth() {
    method getHeight (line 44) | public int getHeight() {
    method equals (line 48) | @Override
    method toString (line 63) | @Override
    method hashCode (line 68) | @Override
    method compareTo (line 74) | @Override

FILE: aliocrlib/src/main/base/cameraview/SizeMap.java
  class SizeMap (line 28) | class SizeMap {
    method add (line 38) | public boolean add(Size size) {
    method remove (line 62) | public void remove(AspectRatio ratio) {
    method ratios (line 66) | Set<AspectRatio> ratios() {
    method sizes (line 70) | SortedSet<Size> sizes(AspectRatio ratio) {
    method clear (line 74) | void clear() {
    method isEmpty (line 78) | boolean isEmpty() {

FILE: aliocrlib/src/main/java/cameraview/CameraView.java
  class CameraView (line 41) | public class CameraView extends FrameLayout {
    method CameraView (line 83) | public CameraView(Context context) {
    method CameraView (line 87) | public CameraView(Context context, AttributeSet attrs) {
    method CameraView (line 91) | @SuppressWarnings("WrongConstant")
    method createPreviewImpl (line 132) | @NonNull
    method onAttachedToWindow (line 143) | @Override
    method onDetachedFromWindow (line 151) | @Override
    method onMeasure (line 159) | @Override
    method onSaveInstanceState (line 219) | @Override
    method onRestoreInstanceState (line 229) | @Override
    method start (line 247) | public void start() {
    method stop (line 262) | public void stop() {
    method isCameraOpened (line 269) | public boolean isCameraOpened() {
    method addCallback (line 279) | public void addCallback(@NonNull Callback callback) {
    method removeCallback (line 289) | public void removeCallback(@NonNull Callback callback) {
    method setAdjustViewBounds (line 298) | public void setAdjustViewBounds(boolean adjustViewBounds) {
    method getAdjustViewBounds (line 310) | public boolean getAdjustViewBounds() {
    method setFacing (line 320) | public void setFacing(@Facing int facing) {
    method getFacing (line 329) | @Facing
    method getSupportedAspectRatios (line 338) | public Set<AspectRatio> getSupportedAspectRatios() {
    method setAspectRatio (line 347) | public void setAspectRatio(@NonNull AspectRatio ratio) {
    method getAspectRatio (line 358) | @Nullable
    method setAutoFocus (line 370) | public void setAutoFocus(boolean autoFocus) {
    method getAutoFocus (line 380) | public boolean getAutoFocus() {
    method setFlash (line 389) | public void setFlash(@Flash int flash) {
    method getFlash (line 398) | @Flash
    method takePicture (line 408) | public void takePicture() {
    class CallbackBridge (line 412) | private class CallbackBridge implements CameraViewImpl.Callback {
      method CallbackBridge (line 418) | CallbackBridge() {
      method add (line 421) | public void add(Callback callback) {
      method remove (line 425) | public void remove(Callback callback) {
      method onCameraOpened (line 429) | @Override
      method onCameraClosed (line 440) | @Override
      method onPictureTaken (line 447) | @Override
      method reserveRequestLayoutOnOpen (line 454) | public void reserveRequestLayoutOnOpen() {
    class SavedState (line 459) | protected static class SavedState extends BaseSavedState {
      method SavedState (line 471) | @SuppressWarnings("WrongConstant")
      method SavedState (line 480) | public SavedState(Parcelable superState) {
      method writeToParcel (line 484) | @Override
      method createFromParcel (line 496) | @Override
      method newArray (line 501) | @Override
    class Callback (line 513) | @SuppressWarnings("UnusedParameters")
      method onCameraOpened (line 521) | public void onCameraOpened(CameraView cameraView) {
      method onCameraClosed (line 529) | public void onCameraClosed(CameraView cameraView) {
      method onPictureTaken (line 538) | public void onPictureTaken(CameraView cameraView, byte[] data) {

FILE: aliocrlib/src/main/java/cameraview/DisplayOrientationDetector.java
  class DisplayOrientationDetector (line 29) | abstract class DisplayOrientationDetector {
    method DisplayOrientationDetector (line 47) | public DisplayOrientationDetector(Context context) {
    method enable (line 68) | public void enable(Display display) {
    method disable (line 75) | public void disable() {
    method getLastKnownDisplayOrientation (line 80) | public int getLastKnownDisplayOrientation() {
    method dispatchOnDisplayOrientationChanged (line 84) | void dispatchOnDisplayOrientationChanged(int displayOrientation) {
    method onDisplayOrientationChanged (line 94) | public abstract void onDisplayOrientationChanged(int displayOrientation);

FILE: aliocrlib/src/main/java/com/lib/aliocr/api/HttpCustomConfig.java
  class HttpCustomConfig (line 15) | public class HttpCustomConfig extends HttpConfig {
    method getCustomBuilder (line 16) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/api/MyApiManager.java
  type MyApiManager (line 22) | public interface MyApiManager {
    method authCard (line 25) | @POST(path)

FILE: aliocrlib/src/main/java/com/lib/aliocr/bean/RepOutput.java
  class RepOutput (line 13) | public class RepOutput implements Serializable {
    class faceRect (line 31) | static class faceRect implements Serializable {
      method getAngle (line 37) | public double getAngle() {
      method setAngle (line 41) | public void setAngle(int angle) {
      method getCenter (line 45) | public Center getCenter() {
      method setCenter (line 49) | public void setCenter(Center center) {
      method getSize (line 53) | public Size getSize() {
      method setSize (line 57) | public void setSize(Size size) {
      class Center (line 61) | static class Center implements Serializable {
        method getX (line 66) | public double getX() {
        method setX (line 70) | public void setX(double x) {
        method getY (line 74) | public double getY() {
        method setY (line 78) | public void setY(double y) {
        method toString (line 82) | @Override
      class Size (line 91) | static class Size implements Serializable {
        method getHeight (line 96) | public double getHeight() {
        method setHeight (line 100) | public void setHeight(double height) {
        method getWidth (line 104) | public double getWidth() {
        method setWidth (line 108) | public void setWidth(double width) {
        method toString (line 113) | @Override
      method toString (line 122) | @Override
    method getAddress (line 133) | public String getAddress() {
    method setAddress (line 137) | public void setAddress(String address) {
    method getConfig_str (line 141) | public String getConfig_str() {
    method setConfig_str (line 145) | public void setConfig_str(String config_str) {
    method getFace_rect (line 149) | public faceRect getFace_rect() {
    method setFace_rect (line 153) | public void setFace_rect(faceRect face_rect) {
    method getName (line 157) | public String getName() {
    method setName (line 161) | public void setName(String name) {
    method getNationality (line 165) | public String getNationality() {
    method setNationality (line 169) | public void setNationality(String nationality) {
    method getNum (line 173) | public String getNum() {
    method setNum (line 177) | public void setNum(String num) {
    method getSex (line 181) | public String getSex() {
    method setSex (line 185) | public void setSex(String sex) {
    method getBirth (line 189) | public String getBirth() {
    method setBirth (line 193) | public void setBirth(String birth) {
    method getStart_date (line 197) | public String getStart_date() {
    method setStart_date (line 201) | public void setStart_date(String start_date) {
    method getEnd_date (line 205) | public String getEnd_date() {
    method setEnd_date (line 209) | public void setEnd_date(String end_date) {
    method getIssue (line 213) | public String getIssue() {
    method setIssue (line 217) | public void setIssue(String issue) {
    method isSuccess (line 221) | public boolean isSuccess() {
    method setSuccess (line 225) | public void setSuccess(boolean success) {
    method toString (line 230) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/bean/ReqInput.java
  class ReqInput (line 13) | public class ReqInput implements Serializable {
    method getImage (line 20) | public String getImage() {
    method setImage (line 24) | public void setImage(String image) {
    method getConfigure (line 28) | public String getConfigure() {
    method setConfigure (line 32) | public void setConfigure(String configure) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/callback/OcrCallback.java
  type OcrCallback (line 12) | public interface OcrCallback {
    method onPicResult (line 15) | void onPicResult(String picPath);
    method onPicError (line 17) | void onPicError();

FILE: aliocrlib/src/main/java/com/lib/aliocr/common/Api.java
  type Api (line 11) | public interface Api {

FILE: aliocrlib/src/main/java/com/lib/aliocr/contact/OcrContact.java
  type OcrContact (line 18) | public interface OcrContact {
    type V (line 20) | interface V {
      method getActivity (line 22) | Activity getActivity();
    type P (line 25) | interface P {
      method onPictureTaken (line 26) | void onPictureTaken(final byte[] data );
      method request (line 28) | void request(boolean isFace, String imgPath);
    type M (line 32) | interface M {
      method AuthCard (line 34) | Observable<RepOutput> AuthCard(boolean isFace, String imgPath);

FILE: aliocrlib/src/main/java/com/lib/aliocr/http/config/HttpConfig.java
  class HttpConfig (line 24) | public abstract class HttpConfig {
    method getDefaultBuilder (line 33) | private OkHttpClient.Builder getDefaultBuilder() {
    method getCustomBuilder (line 77) | @SuppressWarnings("SameReturnValue")
    method build (line 84) | public OkHttpClient build() {
    method getHttpClient (line 102) | public OkHttpClient getHttpClient() {
    method setHttpClient (line 111) | public void setHttpClient(OkHttpClient httpClient) {
    class SafeHostnameVerifier (line 123) | private static class SafeHostnameVerifier implements HostnameVerifier {
      method verify (line 124) | @SuppressLint("BadHostnameVerifier")

FILE: aliocrlib/src/main/java/com/lib/aliocr/http/helper/HttpHelper.java
  class HttpHelper (line 18) | public class HttpHelper {
    method HttpHelper (line 25) | private HttpHelper() {
    method getInstance (line 33) | public static HttpHelper getInstance() {
    method getRetrofit (line 37) | public  Retrofit getRetrofit(String url) {
    class LazyHolder (line 47) | private static final class LazyHolder {

FILE: aliocrlib/src/main/java/com/lib/aliocr/http/https/HttpsUtils.java
  class HttpsUtils (line 35) | @SuppressWarnings("WeakerAccess")
    class SSLParams (line 38) | public static class SSLParams {
    method getSslSocketFactory (line 43) | public static SSLParams getSslSocketFactory() {
    method getSslSocketFactory (line 51) | public static SSLParams getSslSocketFactory(X509TrustManager trustMana...
    method getSslSocketFactory (line 59) | public static SSLParams getSslSocketFactory(InputStream... certificate...
    method getSslSocketFactory (line 68) | public static SSLParams getSslSocketFactory(InputStream bksFile, Strin...
    method getSslSocketFactory (line 77) | public static SSLParams getSslSocketFactory(InputStream bksFile, Strin...
    method getSslSocketFactoryBase (line 81) | private static SSLParams getSslSocketFactoryBase(X509TrustManager trus...
    method prepareKeyManager (line 111) | private static KeyManager[] prepareKeyManager(InputStream bksFile, Str...
    method prepareTrustManager (line 125) | private static TrustManager[] prepareTrustManager(InputStream... certi...
    method chooseTrustManager (line 157) | private static X509TrustManager chooseTrustManager(TrustManager[] trus...
    method checkClientTrusted (line 171) | @SuppressLint("TrustAllX509TrustManager")
    method checkServerTrusted (line 176) | @SuppressLint("TrustAllX509TrustManager")
    method getAcceptedIssuers (line 181) | @Override
    method verify (line 193) | @SuppressLint("BadHostnameVerifier")

FILE: aliocrlib/src/main/java/com/lib/aliocr/http/interceptor/HttpLog.java
  class HttpLog (line 33) | public class HttpLog implements Interceptor {
    type Level (line 37) | public enum Level {
    method setPrintLevel (line 47) | public void setPrintLevel(Level printLevel) {
    method setPrintBinaryBody (line 51) | public void setPrintBinaryBody(boolean printBinaryBody) {
    method intercept (line 55) | @Override
    method logForRequest (line 80) | private void logForRequest(Request request, Connection connection) {
    method logForResponse (line 133) | private Response logForResponse(Response response, long tookMs) {
    method isPlaintext (line 179) | private static boolean isPlaintext(MediaType mediaType) {
    method bodyToString (line 193) | private String bodyToString(Request request) {
    method getCharset (line 210) | private static Charset getCharset(MediaType contentType) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/modle/OCRModel.java
  class OCRModel (line 28) | public class OCRModel implements OcrContact.M{
    method AuthCard (line 31) | public Observable<RepOutput> AuthCard(final boolean isFace, final Stri...

FILE: aliocrlib/src/main/java/com/lib/aliocr/presenter/OCRPresenter.java
  class OCRPresenter (line 33) | public class OCRPresenter implements OcrContact.P {
    method OCRPresenter (line 38) | public OCRPresenter(OcrContact.V view) {
    method onPictureTaken (line 43) | public void onPictureTaken(final byte[] data) {
    method request (line 75) | public void request(boolean isFace, final String imgPath) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/Base64.java
  class Base64 (line 11) | public class Base64 {
    method getAuthor (line 14) | public static String getAuthor(String secretKey,String author) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/Ocr.java
  class Ocr (line 33) | public class Ocr {
    method doOcr (line 46) | public static void doOcr(final Activity activity, final Fragment fragm...
    method onCropImgResult (line 82) | public static void onCropImgResult(Activity activity, Fragment fragmen...
    method onPickImgResult (line 102) | public static Uri onPickImgResult(Activity activity, int requestCode, ...
    method onBackResult (line 124) | public static void onBackResult(Activity activity, int requestCode, in...
    method onRequestPermissionsResult (line 134) | public static void onRequestPermissionsResult(Activity activity, int r...
    method handleImgShot (line 154) | public static void handleImgShot(Activity activity, Uri uri) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/OcrUtils.java
  class OcrUtils (line 46) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method getImageStr (line 48) | public static String getImageStr(String imgFile) {
    method byte2bitmap (line 64) | public static Bitmap byte2bitmap(byte[] data) {
    method saveBitmap (line 78) | public static boolean saveBitmap(Bitmap bitmap,
    method saveBitmap (line 93) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method compressSmallImage (line 143) | public static boolean compressSmallImage(Bitmap image,
    method compressSmallImage (line 161) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method getPath (line 231) | public static String getPath(Context context,
    method getDataColumn (line 300) | public static String getDataColumn(Context context,
    method isExternalStorageDocument (line 331) | public static boolean isExternalStorageDocument(Uri uri) {
    method isDownloadsDocument (line 335) | public static boolean isDownloadsDocument(Uri uri) {
    method isMediaDocument (line 339) | public static boolean isMediaDocument(Uri uri) {
    method isGooglePhotosUri (line 343) | public static boolean isGooglePhotosUri(Uri uri) {
    method getGalleryIntent (line 348) | private static Intent getGalleryIntent(Context context, boolean includ...
    method getGalleryIntents (line 377) | private static List<Intent> getGalleryIntents(@NonNull
    method isReadExternalStoragePermissionsRequired (line 404) | public static boolean isReadExternalStoragePermissionsRequired(@NonNul...
    method isUriRequiresPermissions (line 420) | public static boolean isUriRequiresPermissions(@NonNull Context contex...
    method beginCrop (line 432) | public static void beginCrop(Uri source, Activity activity, Fragment f...

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/Charsets.java
  class Charsets (line 9) | @SuppressWarnings("WeakerAccess")
    method toCharset (line 11) | public static Charset toCharset(Charset charset) {
    method toCharset (line 14) | public static Charset toCharset(String charset) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/FileUtil.java
  class FileUtil (line 41) | @SuppressWarnings("WeakerAccess")
    method formatSize (line 58) | public static String formatSize(long size) {
    method deleteFileDir (line 91) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method deleteFile (line 124) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method getFileOutputBytes (line 145) | public static byte[] getFileOutputBytes(String filePath) {
    method getFileOutputBytes (line 173) | public static byte[] getFileOutputBytes(File file) {
    method getFileOutputBytes (line 228) | public static byte[] getFileOutputBytes(File file,
    method getFileOutputString (line 270) | public static String getFileOutputString(String path) {
    method getFileOutputString (line 294) | public static String getFileOutputString(File file,
    method writeBytesToFile (line 352) | public static boolean writeBytesToFile(File file,
    method writeStringToFile (line 394) | public static boolean writeStringToFile(File file,
    method writeStringToFile (line 409) | public static boolean writeStringToFile(File file,
    method writeBytesToFile (line 466) | public static boolean writeBytesToFile(File file,
    method writeBytesToFile (line 481) | public static boolean writeBytesToFile(File file,
    method createDir (line 544) | public static boolean createDir(File dir) {
    method createParentDir (line 560) | public static boolean createParentDir(File file) {
    method createNewFileAndParentDir (line 575) | @SuppressWarnings("UnusedReturnValue")
    method getFileExtensionFromUrl (line 601) | public static String getFileExtensionFromUrl(String filename) {
    method copyFile (line 618) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method getFileSize (line 679) | public static long getFileSize(File f) {
    method getMemoryCacheSize (line 702) | public static int getMemoryCacheSize(Context context) {
    method formatDownloadFileName (line 755) | public static File formatDownloadFileName(File file) {
    method getFileIntent (line 787) | public static Intent getFileIntent(File file) {
    method getMIMEType (line 800) | public static String getMIMEType(File f) {
    method clearCacheFolder (line 861) | public static int clearCacheFolder(final File dir,
    method getDiskCacheDir (line 893) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method getExternalCacheDir (line 921) | public static File getExternalCacheDir(Context context) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/IOUtils.java
  class IOUtils (line 76) | @SuppressWarnings("WeakerAccess")
    method IOUtils (line 144) | public IOUtils() {
    method close (line 156) | public static void close(URLConnection conn) {
    method closeQuietly (line 185) | public static void closeQuietly(Reader input) {
    method closeQuietly (line 211) | public static void closeQuietly(Writer output) {
    method closeQuietly (line 238) | public static void closeQuietly(InputStream input) {
    method closeQuietly (line 266) | public static void closeQuietly(OutputStream output) {
    method closeQuietly (line 293) | public static void closeQuietly(Closeable closeable) {
    method closeQuietly (line 326) | public static void closeQuietly(Socket sock) {
    method closeQuietly (line 359) | public static void closeQuietly(Selector selector) {
    method closeQuietly (line 392) | public static void closeQuietly(ServerSocket sock) {
    method toBufferedInputStream (line 423) | public static InputStream toBufferedInputStream(InputStream input) thr...
    method toBufferedReader (line 435) | public static BufferedReader toBufferedReader(Reader reader) {
    method toByteArray (line 453) | public static byte[] toByteArray(InputStream input) throws IOException {
    method toByteArray (line 460) | public static byte[] toByteArray(Object input) {
    method toByteArray (line 494) | public static byte[] toByteArray(InputStream input, long size) throws ...
    method toByteArray (line 515) | public static byte[] toByteArray(InputStream input, int size) throws I...
    method toByteArray (line 552) | public static byte[] toByteArray(Reader input) throws IOException {
    method toByteArray (line 570) | public static byte[] toByteArray(Reader input, Charset encoding) throw...
    method toByteArray (line 595) | public static byte[] toByteArray(Reader input, String encoding) throws...
    method toByteArray (line 611) | @Deprecated
    method toByteArray (line 625) | public static byte[] toByteArray(URI uri) throws IOException {
    method toByteArray (line 638) | public static byte[] toByteArray(URL url) throws IOException {
    method toByteArray (line 656) | public static byte[] toByteArray(URLConnection urlConn) throws IOExcep...
    method toCharArray (line 684) | public static char[] toCharArray(InputStream is) throws IOException {
    method toCharArray (line 702) | public static char[] toCharArray(InputStream is, Charset encoding)
    method toCharArray (line 728) | public static char[] toCharArray(InputStream is, String encoding) thro...
    method toCharArray (line 744) | public static char[] toCharArray(Reader input) throws IOException {
    method toString (line 765) | public static String toString(InputStream input) throws IOException {
    method toString (line 784) | public static String toString(InputStream input, Charset encoding) thr...
    method toString (line 808) | public static String toString(InputStream input, String encoding)
    method toString (line 824) | public static String toString(Reader input) throws IOException {
    method toString (line 838) | public static String toString(URI uri) throws IOException {
    method toString (line 851) | public static String toString(URI uri, Charset encoding) throws IOExce...
    method toString (line 866) | public static String toString(URI uri, String encoding) throws IOExcep...
    method toString (line 878) | public static String toString(URL url) throws IOException {
    method toString (line 891) | public static String toString(URL url, Charset encoding) throws IOExce...
    method toString (line 914) | public static String toString(URL url, String encoding) throws IOExcep...
    method toString (line 928) | @Deprecated
    method toString (line 946) | public static String toString(byte[] input, String encoding) throws IO...
    method toReader (line 953) | public static Reader toReader(String str){
    method readLines (line 973) | public static List<String> readLines(InputStream input) throws IOExcep...
    method readLines (line 991) | public static List<String> readLines(InputStream input, Charset encodi...
    method readLines (line 1015) | public static List<String> readLines(InputStream input, String encodin...
    method readLines (line 1032) | public static List<String> readLines(Reader input) throws IOException {
    method toInputStream (line 1053) | public static InputStream toInputStream(CharSequence input) {
    method toInputStream (line 1070) | public static InputStream toInputStream(CharSequence input, Charset en...
    method toInputStream (line 1089) | @SuppressWarnings("RedundantThrows")
    method toInputStream (line 1104) | public static InputStream toInputStream(String input) {
    method toInputStream (line 1117) | public static InputStream toInputStream(String input, Charset encoding) {
    method toInputStream (line 1136) | @SuppressWarnings("RedundantThrows")
    method toObject (line 1143) | public static Object toObject(byte[] input) {
    method write (line 1174) | public static void write(byte[] data, OutputStream output)
    method write (line 1194) | public static void write(byte[] data, Writer output) throws IOException {
    method write (line 1212) | @SuppressLint("ObsoleteSdkInt")
    method write (line 1242) | public static void write(byte[] data, Writer output, String encoding) ...
    method write (line 1260) | public static void write(char[] data, Writer output) throws IOException {
    method write (line 1280) | public static void write(char[] data, OutputStream output)
    method write (line 1300) | public static void write(char[] data, OutputStream output, Charset enc...
    method write (line 1326) | public static void write(char[] data, OutputStream output, String enco...
    method write (line 1343) | public static void write(CharSequence data, Writer output) throws IOEx...
    method write (line 1362) | public static void write(CharSequence data, OutputStream output)
    method write (line 1380) | public static void write(CharSequence data, OutputStream output, Chars...
    method write (line 1404) | public static void write(CharSequence data, OutputStream output, Strin...
    method write (line 1420) | public static void write(String data, Writer output) throws IOException {
    method write (line 1439) | public static void write(String data, OutputStream output)
    method write (line 1457) | public static void write(String data, OutputStream output, Charset enc...
    method write (line 1481) | public static void write(String data, OutputStream output, String enco...
    method write (line 1499) | @Deprecated
    method write (line 1521) | @Deprecated
    method write (line 1547) | @Deprecated
    method writeLines (line 1569) | public static void writeLines(Collection<?> lines, String lineEnding,
    method writeLines (line 1587) | public static void writeLines(Collection<?> lines, String lineEnding, ...
    method writeLines (line 1622) | public static void writeLines(Collection<?> lines, String lineEnding,
    method writeLines (line 1638) | public static void writeLines(Collection<?> lines, String lineEnding,
    method copy (line 1676) | @SuppressWarnings("UnusedReturnValue")
    method copyLarge (line 1701) | public static long copyLarge(InputStream input, OutputStream output)
    method copyLarge (line 1722) | public static long copyLarge(InputStream input, OutputStream output, b...
    method copyLarge (line 1752) | public static long copyLarge(InputStream input, OutputStream output, l...
    method copyLarge (line 1776) | public static long copyLarge(InputStream input, OutputStream output,
    method copy (line 1817) | public static void copy(InputStream input, Writer output)
    method copy (line 1838) | public static void copy(InputStream input, Writer output, Charset enco...
    method copy (line 1864) | public static void copy(InputStream input, Writer output, String encod...
    method copy (line 1889) | @SuppressWarnings("UnusedReturnValue")
    method copyLarge (line 1913) | public static long copyLarge(Reader input, Writer output) throws IOExc...
    method copyLarge (line 1932) | public static long copyLarge(Reader input, Writer output, char[] buffe...
    method copyLarge (line 1961) | public static long copyLarge(Reader input, Writer output, final long i...
    method copyLarge (line 1985) | public static long copyLarge(Reader input, Writer output, final long i...
    method copy (line 2029) | public static void copy(Reader input, OutputStream output)
    method copy (line 2057) | public static void copy(Reader input, OutputStream output, Charset enc...
    method copy (line 2090) | public static void copy(Reader input, OutputStream output, String enco...
    method contentEquals (line 2111) | public static boolean contentEquals(InputStream input1, InputStream in...
    method contentEquals (line 2148) | public static boolean contentEquals(Reader input1, Reader input2)
    method contentEqualsIgnoreEOL (line 2181) | public static boolean contentEqualsIgnoreEOL(Reader input1, Reader inp...
    method skip (line 2209) | public static long skip(InputStream input, long toSkip) throws IOExcep...
    method skip (line 2246) | public static long skip(Reader input, long toSkip) throws IOException {
    method skipFully (line 2283) | public static void skipFully(InputStream input, long toSkip) throws IO...
    method skipFully (line 2307) | public static void skipFully(Reader input, long toSkip) throws IOExcep...
    method read (line 2329) | public static int read(Reader input, char[] buffer, int offset, int le...
    method read (line 2357) | public static int read(Reader input, char[] buffer) throws IOException {
    method read (line 2375) | public static int read(InputStream input, byte[] buffer, int offset, i...
    method read (line 2403) | public static int read(InputStream input, byte[] buffer) throws IOExce...
    method readFully (line 2422) | @SuppressWarnings("SameParameterValue")
    method readFully (line 2443) | public static void readFully(Reader input, char[] buffer) throws IOExc...
    method readFully (line 2462) | @SuppressWarnings("SameParameterValue")
    method readFully (line 2483) | public static void readFully(InputStream input, byte[] buffer) throws ...

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/SdCardUtil.java
  class SdCardUtil (line 27) | public class SdCardUtil {
    method isSdCardAvailable (line 34) | public static boolean isSdCardAvailable() {
    method getStatFs (line 41) | public static StatFs getStatFs(String path) {
    method getDataPath (line 48) | public static String getDataPath() {
    method getNormalSDCardPath (line 56) | public static String getNormalSDCardPath() {
    method getSDCardPath (line 63) | public static String getSDCardPath() {
    method getSDCardPathEx (line 103) | public static ArrayList<String> getSDCardPathEx() {
    method getAvailableSize (line 142) | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    method getSDCardInfo (line 162) | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    class SDCardInfo (line 194) | public static class SDCardInfo {
      method toString (line 206) | @Override
    method clearWebViewCache (line 226) | @SuppressLint("DefaultLocale")

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/io/StringCodingUtils.java
  class StringCodingUtils (line 12) | public class StringCodingUtils {
    method getBytes (line 14) | public static byte[] getBytes(String src, Charset charSet) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/stream/ByteArrayOutputStream.java
  class ByteArrayOutputStream (line 39) | public class ByteArrayOutputStream extends OutputStream {
    method ByteArrayOutputStream (line 59) | public ByteArrayOutputStream() {
    method ByteArrayOutputStream (line 70) | @SuppressWarnings("WeakerAccess")
    method needNewBuffer (line 87) | private void needNewBuffer(int newCount) {
    method write (line 119) | @Override
    method write (line 151) | @Override
    method write (line 173) | @SuppressWarnings({"WeakerAccess", "UnusedReturnValue"})
    method size (line 195) | public synchronized int size() {
    method close (line 207) | @Override
    method reset (line 215) | public synchronized void reset() {
    method writeTo (line 230) | public synchronized void writeTo(OutputStream out) throws IOException {
    method toBufferedInputStream (line 263) | public static InputStream toBufferedInputStream(InputStream input)
    method toBufferedInputStream (line 280) | private InputStream toBufferedInputStream() {
    method toByteArray (line 304) | public synchronized byte[] toByteArray() {
    method toString (line 328) | @Override
    method toString (line 342) | public String toString(String enc) throws UnsupportedEncodingException {

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/stream/ClosedInputStream.java
  class ClosedInputStream (line 17) | public class ClosedInputStream extends InputStream {
    method read (line 29) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/utils/stream/StringBuilderWriter.java
  class StringBuilderWriter (line 21) | public class StringBuilderWriter extends Writer implements Serializable {
    method StringBuilderWriter (line 29) | public StringBuilderWriter() {
    method StringBuilderWriter (line 38) | @SuppressWarnings("SameParameterValue")
    method StringBuilderWriter (line 48) | public StringBuilderWriter(StringBuilder builder) {
    method append (line 58) | @Override
    method append (line 70) | @Override
    method append (line 84) | @Override
    method close (line 93) | @Override
    method flush (line 100) | @Override
    method write (line 110) | @Override
    method write (line 122) | @Override
    method getBuilder (line 132) | public StringBuilder getBuilder() {
    method toString (line 141) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/view/OCRMainActivity.java
  class OCRMainActivity (line 35) | @SuppressWarnings("StatementWithEmptyBody")
    method Launcher (line 44) | public static void Launcher(Context context, boolean isFace) {
    method onCreate (line 58) | @Override
    method onResume (line 83) | @Override
    method onPause (line 109) | @Override
    method onDestroy (line 115) | @Override
    method onRequestPermissionsResult (line 129) | @Override
    method getBackgroundHandler (line 145) | private Handler getBackgroundHandler() {
    method onCameraOpened (line 157) | @Override
    method onCameraClosed (line 162) | @Override
    method onPictureTaken (line 167) | @Override
    method onActivityResult (line 180) | @Override
    method getActivity (line 197) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/view/OcrLaunchFragment.java
  class OcrLaunchFragment (line 25) | public class OcrLaunchFragment extends Fragment implements View.OnClickL...
    method onCreate (line 32) | @Override
    method onCreateView (line 38) | @Nullable
    method onClick (line 49) | @Override
    method onActivityResult (line 63) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/Crop.java
  class Crop (line 19) | public class Crop {
    type Extra (line 25) | interface Extra {
    method of (line 42) | public static Crop of(Uri source, Uri destination) {
    method Crop (line 46) | private Crop(Uri source, Uri destination) {
    method withAspect (line 58) | public Crop withAspect(float x, float y) {
    method asSquare (line 67) | public Crop asSquare() {
    method withMaxSize (line 79) | public Crop withMaxSize(int width, int height) {
    method asPng (line 89) | public Crop asPng(boolean asPng) {
    method start (line 99) | public void start(Activity activity) {
    method start (line 109) | public void start(Activity activity, int requestCode) {
    method start (line 119) | public void start(Context context, Fragment fragment) {
    method start (line 129) | public void start(Context context, android.support.v4.app.Fragment fra...
    method start (line 140) | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    method start (line 152) | public void start(Context context, android.support.v4.app.Fragment fra...
    method getIntent (line 162) | public Intent getIntent(Context context) {
    method getOutput (line 172) | public static Uri getOutput(Intent result) {
    method getError (line 182) | public static Throwable getError(Intent result) {
    method pickImage (line 191) | public static void pickImage(Activity activity ) {
    method pickImage (line 201) | public static void pickImage(Context context, Fragment fragment) {
    method pickImage (line 211) | public static void pickImage(Context context, android.support.v4.app.F...
    method pickImage (line 221) | public static void pickImage(Activity activity , int requestCode) {
    method pickImage (line 236) | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    method pickImage (line 252) | public static void pickImage(Context context, android.support.v4.app.F...
    method getImagePicker (line 260) | private static Intent getImagePicker() {
    method showImagePickerError (line 264) | private static void showImagePickerError(Context context) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/CropImageActivity.java
  class CropImageActivity (line 47) | public class CropImageActivity extends MonitoredActivity {
    method onCreate (line 73) | @Override
    method setupWindowFlags (line 87) | @TargetApi(Build.VERSION_CODES.KITKAT)
    method setupViews (line 95) | private void setupViews() {
    method loadInput (line 122) | private void loadInput() {
    method calculateBitmapSampleSize (line 158) | private int calculateBitmapSampleSize(Uri bitmapUri) throws IOException {
    method getMaxImageSize (line 177) | private int getMaxImageSize() {
    method getMaxTextureSize (line 186) | private int getMaxTextureSize() {
    method startCrop (line 193) | private void startCrop() {
    class Cropper (line 221) | private class Cropper {
      method makeDefault (line 223) | private void makeDefault() {
      method crop (line 255) | public void crop() {
    method onSaveClicked (line 269) | private void onSaveClicked() {
    method saveImage (line 309) | private void saveImage(Bitmap croppedImage) {
    method decodeRegionCrop (line 324) | private Bitmap decodeRegionCrop(Rect rect, int outWidth, int outHeight) {
    method clearImageView (line 374) | private void clearImageView() {
    method saveOutput (line 382) | private void saveOutput(Bitmap croppedImage) {
    method onDestroy (line 418) | @Override
    method onSearchRequested (line 426) | @Override
    method isSaving (line 431) | public boolean isSaving() {
    method setResultUri (line 435) | private void setResultUri(Uri uri) {
    method setResultException (line 439) | private void setResultException(Throwable throwable) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/CropImageView.java
  class CropImageView (line 12) | public class CropImageView extends ImageViewTouchBase {
    method CropImageView (line 23) | public CropImageView(Context context) {
    method CropImageView (line 27) | public CropImageView(Context context, AttributeSet attrs) {
    method CropImageView (line 31) | public CropImageView(Context context, AttributeSet attrs, int defStyle) {
    method onLayout (line 35) | @Override
    method zoomTo (line 50) | @Override
    method zoomIn (line 59) | @Override
    method zoomOut (line 68) | @Override
    method postTranslate (line 77) | @Override
    method onTouchEvent (line 86) | @Override
    method ensureVisible (line 139) | private void ensureVisible(HighlightView hv) {
    method centerBasedOnHighlightView (line 158) | private void centerBasedOnHighlightView(HighlightView hv) {
    method onDraw (line 183) | @Override
    method add (line 191) | public void add(HighlightView hv) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/CropUtil.java
  class CropUtil (line 41) | class CropUtil {
    method closeSilently (line 46) | public static void closeSilently(@Nullable Closeable c) {
    method getExifRotation (line 55) | public static int getExifRotation(File imageFile) {
    method copyExifRotation (line 76) | public static boolean copyExifRotation(File sourceFile, File destFile) {
    method getFromMediaUri (line 90) | @Nullable
    method getTempFilename (line 125) | private static String getTempFilename(Context context) throws IOExcept...
    method getFromMediaUriPfd (line 131) | @Nullable
    method startBackgroundJob (line 160) | public static void startBackgroundJob(MonitoredActivity activity,
    class BackgroundJob (line 169) | private static class BackgroundJob extends MonitoredActivity.LifeCycle...
      method run (line 176) | public void run() {
      method BackgroundJob (line 182) | public BackgroundJob(MonitoredActivity activity, Runnable job,
      method run (line 191) | public void run() {
      method onActivityDestroyed (line 199) | @Override
      method onActivityStopped (line 207) | @Override
      method onActivityStarted (line 212) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/HighlightView.java
  class HighlightView (line 44) | class HighlightView {
    type ModifyMode (line 57) | enum ModifyMode { None, Move, Grow }
    type HandleMode (line 58) | enum HandleMode { Changing, Always, Never }
    method HighlightView (line 82) | public HighlightView(View context) {
    method initStyles (line 87) | private void initStyles(Context context) {
    method setup (line 102) | public void setup(Matrix m, Rect imageRect, RectF cropRect, boolean ma...
    method dpToPx (line 125) | private float dpToPx(float dp) {
    method draw (line 129) | protected void draw(Canvas canvas) {
    method drawOutsideFallback (line 171) | private void drawOutsideFallback(Canvas canvas) {
    method isClipPathSupported (line 183) | @SuppressLint("NewApi")
    method drawHandles (line 195) | private void drawHandles(Canvas canvas) {
    method drawThirds (line 205) | private void drawThirds(Canvas canvas) {
    method drawCircle (line 220) | private void drawCircle(Canvas canvas) {
    method setMode (line 225) | public void setMode(ModifyMode mode) {
    method getHit (line 233) | public int getHit(float x, float y) {
    method handleMotion (line 268) | void handleMotion(int edge, float dx, float dy) {
    method moveBy (line 292) | void moveBy(float dx, float dy) {
    method growBy (line 313) | void growBy(float dx, float dy) {
    method getScaledCropRect (line 371) | public Rect getScaledCropRect(float scale) {
    method computeLayout (line 377) | private Rect computeLayout() {
    method invalidate (line 385) | public void invalidate() {
    method hasFocus (line 389) | public boolean hasFocus() {
    method setFocus (line 393) | public void setFocus(boolean isFocused) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/ImageViewTouchBase.java
  class ImageViewTouchBase (line 32) | abstract class ImageViewTouchBase extends android.support.v7.widget.AppC...
    type Recycler (line 73) | public interface Recycler {
      method recycle (line 74) | public void recycle(Bitmap b);
    method ImageViewTouchBase (line 79) | public ImageViewTouchBase(Context context) {
    method ImageViewTouchBase (line 84) | public ImageViewTouchBase(Context context, AttributeSet attrs) {
    method ImageViewTouchBase (line 89) | public ImageViewTouchBase(Context context, AttributeSet attrs, int def...
    method setRecycler (line 94) | public void setRecycler(Recycler recycler) {
    method onLayout (line 98) | @Override
    method onKeyDown (line 114) | @Override
    method onKeyUp (line 123) | @Override
    method setImageBitmap (line 136) | @Override
    method setImageBitmap (line 141) | private void setImageBitmap(Bitmap bitmap, int rotation) {
    method clear (line 157) | public void clear() {
    method setImageBitmapResetBase (line 164) | public void setImageBitmapResetBase(final Bitmap bitmap, final boolean...
    method setImageRotateBitmapResetBase (line 168) | public void setImageRotateBitmapResetBase(final RotateBitmap bitmap, f...
    method center (line 198) | protected void center() {
    method centerVertical (line 220) | private float centerVertical(RectF rect, float height, float deltaY) {
    method centerHorizontal (line 232) | private float centerHorizontal(RectF rect, float width, float deltaX) {
    method init (line 244) | private void init() {
    method getValue (line 248) | protected float getValue(Matrix matrix, int whichValue) {
    method getScale (line 254) | protected float getScale(Matrix matrix) {
    method getScale (line 258) | protected float getScale() {
    method getProperBaseMatrix (line 263) | private void getProperBaseMatrix(RotateBitmap bitmap, Matrix matrix, b...
    method getImageViewMatrix (line 284) | protected Matrix getImageViewMatrix() {
    method getUnrotatedMatrix (line 292) | public Matrix getUnrotatedMatrix(){
    method calculateMaxZoom (line 299) | protected float calculateMaxZoom() {
    method zoomTo (line 309) | protected void zoomTo(float scale, float centerX, float centerY) {
    method zoomTo (line 322) | protected void zoomTo(final float scale, final float centerX,
    method zoomTo (line 342) | protected void zoomTo(float scale) {
    method zoomIn (line 348) | protected void zoomIn() {
    method zoomOut (line 352) | protected void zoomOut() {
    method zoomIn (line 356) | protected void zoomIn(float rate) {
    method zoomOut (line 371) | protected void zoomOut(float rate) {
    method postTranslate (line 392) | protected void postTranslate(float dx, float dy) {
    method panBy (line 396) | protected void panBy(float dx, float dy) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/Log.java
  class Log (line 3) | class Log {
    method e (line 7) | public static void e(String msg) {
    method e (line 11) | public static void e(String msg, Throwable e) {

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/MonitoredActivity.java
  class MonitoredActivity (line 27) | abstract class MonitoredActivity extends Activity {
    type LifeCycleListener (line 31) | public static interface LifeCycleListener {
      method onActivityCreated (line 32) | public void onActivityCreated(MonitoredActivity activity);
      method onActivityDestroyed (line 33) | public void onActivityDestroyed(MonitoredActivity activity);
      method onActivityStarted (line 34) | public void onActivityStarted(MonitoredActivity activity);
      method onActivityStopped (line 35) | public void onActivityStopped(MonitoredActivity activity);
    class LifeCycleAdapter (line 38) | public static class LifeCycleAdapter implements LifeCycleListener {
      method onActivityCreated (line 39) | public void onActivityCreated(MonitoredActivity activity) {}
      method onActivityDestroyed (line 40) | public void onActivityDestroyed(MonitoredActivity activity) {}
      method onActivityStarted (line 41) | public void onActivityStarted(MonitoredActivity activity) {}
      method onActivityStopped (line 42) | public void onActivityStopped(MonitoredActivity activity) {}
    method addLifeCycleListener (line 45) | public void addLifeCycleListener(LifeCycleListener listener) {
    method removeLifeCycleListener (line 50) | public void removeLifeCycleListener(LifeCycleListener listener) {
    method onCreate (line 54) | @Override
    method onDestroy (line 62) | @Override
    method onStart (line 70) | @Override
    method onStop (line 78) | @Override

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/crop/RotateBitmap.java
  class RotateBitmap (line 25) | class RotateBitmap {
    method RotateBitmap (line 30) | public RotateBitmap(Bitmap bitmap, int rotation) {
    method setRotation (line 35) | public void setRotation(int rotation) {
    method getRotation (line 39) | public int getRotation() {
    method getBitmap (line 43) | public Bitmap getBitmap() {
    method setBitmap (line 47) | public void setBitmap(Bitmap bitmap) {
    method getRotateMatrix (line 51) | public Matrix getRotateMatrix() {
    method isOrientationChanged (line 67) | public boolean isOrientationChanged() {
    method getHeight (line 71) | public int getHeight() {
    method getWidth (line 80) | public int getWidth() {
    method recycle (line 89) | public void recycle() {

FILE: aliocrlib/src/main/java/com/lib/aliocr/widget/popup/XinPopWindow.java
  class XinPopWindow (line 46) | public class XinPopWindow extends PopupWindow {
    method XinPopWindow (line 53) | public XinPopWindow(Activity context) {
    method backgroundAlpha (line 107) | public void backgroundAlpha(float bgAlpha) {
    method showAtLocation (line 119) | @Override
    method setData (line 125) | public void setData(List<MenuItem> menuItems) {
    method setOnItemClickListener (line 129) | public void setOnItemClickListener(final OnItemClickListener listener) {
    type OnItemClickListener (line 137) | public interface OnItemClickListener {
      method onItemClick (line 138) | void onItemClick(AdapterView<?> parent, View view, int position, lon...
    class MenuAdapter (line 141) | public static class MenuAdapter extends BaseAdapter {
      method MenuAdapter (line 145) | public MenuAdapter() {
      method getMenuItems (line 150) | public List<MenuItem> getMenuItems() {
      method setMenuItems (line 154) | public void setMenuItems(List<MenuItem> menuItems) {
      class ViewHolder (line 159) | static class ViewHolder {
      method getCount (line 165) | @Override
      method getItem (line 170) | @Override
      method getItemId (line 175) | @Override
      method getView (line 180) | @Override
    class MenuItem (line 215) | public static class MenuItem {
      method MenuItem (line 219) | public MenuItem(String name, int type) {
      method equals (line 224) | @Override
      method hashCode (line 234) | @Override

FILE: app/src/main/java/com/xin/lockdemo/App.java
  class App (line 16) | public class App extends Application {
    method onCreate (line 18) | @Override

FILE: app/src/main/java/com/xin/lockdemo/GesturePswMainActivity.java
  class GesturePswMainActivity (line 26) | public class GesturePswMainActivity extends AppCompatActivity implements...
    method Launcher (line 32) | public static void Launcher(Context context) {
    method onCreate (line 43) | @Override
    method onResume (line 57) | @Override
    method onClick (line 67) | @Override
    method hasPsw (line 88) | private boolean hasPsw() {

FILE: app/src/main/java/com/xin/lockdemo/MainActivity.java
  class MainActivity (line 27) | public class MainActivity extends AppCompatActivity implements View.OnCl...
    method onCreate (line 33) | @Override
    method onClick (line 46) | @Override
    method onBackPressed (line 74) | @Override
    method authActivity (line 90) | private void authActivity() {
    method onResume (line 125) | @Override

FILE: app/src/main/java/com/xin/lockdemo/dialog/CustomDialog.java
  class CustomDialog (line 27) | public class CustomDialog extends Dialog {
    method CustomDialog (line 37) | public CustomDialog(Context context) {
    method onCreate (line 43) | @Override
    method initView (line 63) | private void initView() {
    method initData (line 74) | private void initData() {
    method initEvent (line 91) | private void initEvent() {
    method getContentView (line 97) | public View getContentView() {
    method setCustom (line 101) | public void setCustom(View mContentView) {

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/activities/FingerprintPswMainActivity.java
  class FingerprintPswMainActivity (line 23) | public class FingerprintPswMainActivity extends AppCompatActivity {
    method Launcher (line 26) | public static void Launcher(Context context) {
    method onCreate (line 37) | @Override
    method startFingerprintRecognition (line 72) | private void startFingerprintRecognition() {
    method cancelFingerprintRecognition (line 86) | private void cancelFingerprintRecognition() {
    method onDestroy (line 93) | @Override

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/core/CryptoObjectCreator.java
  class CryptoObjectCreator (line 28) | @TargetApi(Build.VERSION_CODES.M)
    type ICryptoObjectCreateListener (line 38) | public interface ICryptoObjectCreateListener {
      method onDataPrepared (line 39) | void onDataPrepared(FingerprintManager.CryptoObject cryptoObject);
    method CryptoObjectCreator (line 42) | public CryptoObjectCreator(ICryptoObjectCreateListener createListener) {
    method prepareData (line 52) | private void prepareData(final ICryptoObjectCreateListener createListe...
    method createKey (line 79) | private void createKey() {
    method initCipher (line 112) | private boolean initCipher() {
    method providesKeystore (line 128) | public static KeyStore providesKeystore() {
    method providesKeyGenerator (line 136) | public static KeyGenerator providesKeyGenerator() {
    method providesCipher (line 144) | public static Cipher providesCipher(KeyStore keyStore) {
    method getCryptoObject (line 154) | public FingerprintManager.CryptoObject getCryptoObject() {
    method onDestroy (line 158) | public void onDestroy() {

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/core/FingerprintCore.java
  class FingerprintCore (line 20) | @TargetApi(Build.VERSION_CODES.M)
    type IFingerprintResultListener (line 43) | public interface IFingerprintResultListener {
      method onAuthenticateSuccess (line 45) | void onAuthenticateSuccess();
      method onAuthenticateFailed (line 48) | void onAuthenticateFailed(int helpId,String errString);
      method onAuthenticateError (line 51) | void onAuthenticateError(int errMsgId);
      method onStartAuthenticateResult (line 54) | void onStartAuthenticateResult(boolean isSuccess);
    method FingerprintCore (line 57) | private FingerprintCore(Context context) {
    method initCryptoObject (line 64) | private void initCryptoObject() {
    method setFingerprintManager (line 78) | public void setFingerprintManager(IFingerprintResultListener fingerpri...
    method startAuthenticate (line 82) | public void startAuthenticate() {
    method isAuthenticating (line 86) | public boolean isAuthenticating() {
    method startAuthenticate (line 90) | private void startAuthenticate(FingerprintManager.CryptoObject cryptoO...
    method notifyStartAuthenticateResult (line 111) | private void notifyStartAuthenticateResult(boolean isSuccess, String e...
    method notifyAuthenticationSucceeded (line 125) | private void notifyAuthenticationSucceeded() {
    method notifyAuthenticationError (line 132) | private void notifyAuthenticationError(int errMsgId, CharSequence errS...
    method notifyAuthenticationFailed (line 139) | private void notifyAuthenticationFailed(int msgId, String errString) {
    method prepareData (line 146) | private void prepareData() {
    method cancelAuthenticate (line 184) | public void cancelAuthenticate() {
    method onFailedRetry (line 193) | private void onFailedRetry(int msgId, String helpString) {
    method startDelay (line 216) | public void startDelay(){
    method run (line 225) | @Override
    method isSupport (line 231) | public boolean isSupport() {
    method isHardwareDetected (line 239) | public boolean isHardwareDetected() {
    method isHasEnrolledFingerprints (line 251) | public boolean isHasEnrolledFingerprints() {
    method getFingerprintManager (line 261) | public static FingerprintManager getFingerprintManager(Context context) {
    method onDestroy (line 271) | public void onDestroy() {
    method getInstance (line 285) | public static final FingerprintCore getInstance() {
    class LazyHolder (line 289) | public static class LazyHolder {

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/core/MyListener.java
  class MyListener (line 11) | public abstract class MyListener implements FingerprintCore.IFingerprint...

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/dialog/FingerDialog.java
  class FingerDialog (line 29) | public class FingerDialog extends Dialog {
    method FingerDialog (line 38) | public FingerDialog(Context context) {
    method onCreate (line 44) | @Override
    method initView (line 64) | private void initView() {
    method initData (line 75) | private void initData() {
    method initEvent (line 92) | private void initEvent() {
    method getContentView (line 98) | public View getContentView() {
    method setCustom (line 102) | public void setCustom(View mContentView) {

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/utils/FingerContext.java
  class FingerContext (line 15) | public class FingerContext {
    method FingerContext (line 22) | private FingerContext() {
    method init (line 31) | public static void init(@NonNull Context context) {
    method getContext (line 40) | public static Context getContext() {

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/utils/FingerprintUtil.java
  class FingerprintUtil (line 30) | public class FingerprintUtil {
    method openFingerPrintSettingPage (line 43) | public static void openFingerPrintSettingPage(Context context) {
    method supportAndSysOpenedFingerPrint (line 55) | public static boolean supportAndSysOpenedFingerPrint() {
    method startFingerprintRecognition (line 65) | public static void startFingerprintRecognition(final Activity activity...
    method showLog (line 195) | private static void showLog(String msg) {

FILE: fingerprintlib/src/main/java/com/lib/lock/fingerprint/utils/KeyguardLockScreenManager.java
  class KeyguardLockScreenManager (line 14) | public class KeyguardLockScreenManager {
    method isOpenLockScreenPwd (line 22) | public boolean isOpenLockScreenPwd() {
    method KeyguardLockScreenManager (line 34) | public KeyguardLockScreenManager(Context context) {
    method getKeyguardManager (line 38) | public static KeyguardManager getKeyguardManager(Context context) {
    method showAuthenticationScreen (line 51) | public void showAuthenticationScreen(Activity activity) {
    method onDestroy (line 61) | public void onDestroy() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/activities/GestureSettingsActivity.java
  class GestureSettingsActivity (line 29) | public class GestureSettingsActivity extends AppCompatActivity {
    method launch (line 35) | public static void launch(Activity activity) {
    method onCreate (line 41) | @Override
    method onResume (line 81) | @Override
    method isPatternOk (line 87) | private boolean isPatternOk(List<Integer> hitList) {
    method updateMsg (line 92) | private void updateMsg() {
    method finishIfNeeded (line 97) | private void finishIfNeeded() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/activities/GestureVerifyActivity.java
  class GestureVerifyActivity (line 26) | public class GestureVerifyActivity extends AppCompatActivity {
    method launch (line 36) | public static void launch(Activity activity, boolean isSettings) {
    method onCreate (line 43) | @Override
    method isPatternOk (line 80) | private boolean isPatternOk(List<Integer> hitList) {
    method updateMsg (line 85) | private void updateMsg() {
    method finishIfNeeded (line 90) | private void finishIfNeeded() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/bean/CellBean.java
  class CellBean (line 5) | public class CellBean {
    method CellBean (line 14) | public CellBean(int id, float x, float y, float radius) {
    method of (line 28) | public boolean of(float x, float y) {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/bean/CellFactory.java
  class CellFactory (line 9) | public class CellFactory {
    method CellFactory (line 14) | public CellFactory(int width, int height) {
    method create (line 21) | private void create() {
    method getCellBeanList (line 36) | public List<CellBean> getCellBeanList() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/config/Config.java
  class Config (line 11) | public class Config {
    method getDefaultNormalColor (line 20) | public static @ColorInt
    method getDefaultHitColor (line 25) | public static @ColorInt
    method getDefaultErrorColor (line 30) | public static @ColorInt
    method getDefaultFillColor (line 35) | public static @ColorInt
    method getDefaultLineWidth (line 40) | public static float getDefaultLineWidth(Resources resources) {
    method getDefaultDelayTime (line 44) | public static int getDefaultDelayTime() {
    method getDefaultEnableAutoClean (line 48) | public static boolean getDefaultEnableAutoClean() {
    method createPaint (line 52) | public static Paint createPaint() {
    method convertDpToPx (line 61) | private static float convertDpToPx(float dp, Resources resources) {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/content/DataKeeper.java
  class DataKeeper (line 31) | public class DataKeeper {
    method DataKeeper (line 36) | @SuppressLint("CommitPrefEdits")
    method get (line 46) | public String get(String key, String defValue) {
    method get (line 50) | public boolean get(String key, boolean defValue) {
    method get (line 54) | public float get(String key, float defValue) {
    method getInt (line 58) | public int getInt(String key, int defValue) {
    method get (line 62) | public long get(String key, long defValue) {
    method put (line 67) | public SharedPreferences.Editor put(String key, String value) {
    method put (line 76) | public SharedPreferences.Editor put(String key, boolean value) {
    method put (line 81) | public SharedPreferences.Editor put(String key, float value) {
    method put (line 86) | public SharedPreferences.Editor put(String key, long value) {
    method putInt (line 91) | public SharedPreferences.Editor putInt(String key, int value) {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/content/SPManager.java
  class SPManager (line 11) | public class SPManager implements SharedPreferencesKeys {
    method SPManager (line 17) | private SPManager() {
    method getInstance (line 21) | public static SPManager getInstance() {
    method putPatternPSW (line 45) | public void   putPatternPSW(String encryptPwd) {
    method getPatternPSW (line 55) | public String getPatternPSW() {
    method setHasFingerPrint (line 65) | public void setHasFingerPrint(boolean isSet) {
    method getHasFingerPrint (line 74) | public boolean getHasFingerPrint() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/content/SharedPreferencesKeys.java
  type SharedPreferencesKeys (line 11) | public interface SharedPreferencesKeys {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultIndicatorHitCellView.java
  class DefaultIndicatorHitCellView (line 14) | public class DefaultIndicatorHitCellView implements  IHitCellView {
    method DefaultIndicatorHitCellView (line 23) | public DefaultIndicatorHitCellView() {
    method getNormalColor (line 28) | public int getNormalColor() {
    method setNormalColor (line 32) | public DefaultIndicatorHitCellView setNormalColor(int normalColor) {
    method getErrorColor (line 37) | public int getErrorColor() {
    method setErrorColor (line 41) | public DefaultIndicatorHitCellView setErrorColor(int errorColor) {
    method draw (line 46) | @Override
    method getColor (line 56) | private int getColor(boolean isError) {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultIndicatorLinkedLineView.java
  class DefaultIndicatorLinkedLineView (line 18) | public class DefaultIndicatorLinkedLineView implements IIndicatorLinkedL...
    method DefaultIndicatorLinkedLineView (line 27) | public DefaultIndicatorLinkedLineView() {
    method getNormalColor (line 32) | public int getNormalColor() {
    method setNormalColor (line 36) | public DefaultIndicatorLinkedLineView setNormalColor(int normalColor) {
    method getErrorColor (line 41) | public int getErrorColor() {
    method setErrorColor (line 45) | public DefaultIndicatorLinkedLineView setErrorColor(int errorColor) {
    method getLineWidth (line 50) | public float getLineWidth() {
    method setLineWidth (line 54) | public DefaultIndicatorLinkedLineView setLineWidth(float lineWidth) {
    method draw (line 59) | @Override
    method getColor (line 83) | private int getColor(boolean isError) {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultIndicatorNormalCellView.java
  class DefaultIndicatorNormalCellView (line 13) | public class DefaultIndicatorNormalCellView implements INormalCellView {
    method DefaultIndicatorNormalCellView (line 21) | public DefaultIndicatorNormalCellView() {
    method getNormalColor (line 26) | public int getNormalColor() {
    method setNormalColor (line 30) | public DefaultIndicatorNormalCellView setNormalColor(int normalColor) {
    method getFillColor (line 35) | public int getFillColor() {
    method setFillColor (line 39) | public DefaultIndicatorNormalCellView setFillColor(int fillColor) {
    method getLineWidth (line 44) | public float getLineWidth() {
    method setLineWidth (line 48) | public DefaultIndicatorNormalCellView setLineWidth(float lineWidth) {
    method draw (line 53) | @Override

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerHitCellView.java
  class DefaultLockerHitCellView (line 17) | public class DefaultLockerHitCellView implements IHitCellView {
    method DefaultLockerHitCellView (line 34) | public DefaultLockerHitCellView() {
    method getHitColor (line 41) | public @ColorInt
    method setHitColor (line 46) | public DefaultLockerHitCellView setHitColor(@ColorInt int hitColor) {
    method getErrorColor (line 51) | public @ColorInt
    method setErrorColor (line 56) | public DefaultLockerHitCellView setErrorColor(@ColorInt int errorColor) {
    method getNormalColor (line 61) | public int getNormalColor() {
    method setNormalColor (line 65) | public DefaultLockerHitCellView setNormalColor(int normalColor) {
    method getFillColor (line 70) | public @ColorInt
    method setFillColor (line 75) | public DefaultLockerHitCellView setFillColor(@ColorInt int fillColor) {
    method getLineWidth (line 80) | public float getLineWidth() {
    method setLineWidth (line 84) | public DefaultLockerHitCellView setLineWidth(float lineWidth) {
    method draw (line 90) | @Override
    method getColor (line 112) | private @ColorInt
    method getOuterColor (line 117) | private @ColorInt
    method getGradientColor (line 123) | private @ColorInt

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerLinkedLineView.java
  class DefaultLockerLinkedLineView (line 18) | public class DefaultLockerLinkedLineView implements ILockerLinkedLineView {
    method DefaultLockerLinkedLineView (line 34) | public DefaultLockerLinkedLineView() {
    method getNormalColor (line 39) | public int getNormalColor() {
    method setNormalColor (line 43) | public DefaultLockerLinkedLineView setNormalColor(int normalColor) {
    method getErrorColor (line 48) | public int getErrorColor() {
    method setHitColor (line 52) | public ILockerLinkedLineView setHitColor(int hitColor) {
    method getHitColor (line 58) | public int getHitColor() {
    method setErrorColor (line 62) | public DefaultLockerLinkedLineView setErrorColor(int errorColor) {
    method getLineWidth (line 67) | public float getLineWidth() {
    method setLineWidth (line 71) | public DefaultLockerLinkedLineView setLineWidth(float lineWidth) {
    method draw (line 76) | @Override
    method getColor (line 105) | private @ColorInt

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerNormalCellView.java
  class DefaultLockerNormalCellView (line 14) | public class DefaultLockerNormalCellView implements INormalCellView {
    method DefaultLockerNormalCellView (line 25) | public DefaultLockerNormalCellView() {
    method getNormalColor (line 30) | public int getNormalColor() {
    method setNormalColor (line 34) | public DefaultLockerNormalCellView setNormalColor(int normalColor) {
    method getFillColor (line 39) | public int getFillColor() {
    method setFillColor (line 43) | public DefaultLockerNormalCellView setFillColor(int fillColor) {
    method getLineWidth (line 48) | public float getLineWidth() {
    method setLineWidth (line 52) | public DefaultLockerNormalCellView setLineWidth(float lineWidth) {
    method draw (line 57) | @Override

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerNormalCustomCellView.java
  class DefaultLockerNormalCustomCellView (line 14) | public class DefaultLockerNormalCustomCellView implements INormalCellView {
    method DefaultLockerNormalCustomCellView (line 28) | public DefaultLockerNormalCustomCellView() {
    method getNormalColor (line 33) | public int getNormalColor() {
    method setNormalColor (line 37) | public DefaultLockerNormalCustomCellView setNormalColor(int normalColo...
    method getFillColor (line 42) | public int getFillColor() {
    method setFillColor (line 46) | public DefaultLockerNormalCustomCellView setFillColor(int fillColor) {
    method getLineWidth (line 51) | public float getLineWidth() {
    method setLineWidth (line 55) | public DefaultLockerNormalCustomCellView setLineWidth(float lineWidth) {
    method setHitColor (line 61) | public DefaultLockerNormalCustomCellView setHitColor(@ColorInt int hit...
    method getHitColor (line 66) | public @ColorInt
    method draw (line 71) | @Override

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/IHitCellView.java
  type IHitCellView (line 11) | public interface IHitCellView {
    method draw (line 19) | void draw(@NonNull Canvas canvas, @NonNull CellBean cellBean, boolean ...

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/IIndicatorLinkedLineView.java
  type IIndicatorLinkedLineView (line 14) | public interface IIndicatorLinkedLineView {
    method draw (line 23) | void draw(@NonNull Canvas canvas,

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/ILockerLinkedLineView.java
  type ILockerLinkedLineView (line 14) | public interface ILockerLinkedLineView {
    method draw (line 25) | void draw(@NonNull Canvas canvas,

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/INormalCellView.java
  type INormalCellView (line 11) | public interface INormalCellView {
    method draw (line 18) | void draw(@NonNull Canvas canvas, @NonNull CellBean cellBean);

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/OnPatternChangeListener.java
  type OnPatternChangeListener (line 8) | public interface OnPatternChangeListener {
    method onStart (line 14) | void onStart(PatternLockerView view);
    method onChange (line 22) | void onChange(PatternLockerView view, List<Integer> hitList);
    method onComplete (line 30) | void onComplete(PatternLockerView view, List<Integer> hitList);
    method onClear (line 37) | void onClear(PatternLockerView view);

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/PatternIndicatorView.java
  class PatternIndicatorView (line 22) | public class PatternIndicatorView extends View {
    method PatternIndicatorView (line 40) | public PatternIndicatorView(Context context) {
    method PatternIndicatorView (line 44) | public PatternIndicatorView(Context context, @Nullable AttributeSet at...
    method PatternIndicatorView (line 48) | public PatternIndicatorView(Context context, @Nullable AttributeSet at...
    method getNormalColor (line 53) | public int getNormalColor() {
    method setNormalColor (line 57) | public PatternIndicatorView setNormalColor(int normalColor) {
    method getFillColor (line 62) | public int getFillColor() {
    method setFillColor (line 66) | public PatternIndicatorView setFillColor(int fillColor) {
    method getHitColor (line 71) | public int getHitColor() {
    method setHitColor (line 75) | public PatternIndicatorView setHitColor(int hitColor) {
    method getErrorColor (line 80) | public int getErrorColor() {
    method setErrorColor (line 84) | public PatternIndicatorView setErrorColor(int errorColor) {
    method getLineWidth (line 89) | public float getLineWidth() {
    method setLineWidth (line 93) | public PatternIndicatorView setLineWidth(float lineWidth) {
    method getLinkedLineView (line 98) | public IIndicatorLinkedLineView getLinkedLineView() {
    method setLinkedLineView (line 102) | public PatternIndicatorView setLinkedLineView(IIndicatorLinkedLineView...
    method getNormalCellView (line 107) | public INormalCellView getNormalCellView() {
    method setNormalCellView (line 111) | public PatternIndicatorView setNormalCellView(INormalCellView normalCe...
    method getHitCellView (line 116) | public IHitCellView getHitCellView() {
    method setHitCellView (line 120) | public PatternIndicatorView setHitCellView(IHitCellView hitCellView) {
    method buildWithDefaultStyle (line 125) | public void buildWithDefaultStyle() {
    method build (line 140) | public void build() {
    method updateState (line 157) | public void updateState(List<Integer> hitList, boolean isError) {
    method onMeasure (line 183) | @Override
    method onDraw (line 189) | @Override
    method init (line 202) | private void init(Context context, @Nullable AttributeSet attrs, int d...
    method initAttrs (line 207) | private void initAttrs(Context context, @Nullable AttributeSet attrs, ...
    method initData (line 225) | private void initData() {
    method drawLinkedLine (line 230) | private void drawLinkedLine(Canvas canvas) {
    method drawCells (line 239) | private void drawCells(Canvas canvas) {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/customView/PatternLockerView.java
  class PatternLockerView (line 24) | public class PatternLockerView extends View {
    method PatternLockerView (line 51) | public PatternLockerView(Context context) {
    method PatternLockerView (line 55) | public PatternLockerView(Context context, @Nullable AttributeSet attrs) {
    method PatternLockerView (line 59) | public PatternLockerView(Context context, @Nullable AttributeSet attrs...
    method setOnPatternChangedListener (line 64) | public void setOnPatternChangedListener(OnPatternChangeListener listen...
    method updateStatus (line 68) | public void updateStatus(boolean isError) {
    method clearHitState (line 73) | public void clearHitState() {
    method getNormalColor (line 83) | public int getNormalColor() {
    method setNormalColor (line 87) | public PatternLockerView setNormalColor(int normalColor) {
    method getHitColor (line 92) | public int getHitColor() {
    method setHitColor (line 96) | public PatternLockerView setHitColor(int hitColor) {
    method getErrorColor (line 101) | public int getErrorColor() {
    method setErrorColor (line 105) | public PatternLockerView setErrorColor(int errorColor) {
    method getFillColor (line 110) | public int getFillColor() {
    method setFillColor (line 114) | public PatternLockerView setFillColor(int fillColor) {
    method getLineWidth (line 119) | public float getLineWidth() {
    method setLineWidth (line 123) | public PatternLockerView setLineWidth(float lineWidth) {
    method getLinkedLineView (line 128) | public ILockerLinkedLineView getLinkedLineView() {
    method setLinkedLineView (line 132) | public PatternLockerView setLinkedLineView(ILockerLinkedLineView linke...
    method getNormalCellView (line 137) | public INormalCellView getNormalCellView() {
    method setNormalCellView (line 141) | public PatternLockerView setNormalCellView(INormalCellView normalCellV...
    method getHitCellView (line 146) | public IHitCellView getHitCellView() {
    method setHitCellView (line 150) | public PatternLockerView setHitCellView(IHitCellView hitCellView) {
    method buildWithDefaultStyle (line 155) | public void buildWithDefaultStyle() {
    method build (line 174) | public void build() {
    method onMeasure (line 192) | @Override
    method onDraw (line 198) | @Override
    method onTouchEvent (line 209) | @Override
    method init (line 236) | private void init(Context context, @Nullable AttributeSet attrs, int d...
    method initAttrs (line 241) | private void initAttrs(Context context, @Nullable AttributeSet attrs, ...
    method initData (line 260) | private void initData() {
    method drawLinkedLine (line 265) | private void drawLinkedLine(Canvas canvas) {
    method drawCells (line 276) | private void drawCells(Canvas canvas) {
    method handleActionDown (line 297) | private void handleActionDown(MotionEvent event) {
    method handleActionMove (line 310) | private void handleActionMove(MotionEvent event) {
    method handleActionUp (line 326) | private void handleActionUp(MotionEvent event) {
    method updateHitState (line 343) | private void updateHitState(MotionEvent event) {
    method clearHitData (line 354) | private void clearHitData() {
    method run (line 363) | @Override
    method onDetachedFromWindow (line 370) | @Override
    method startTimer (line 377) | private void startTimer() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/utils/ContextUtils.java
  class ContextUtils (line 18) | public class ContextUtils {
    method ContextUtils (line 25) | private ContextUtils() {
    method init (line 34) | public static void init(@NonNull Context context) {
    method getContext (line 43) | public static Context getContext() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/utils/PatternHelper.java
  class PatternHelper (line 13) | public class PatternHelper {
    method validateForSetting (line 25) | public void validateForSetting(List<Integer> hitList) {
    method validateForChecking (line 55) | public void validateForChecking(List<Integer> hitList) {
    method getMessage (line 77) | public String getMessage() {
    method isFinish (line 81) | public boolean isFinish() {
    method isOk (line 85) | public boolean isOk() {
    method getReDrawMsg (line 89) | private String getReDrawMsg() {
    method getSettingSuccessMsg (line 93) | private String getSettingSuccessMsg() {
    method getCheckingSuccessMsg (line 97) | private String getCheckingSuccessMsg() {
    method getSizeErrorMsg (line 101) | private String getSizeErrorMsg() {
    method getDiffPreErrorMsg (line 105) | private String getDiffPreErrorMsg() {
    method getPwdErrorMsg (line 109) | private String getPwdErrorMsg() {
    method convert2String (line 113) | private String convert2String(List<Integer> hitList) {
    method saveToStorage (line 117) | private void saveToStorage(String gesturePwd) {
    method getFromStorage (line 122) | private String getFromStorage() {
    method getRemainTimes (line 127) | private int getRemainTimes() {

FILE: gesturepswlib/src/main/java/com/lib/lock/gesture/utils/SecurityUtil.java
  class SecurityUtil (line 16) | public class SecurityUtil {
    method createKey (line 20) | private static SecretKeySpec createKey(String password) {
    method encrypt (line 48) | public static String encrypt(final String content) {
    method encrypt (line 52) | public static byte[] encrypt(byte[] content, String password) {
    method encrypt (line 65) | public static String encrypt(String content, String password) {
    method decrypt (line 79) | public static String decrypt(final String content) {
    method decrypt (line 83) | public static byte[] decrypt(byte[] content, String password) {
    method decrypt (line 96) | public static String decrypt(String content, String password) {
    method byte2hex (line 122) | public static String byte2hex(byte[] b) { // 一个字节的数,
    method hex2byte (line 137) | private static byte[] hex2byte(String inputString) {
Condensed preview — 161 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (596K chars).
[
  {
    "path": ".gitignore",
    "chars": 1008,
    "preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated file"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 742,
    "preview": "# LockDemo\n封装了:指纹识别、图形密码手势密码识别、aliOCR识别\n个人使用,可根据需求添加。\n\n  \n \n\n\n\n <div class='row'>\n<img src=\"https://github.com/wzx54321/"
  },
  {
    "path": "aliocrlib/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "aliocrlib/README.MD",
    "chars": 20,
    "preview": "## 基于阿里OCR封装的身份证识别功能"
  },
  {
    "path": "aliocrlib/build.gradle",
    "chars": 1210,
    "preview": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 27\n\n\n\n    defaultConfig {\n        minSdkVersion 16\n"
  },
  {
    "path": "aliocrlib/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "aliocrlib/src/main/AndroidManifest.xml",
    "chars": 797,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest package=\"com.lib.aliocr\"\n          xmlns:android=\"http://schemas.androi"
  },
  {
    "path": "aliocrlib/src/main/api14/cameraview/Camera1.java",
    "chars": 15764,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/api14/cameraview/TextureViewPreview.java",
    "chars": 4783,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/api21/cameraview/Camera2.java",
    "chars": 27718,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/api23/cameraview/Camera2Api23.java",
    "chars": 1554,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/api9/cameraview/SurfaceViewPreview.java",
    "chars": 2471,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/base/cameraview/AspectRatio.java",
    "chars": 5284,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/base/cameraview/CameraViewImpl.java",
    "chars": 1912,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/base/cameraview/Constants.java",
    "chars": 967,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/base/cameraview/PreviewImpl.java",
    "chars": 1776,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/base/cameraview/Size.java",
    "chars": 2079,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/base/cameraview/SizeMap.java",
    "chars": 2352,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/cameraview/CameraView.java",
    "chars": 17401,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/cameraview/DisplayOrientationDetector.java",
    "chars": 3195,
    "preview": "/*\n * Copyright (C) 2016 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/api/HttpCustomConfig.java",
    "chars": 398,
    "preview": "package com.lib.aliocr.api;\n\nimport com.lib.aliocr.http.config.HttpConfig;\n\nimport okhttp3.OkHttpClient;\n\n/**\n * 作者:xin "
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/api/MyApiManager.java",
    "chars": 590,
    "preview": "package com.lib.aliocr.api;\n\n\nimport com.lib.aliocr.bean.RepOutput;\nimport com.lib.aliocr.common.Api;\n\nimport io.reactiv"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/bean/RepOutput.java",
    "chars": 5690,
    "preview": "package com.lib.aliocr.bean;\n\nimport java.io.Serializable;\n\n/**\n * 作者:xin on 2018/7/9 0009 13:50\n * <p>\n * 邮箱:ittfxin@12"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/bean/ReqInput.java",
    "chars": 719,
    "preview": "package com.lib.aliocr.bean;\n\nimport java.io.Serializable;\n\n/**\n * 作者:xin on 2018/7/9 0009 15:03\n * <p>\n * 邮箱:ittfxin@12"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/callback/OcrCallback.java",
    "chars": 257,
    "preview": "package com.lib.aliocr.callback;\n\n/**\n * 作者:xin on 2018/7/9 0009 15:03\n * <p>\n * 邮箱:ittfxin@126.com\n * <p>\n * https://gi"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/common/Api.java",
    "chars": 363,
    "preview": "package com.lib.aliocr.common;\n\n/**\n * 作者:xin on 2018/7/9 0009 15:03\n * <p>\n * 邮箱:ittfxin@126.com\n * <p>\n * https://gith"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/contact/OcrContact.java",
    "chars": 588,
    "preview": "package com.lib.aliocr.contact;\n\nimport android.app.Activity;\n\nimport com.lib.aliocr.bean.RepOutput;\n\nimport io.reactive"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/http/config/HttpConfig.java",
    "chars": 4040,
    "preview": "package com.lib.aliocr.http.config;\n\nimport android.annotation.SuppressLint;\n\nimport com.lib.aliocr.http.https.HttpsUtil"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/http/helper/HttpHelper.java",
    "chars": 1296,
    "preview": "package com.lib.aliocr.http.helper;\n\n\nimport com.lib.aliocr.api.HttpCustomConfig;\n\nimport okhttp3.OkHttpClient;\nimport r"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/http/https/HttpsUtils.java",
    "chars": 7504,
    "preview": "\npackage com.lib.aliocr.http.https;\n\n\nimport android.annotation.SuppressLint;\nimport android.util.Log;\n\nimport java.io.I"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/http/interceptor/HttpLog.java",
    "chars": 8047,
    "preview": "package com.lib.aliocr.http.interceptor;\n\n\nimport android.support.annotation.NonNull;\nimport android.util.Log;\n\nimport c"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/modle/OCRModel.java",
    "chars": 2038,
    "preview": "package com.lib.aliocr.modle;\n\nimport com.google.gson.Gson;\nimport com.lib.aliocr.api.MyApiManager;\nimport com.lib.alioc"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/presenter/OCRPresenter.java",
    "chars": 3494,
    "preview": "package com.lib.aliocr.presenter;\n\nimport android.graphics.Bitmap;\nimport android.net.Uri;\nimport android.os.Environment"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/Base64.java",
    "chars": 609,
    "preview": "package com.lib.aliocr.utils;\n\nimport sun.misc.BASE64Encoder;\n/**\n * 作者:xin on 2018/7/9 0009 15:03\n * <p>\n * 邮箱:ittfxin@"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/Ocr.java",
    "chars": 5866,
    "preview": "package com.lib.aliocr.utils;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.Intent;\nimpo"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/OcrUtils.java",
    "chars": 14344,
    "preview": "package com.lib.aliocr.utils;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.ComponentNam"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/io/Charsets.java",
    "chars": 851,
    "preview": "\npackage com.lib.aliocr.utils.io;\n\nimport java.nio.charset.Charset;\n\n/**\n * Charsets\n */\n@SuppressWarnings(\"WeakerAccess"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/io/FileUtil.java",
    "chars": 28342,
    "preview": "package com.lib.aliocr.utils.io;\n\nimport android.app.ActivityManager;\nimport android.content.Context;\nimport android.con"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/io/IOUtils.java",
    "chars": 97143,
    "preview": "\npackage com.lib.aliocr.utils.io;\n\nimport android.annotation.SuppressLint;\nimport android.os.Build;\nimport android.util."
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/io/SdCardUtil.java",
    "chars": 7339,
    "preview": "package com.lib.aliocr.utils.io;\n\nimport android.annotation.SuppressLint;\nimport android.annotation.TargetApi;\nimport an"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/io/StringCodingUtils.java",
    "chars": 338,
    "preview": "package com.lib.aliocr.utils.io;\n\nimport java.nio.charset.Charset;\n\n/**\n * 作者:xin on 2018/7/9 0009 15:03\n * <p>\n * 邮箱:it"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/stream/ByteArrayOutputStream.java",
    "chars": 11804,
    "preview": "\npackage com.lib.aliocr.utils.stream;\n \nimport android.support.annotation.NonNull;\n\nimport java.io.ByteArrayInputStream;"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/stream/ClosedInputStream.java",
    "chars": 815,
    "preview": "\npackage com.lib.aliocr.utils.stream;\n\nimport java.io.InputStream;\n\n/**\n * Closed input stream. This stream returns -1 t"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/utils/stream/StringBuilderWriter.java",
    "chars": 3798,
    "preview": "\npackage com.lib.aliocr.utils.stream;\n\nimport android.support.annotation.NonNull;\n\nimport java.io.Serializable;\nimport j"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/view/OCRMainActivity.java",
    "chars": 6396,
    "preview": "package com.lib.aliocr.view;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.Context;\nimpo"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/view/OcrLaunchFragment.java",
    "chars": 2264,
    "preview": "package com.lib.aliocr.view;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.annotation"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/Crop.java",
    "chars": 7869,
    "preview": "package com.lib.aliocr.widget.crop;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.ap"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/CropImageActivity.java",
    "chars": 14889,
    "preview": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/CropImageView.java",
    "chars": 6342,
    "preview": "package com.lib.aliocr.widget.crop;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.grap"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/CropUtil.java",
    "chars": 8076,
    "preview": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/HighlightView.java",
    "chars": 14543,
    "preview": "/*\n * Copyright (C) 2007 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/ImageViewTouchBase.java",
    "chars": 12784,
    "preview": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/Log.java",
    "chars": 291,
    "preview": "package com.lib.aliocr.widget.crop;\n\nclass Log {\n\n    private static final String TAG = \"android-crop\";\n\n    public stat"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/MonitoredActivity.java",
    "chars": 2689,
    "preview": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/crop/RotateBitmap.java",
    "chars": 2590,
    "preview": "/*\n * Copyright (C) 2009 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "aliocrlib/src/main/java/com/lib/aliocr/widget/popup/XinPopWindow.java",
    "chars": 7632,
    "preview": "package com.lib.aliocr.widget.popup;\n\nimport android.annotation.SuppressLint;\nimport android.app.Activity;\nimport androi"
  },
  {
    "path": "aliocrlib/src/main/res/anim/push_bottom_in.xml",
    "chars": 362,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- 上下滑入式 -->\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n"
  },
  {
    "path": "aliocrlib/src/main/res/anim/push_bottom_out.xml",
    "chars": 345,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- 上下滑入式 -->\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n"
  },
  {
    "path": "aliocrlib/src/main/res/drawable/common_btn_pop_choose_pic_down.xml",
    "chars": 418,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item "
  },
  {
    "path": "aliocrlib/src/main/res/drawable/common_btn_pop_choose_pic_mid.xml",
    "chars": 321,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "aliocrlib/src/main/res/drawable/common_btn_pop_choose_pic_up.xml",
    "chars": 409,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item "
  },
  {
    "path": "aliocrlib/src/main/res/drawable/crop__selectable_background.xml",
    "chars": 560,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android"
  },
  {
    "path": "aliocrlib/src/main/res/drawable/crop__texture.xml",
    "chars": 178,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<bitmap xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:s"
  },
  {
    "path": "aliocrlib/src/main/res/drawable/ic_camera.xml",
    "chars": 1267,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    Copyright (C) 2016 The Android Open Source Project\n    Licensed under th"
  },
  {
    "path": "aliocrlib/src/main/res/drawable-v21/crop__selectable_background.xml",
    "chars": 226,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        andro"
  },
  {
    "path": "aliocrlib/src/main/res/layout/activity_ocr_main.xml",
    "chars": 1174,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  "
  },
  {
    "path": "aliocrlib/src/main/res/layout/common_item_popup.xml",
    "chars": 1054,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        "
  },
  {
    "path": "aliocrlib/src/main/res/layout/common_popwindow.xml",
    "chars": 1818,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      "
  },
  {
    "path": "aliocrlib/src/main/res/layout/crop__activity_crop.xml",
    "chars": 608,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
  },
  {
    "path": "aliocrlib/src/main/res/layout/crop__layout_done_cancel.xml",
    "chars": 487,
    "preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    style=\"@style/Crop.DoneCancelBar\">\n\n    <Fr"
  },
  {
    "path": "aliocrlib/src/main/res/layout/fragment_ocr_launch.xml",
    "chars": 1311,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    "
  },
  {
    "path": "aliocrlib/src/main/res/layout/surface_view.xml",
    "chars": 929,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    Copyright (C) 2016 The Android Open Source Project\n    Licensed under th"
  },
  {
    "path": "aliocrlib/src/main/res/layout-v14/texture_view.xml",
    "chars": 929,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    Copyright (C) 2016 The Android Open Source Project\n    Licensed under th"
  },
  {
    "path": "aliocrlib/src/main/res/values/attrs.xml",
    "chars": 3053,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    Copyright (C) 2016 The Android Open Source Project\n    Licensed under th"
  },
  {
    "path": "aliocrlib/src/main/res/values/colors.xml",
    "chars": 428,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"white\">@android:color/white</color>\n    <color name="
  },
  {
    "path": "aliocrlib/src/main/res/values/dimens.xml",
    "chars": 111,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"crop__bar_height\">56dp</dimen>\n</resources>"
  },
  {
    "path": "aliocrlib/src/main/res/values/public.xml",
    "chars": 907,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    Copyright (C) 2016 The Android Open Source Project\n    Licensed under th"
  },
  {
    "path": "aliocrlib/src/main/res/values/strings.xml",
    "chars": 480,
    "preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <string name=\"app_name\">aliocrlib</string>\n    <string na"
  },
  {
    "path": "aliocrlib/src/main/res/values/styles.xml",
    "chars": 3168,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    Copyright (C) 2016 The Android Open Source Project\n    Licensed under th"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 865,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion rootProject.ext.android[\"compileSdkVersion\"]\n  "
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 903,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest package=\"com.xin.lockdemo\"\n          xmlns:android=\"http://schemas.andr"
  },
  {
    "path": "app/src/main/java/com/xin/lockdemo/App.java",
    "chars": 515,
    "preview": "package com.xin.lockdemo;\n\nimport android.app.Application;\n\nimport com.lib.lock.fingerprint.utils.FingerContext;\nimport "
  },
  {
    "path": "app/src/main/java/com/xin/lockdemo/GesturePswMainActivity.java",
    "chars": 2367,
    "preview": "package com.xin.lockdemo;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.Intent;\ni"
  },
  {
    "path": "app/src/main/java/com/xin/lockdemo/MainActivity.java",
    "chars": 4747,
    "preview": "package com.xin.lockdemo;\n\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.support.v4.app.FragmentManag"
  },
  {
    "path": "app/src/main/java/com/xin/lockdemo/dialog/CustomDialog.java",
    "chars": 1819,
    "preview": "package com.xin.lockdemo.dialog;\n\nimport android.app.Dialog;\nimport android.content.Context;\nimport android.os.Bundle;\ni"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5577,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    androi"
  },
  {
    "path": "app/src/main/res/drawable/login_shape_bg_finger_change_dialog.xml",
    "chars": 200,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <corners a"
  },
  {
    "path": "app/src/main/res/layout/activity_gesture_psw_main.xml",
    "chars": 998,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        "
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 1768,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    "
  },
  {
    "path": "app/src/main/res/layout/common_dialog_custom_view_layout.xml",
    "chars": 571,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      "
  },
  {
    "path": "app/src/main/res/layout/login_finger_change_dialog.xml",
    "chars": 1289,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        "
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 262,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#15A9F2</color>\n    <color name=\"color"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 213,
    "preview": "<resources>\n    <string name=\"app_name\">lock demo</string>\n\n    <string name=\"login_btn_text_fingerprint_psw\">设置录纹密码</st"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 929,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "build.gradle",
    "chars": 573,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    a"
  },
  {
    "path": "config.gradle",
    "chars": 428,
    "preview": "ext {\n\n\n    android = [\n            compileSdkVersion: 26,\n            minSdkVersion    : 16,\n            targetSdkVersi"
  },
  {
    "path": "fingerprintlib/README.MD",
    "chars": 103,
    "preview": "## 指纹识别封装\n\n#### 使用:\n  程序入口处或使用前初始化指纹密码\n    FingerContext.init(this);\n\n\n * 作者:xin\n * 邮箱:ittfxin@126.com\n"
  },
  {
    "path": "fingerprintlib/build.gradle",
    "chars": 615,
    "preview": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 27\n    defaultConfig {\n        minSdkVersion 16\n   "
  },
  {
    "path": "fingerprintlib/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "fingerprintlib/src/main/AndroidManifest.xml",
    "chars": 363,
    "preview": "<manifest package=\"com.lib.lock.fingerprint\"\n          xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    "
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/activities/FingerprintPswMainActivity.java",
    "chars": 2675,
    "preview": "package com.lib.lock.fingerprint.activities;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport androi"
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/core/CryptoObjectCreator.java",
    "chars": 6075,
    "preview": "package com.lib.lock.fingerprint.core;\n\nimport android.annotation.TargetApi;\nimport android.hardware.fingerprint.Fingerp"
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/core/FingerprintCore.java",
    "chars": 9173,
    "preview": "package com.lib.lock.fingerprint.core;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport andr"
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/core/MyListener.java",
    "chars": 256,
    "preview": "package com.lib.lock.fingerprint.core;\n\n/**\n * 作者:xin on 2018/7/9 0009 15:03\n * <p>\n * 邮箱:ittfxin@126.com\n * <p>\n * http"
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/dialog/FingerDialog.java",
    "chars": 1885,
    "preview": "package com.lib.lock.fingerprint.dialog;\n\nimport android.app.Dialog;\nimport android.content.Context;\nimport android.os.B"
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/utils/FingerContext.java",
    "chars": 936,
    "preview": "package com.lib.lock.fingerprint.utils;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport "
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/utils/FingerprintUtil.java",
    "chars": 7360,
    "preview": "package com.lib.lock.fingerprint.utils;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.con"
  },
  {
    "path": "fingerprintlib/src/main/java/com/lib/lock/fingerprint/utils/KeyguardLockScreenManager.java",
    "chars": 1773,
    "preview": "package com.lib.lock.fingerprint.utils;\n\nimport android.app.Activity;\nimport android.app.KeyguardManager;\nimport android"
  },
  {
    "path": "fingerprintlib/src/main/res/anim/anim_shake.xml",
    "chars": 949,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      >\n    <!-- "
  },
  {
    "path": "fingerprintlib/src/main/res/anim/cycle.xml",
    "chars": 158,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<cycleInterpolator xmlns:android=\"http://schemas.android.com/apk/res/android\"\n   "
  },
  {
    "path": "fingerprintlib/src/main/res/drawable/bg_finger_change_dialog.xml",
    "chars": 201,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <corners a"
  },
  {
    "path": "fingerprintlib/src/main/res/layout/activity_fingerprint_psw_main.xml",
    "chars": 889,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      "
  },
  {
    "path": "fingerprintlib/src/main/res/layout/finger_dialog_custom_view_layout.xml",
    "chars": 528,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      "
  },
  {
    "path": "fingerprintlib/src/main/res/layout/finger_dialog_error.xml",
    "chars": 1563,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        "
  },
  {
    "path": "fingerprintlib/src/main/res/layout/finger_dialog_icon_info.xml",
    "chars": 2366,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      "
  },
  {
    "path": "fingerprintlib/src/main/res/values/strings.xml",
    "chars": 778,
    "preview": "<resources>\n    <string name=\"app_name\">fingerprintlib</string>\n\n    <string name=\"ok\">确定</string>\n    <string name=\"aut"
  },
  {
    "path": "fingerprintlib/src/main/res/values/style.xml",
    "chars": 623,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <!--对话框-->\n    <style name=\"dialog_finger\" parent=\"@android:styl"
  },
  {
    "path": "gesturepswlib/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "gesturepswlib/build.gradle",
    "chars": 697,
    "preview": "apply plugin: 'com.android.library'\n\n\n\nandroid {\n    compileSdkVersion rootProject.ext.android[\"compileSdkVersion\"]\n\n\n  "
  },
  {
    "path": "gesturepswlib/proguard-rules.pro",
    "chars": 932,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "gesturepswlib/src/main/AndroidManifest.xml",
    "chars": 535,
    "preview": "<manifest package=\"com.lib.lock.gesture\"\n          xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <app"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/activities/GestureSettingsActivity.java",
    "chars": 2917,
    "preview": "package com.lib.lock.gesture.activities;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/activities/GestureVerifyActivity.java",
    "chars": 3015,
    "preview": "package com.lib.lock.gesture.activities;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/bean/CellBean.java",
    "chars": 607,
    "preview": "package com.lib.lock.gesture.bean;\n\n\n\npublic class CellBean {\n\n    public int id;\n    public float x;\n    public float y"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/bean/CellFactory.java",
    "chars": 927,
    "preview": "package com.lib.lock.gesture.bean;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\n\n\npublic class CellFactory {\n  "
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/config/Config.java",
    "chars": 1942,
    "preview": "package com.lib.lock.gesture.config;\n\nimport android.content.res.Resources;\nimport android.graphics.Color;\nimport androi"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/content/DataKeeper.java",
    "chars": 2579,
    "preview": "/*\n * Copyright (C) 2013 litesuits.com\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you ma"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/content/SPManager.java",
    "chars": 1320,
    "preview": "package com.lib.lock.gesture.content;\n\n\nimport com.lib.lock.gesture.utils.ContextUtils;\n\n/**\n * Description :SharedPrefe"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/content/SharedPreferencesKeys.java",
    "chars": 690,
    "preview": "package com.lib.lock.gesture.content;\n\n/**\n * <p>\n * 邮箱:ittfxin@126.com\n * <p>\n * https://github.com/wzx54321/XinFramewo"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/content/readme.txt",
    "chars": 17,
    "preview": "SharedPreferences"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultIndicatorHitCellView.java",
    "chars": 1475,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultIndicatorLinkedLineView.java",
    "chars": 2308,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultIndicatorNormalCellView.java",
    "chars": 1703,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerHitCellView.java",
    "chars": 3294,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerLinkedLineView.java",
    "chars": 2751,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerNormalCellView.java",
    "chars": 1779,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/DefaultLockerNormalCustomCellView.java",
    "chars": 1895,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android."
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/IHitCellView.java",
    "chars": 399,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.support.annotation.NonNull;\n\nim"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/IIndicatorLinkedLineView.java",
    "chars": 584,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.support.annotation.NonNull;\nimp"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/ILockerLinkedLineView.java",
    "chars": 672,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.support.annotation.NonNull;\nimp"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/INormalCellView.java",
    "chars": 391,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.graphics.Canvas;\nimport android.support.annotation.NonNull;\n\nim"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/OnPatternChangeListener.java",
    "chars": 712,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport java.util.List;\n\n/**\n */\n\npublic interface OnPatternChangeListener {\n  "
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/PatternIndicatorView.java",
    "chars": 7814,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport "
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/customView/PatternLockerView.java",
    "chars": 11140,
    "preview": "package com.lib.lock.gesture.customView;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport "
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/utils/ContextUtils.java",
    "chars": 934,
    "preview": "package com.lib.lock.gesture.utils;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport andr"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/utils/PatternHelper.java",
    "chars": 3301,
    "preview": "package com.lib.lock.gesture.utils;\n\nimport android.text.TextUtils;\n\nimport com.lib.lock.gesture.content.SPManager;\n\nimp"
  },
  {
    "path": "gesturepswlib/src/main/java/com/lib/lock/gesture/utils/SecurityUtil.java",
    "chars": 3937,
    "preview": "package com.lib.lock.gesture.utils;\n\nimport java.io.UnsupportedEncodingException;\n\nimport javax.crypto.Cipher;\nimport ja"
  },
  {
    "path": "gesturepswlib/src/main/res/layout/activity_gesture_settings.xml",
    "chars": 2227,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      "
  },
  {
    "path": "gesturepswlib/src/main/res/layout/activity_gesture_verify.xml",
    "chars": 1218,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        "
  },
  {
    "path": "gesturepswlib/src/main/res/values/attrs.xml",
    "chars": 918,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"PatternIndicatorView\">\n        <attr nam"
  },
  {
    "path": "gesturepswlib/src/main/res/values/strings.xml",
    "chars": 70,
    "preview": "<resources>\n    <string name=\"app_name\">Library</string>\n</resources>\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Mon Jul 16 11:27:18 CST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 730,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "settings.gradle",
    "chars": 73,
    "preview": "include ':app', ':gesturepswlib', ':aliocrlib',\n        ':fingerprintlib'"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the wzx54321/LockDemo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 161 files (542.1 KB), approximately 129.1k tokens, and a symbol index with 1073 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!