Commit 70af6e722357e53e284e9f140c351ab8a594d297
Merge branch 'master' of http://bj.gitlab.cnlive.com/cnlive-team/newModuleStrike
Showing
37 changed files
with
0 additions
and
4646 deletions
Too many changes to show.
To preserve performance only 37 of 178 files are displayed.
.idea/gradle.xml
| ... | ... | @@ -24,7 +24,6 @@ |
| 24 | 24 | <option value="$PROJECT_DIR$/core/app_qr" /> |
| 25 | 25 | <option value="$PROJECT_DIR$/core/base" /> |
| 26 | 26 | <option value="$PROJECT_DIR$/core/database" /> |
| 27 | - <option value="$PROJECT_DIR$/core/dentity_verfication" /> | |
| 28 | 27 | <option value="$PROJECT_DIR$/core/imageload" /> |
| 29 | 28 | <option value="$PROJECT_DIR$/core/network" /> |
| 30 | 29 | <option value="$PROJECT_DIR$/library_baidumap" /> | ... | ... |
app/strike/build.gradle
| ... | ... | @@ -187,7 +187,6 @@ dependencies { |
| 187 | 187 | // implementation project(path: ':core:encipher') |
| 188 | 188 | // implementation project(path: ':cloud:user') |
| 189 | 189 | implementation project(path: ':cloud:wjj_lib') |
| 190 | - implementation project(path: ':core:dentity_verfication') | |
| 191 | 190 | implementation "androidx.viewpager2:viewpager2:1.0.0" |
| 192 | 191 | |
| 193 | 192 | ... | ... |
app/strike/src/main/AndroidManifest.xml
| ... | ... | @@ -17,7 +17,6 @@ |
| 17 | 17 | android:roundIcon="@mipmap/ic_launcher_round" |
| 18 | 18 | android:supportsRtl="true" |
| 19 | 19 | android:theme="@style/AppTheme"> |
| 20 | - <activity android:name="com.cnlive.strike.imgutil.UgcActivity"></activity> | |
| 21 | 20 | <activity android:name="com.cnlive.strike.imgutil.SimplePrevActivity" /> |
| 22 | 21 | <activity android:name="com.cnlive.strike.demo.activity.HappyChinaActivity" /> |
| 23 | 22 | ... | ... |
app/strike/src/main/java/com/cnlive/strike/MainActivity.java
| ... | ... | @@ -10,7 +10,6 @@ import android.view.View; |
| 10 | 10 | import com.cnlive.cloud.R; |
| 11 | 11 | import com.cnlive.strike.demo.activity.DemoMvpActivity; |
| 12 | 12 | import com.cnlive.strike.imgutil.ImgActivity; |
| 13 | -import com.cnlive.strike.imgutil.UgcActivity; | |
| 14 | 13 | |
| 15 | 14 | import androidx.annotation.NonNull; |
| 16 | 15 | import androidx.annotation.Nullable; |
| ... | ... | @@ -31,7 +30,6 @@ public class MainActivity extends AppCompatActivity { |
| 31 | 30 | } |
| 32 | 31 | }); |
| 33 | 32 | findViewById(R.id.to_img).setOnClickListener(view -> startActivity(new Intent(this, ImgActivity.class))); |
| 34 | - findViewById(R.id.ugc_btn).setOnClickListener(view -> startActivity(new Intent(this, UgcActivity.class))); | |
| 35 | 33 | } |
| 36 | 34 | |
| 37 | 35 | @Nullable | ... | ... |
app/strike/src/main/java/com/cnlive/strike/imgutil/UgcActivity.java deleted
100644 → 0
| 1 | -package com.cnlive.strike.imgutil; | |
| 2 | - | |
| 3 | -import android.content.Intent; | |
| 4 | -import android.os.Bundle; | |
| 5 | - | |
| 6 | -import com.cnlive.cloud.R; | |
| 7 | -import com.cnlive.core.company_verfication.ui.activity.FillInCompanyDataActivity; | |
| 8 | -import com.cnlive.core.company_verfication.ui.activity.SelectCompanyDataActivity; | |
| 9 | -import com.cnlive.core.people_verfication.activity.CheckResultActivity; | |
| 10 | -import com.cnlive.core.people_verfication.activity.PersonCheckActivity; | |
| 11 | -import com.cnlive.core.people_verfication.activity.TakeIdentityPictureActivity; | |
| 12 | - | |
| 13 | -import androidx.appcompat.app.AppCompatActivity; | |
| 14 | - | |
| 15 | -public class UgcActivity extends AppCompatActivity { | |
| 16 | - | |
| 17 | - @Override | |
| 18 | - protected void onCreate(Bundle savedInstanceState) { | |
| 19 | - super.onCreate(savedInstanceState); | |
| 20 | - setContentView(R.layout.activity_ugc); | |
| 21 | - | |
| 22 | - findViewById(R.id.people_denty).setOnClickListener(view -> startActivity(new Intent(this, TakeIdentityPictureActivity.class))); | |
| 23 | - findViewById(R.id.company_denty).setOnClickListener(view -> startActivity(new Intent(this, FillInCompanyDataActivity.class))); | |
| 24 | - findViewById(R.id.company_denty_list).setOnClickListener(view -> startActivity(new Intent(this, SelectCompanyDataActivity.class))); | |
| 25 | - | |
| 26 | - findViewById(R.id.btn1).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","-1")); | |
| 27 | - findViewById(R.id.btn2).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","0")); | |
| 28 | - findViewById(R.id.btn3).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","2")); | |
| 29 | - findViewById(R.id.btn4).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","1")); | |
| 30 | - | |
| 31 | - findViewById(R.id.btn01).setOnClickListener(view -> CheckResultActivity.startActivity(this,"","person","-1")); | |
| 32 | - findViewById(R.id.btn02).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","person","0")); | |
| 33 | - findViewById(R.id.btn03).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","person","2")); | |
| 34 | - findViewById(R.id.btn04).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","person","1")); | |
| 35 | - | |
| 36 | - findViewById(R.id.btn11).setOnClickListener(view -> CheckResultActivity.startActivity(this,"","company","-1")); | |
| 37 | - findViewById(R.id.btn12).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","company","0")); | |
| 38 | - findViewById(R.id.btn13).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","company","2")); | |
| 39 | - findViewById(R.id.btn14).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","company","1")); | |
| 40 | - } | |
| 41 | -} |
app/strike/src/main/res/layout/activity_main.xml
| ... | ... | @@ -21,11 +21,5 @@ |
| 21 | 21 | android:layout_height="wrap_content" |
| 22 | 22 | android:text="图片加载测试"/> |
| 23 | 23 | |
| 24 | - <Button | |
| 25 | - android:id="@+id/ugc_btn" | |
| 26 | - android:layout_width="wrap_content" | |
| 27 | - android:layout_height="wrap_content" | |
| 28 | - android:text="ugc直播认证" | |
| 29 | - /> | |
| 30 | 24 | </LinearLayout> |
| 31 | 25 | </layout> |
| 32 | 26 | \ No newline at end of file | ... | ... |
app/strike/src/main/res/layout/activity_ugc.xml deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="utf-8"?> | |
| 2 | -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | - xmlns:app="http://schemas.android.com/apk/res-auto" | |
| 4 | - xmlns:tools="http://schemas.android.com/tools" | |
| 5 | - android:layout_width="match_parent" | |
| 6 | - android:layout_height="match_parent" | |
| 7 | - android:orientation="vertical" | |
| 8 | - tools:context="com.cnlive.strike.imgutil.UgcActivity"> | |
| 9 | - | |
| 10 | - <Button | |
| 11 | - android:id="@+id/people_denty" | |
| 12 | - android:layout_width="match_parent" | |
| 13 | - android:layout_height="wrap_content" | |
| 14 | - android:layout_margin="@dimen/dp_10" | |
| 15 | - android:text="个人认证" /> | |
| 16 | - | |
| 17 | - <TextView | |
| 18 | - android:layout_width="wrap_content" | |
| 19 | - android:layout_height="wrap_content" | |
| 20 | - android:text="身份校验" /> | |
| 21 | - | |
| 22 | - <LinearLayout | |
| 23 | - android:layout_width="match_parent" | |
| 24 | - android:layout_height="wrap_content" | |
| 25 | - android:orientation="horizontal"> | |
| 26 | - | |
| 27 | - <Button | |
| 28 | - android:id="@+id/btn1" | |
| 29 | - android:layout_width="wrap_content" | |
| 30 | - android:layout_height="wrap_content" | |
| 31 | - android:text="未校验" /> | |
| 32 | - | |
| 33 | - <Button | |
| 34 | - android:id="@+id/btn2" | |
| 35 | - android:layout_width="wrap_content" | |
| 36 | - android:layout_height="wrap_content" | |
| 37 | - android:text="审核中" /> | |
| 38 | - | |
| 39 | - <Button | |
| 40 | - android:id="@+id/btn3" | |
| 41 | - android:layout_width="wrap_content" | |
| 42 | - android:layout_height="wrap_content" | |
| 43 | - android:text="失败" /> | |
| 44 | - | |
| 45 | - <Button | |
| 46 | - android:id="@+id/btn4" | |
| 47 | - android:layout_width="wrap_content" | |
| 48 | - android:layout_height="wrap_content" | |
| 49 | - android:text="成功" /> | |
| 50 | - </LinearLayout> | |
| 51 | - | |
| 52 | - <TextView | |
| 53 | - android:layout_width="wrap_content" | |
| 54 | - android:layout_height="wrap_content" | |
| 55 | - android:text="个人认证" /> | |
| 56 | - | |
| 57 | - <LinearLayout | |
| 58 | - android:layout_width="match_parent" | |
| 59 | - android:layout_height="wrap_content" | |
| 60 | - android:orientation="horizontal"> | |
| 61 | - | |
| 62 | - <Button | |
| 63 | - android:id="@+id/btn01" | |
| 64 | - android:layout_width="wrap_content" | |
| 65 | - android:layout_height="wrap_content" | |
| 66 | - android:text="未认证" /> | |
| 67 | - | |
| 68 | - <Button | |
| 69 | - android:id="@+id/btn02" | |
| 70 | - android:layout_width="wrap_content" | |
| 71 | - android:layout_height="wrap_content" | |
| 72 | - android:text="审核中" /> | |
| 73 | - | |
| 74 | - <Button | |
| 75 | - android:id="@+id/btn03" | |
| 76 | - android:layout_width="wrap_content" | |
| 77 | - android:layout_height="wrap_content" | |
| 78 | - android:text="失败" /> | |
| 79 | - | |
| 80 | - <Button | |
| 81 | - android:id="@+id/btn04" | |
| 82 | - android:layout_width="wrap_content" | |
| 83 | - android:layout_height="wrap_content" | |
| 84 | - android:text="成功" /> | |
| 85 | - </LinearLayout> | |
| 86 | - | |
| 87 | - | |
| 88 | - | |
| 89 | - <Button | |
| 90 | - android:id="@+id/company_denty" | |
| 91 | - android:layout_width="match_parent" | |
| 92 | - android:layout_height="wrap_content" | |
| 93 | - android:layout_margin="@dimen/dp_10" | |
| 94 | - android:text="机构认证" /> | |
| 95 | - | |
| 96 | - <TextView | |
| 97 | - android:layout_width="wrap_content" | |
| 98 | - android:layout_height="wrap_content" | |
| 99 | - android:text="机构认证" /> | |
| 100 | - | |
| 101 | - <LinearLayout | |
| 102 | - android:layout_width="match_parent" | |
| 103 | - android:layout_height="wrap_content" | |
| 104 | - android:orientation="horizontal"> | |
| 105 | - | |
| 106 | - <Button | |
| 107 | - android:id="@+id/btn11" | |
| 108 | - android:layout_width="wrap_content" | |
| 109 | - android:layout_height="wrap_content" | |
| 110 | - android:text="未认证" /> | |
| 111 | - | |
| 112 | - <Button | |
| 113 | - android:id="@+id/btn12" | |
| 114 | - android:layout_width="wrap_content" | |
| 115 | - android:layout_height="wrap_content" | |
| 116 | - android:text="审核中" /> | |
| 117 | - | |
| 118 | - <Button | |
| 119 | - android:id="@+id/btn13" | |
| 120 | - android:layout_width="wrap_content" | |
| 121 | - android:layout_height="wrap_content" | |
| 122 | - android:text="失败" /> | |
| 123 | - | |
| 124 | - <Button | |
| 125 | - android:id="@+id/btn14" | |
| 126 | - android:layout_width="wrap_content" | |
| 127 | - android:layout_height="wrap_content" | |
| 128 | - android:text="成功" /> | |
| 129 | - </LinearLayout> | |
| 130 | - | |
| 131 | - <Button | |
| 132 | - android:id="@+id/company_denty_list" | |
| 133 | - android:layout_width="match_parent" | |
| 134 | - android:layout_height="wrap_content" | |
| 135 | - android:layout_margin="@dimen/dp_10" | |
| 136 | - android:text="机构认证列表" /> | |
| 137 | -</LinearLayout> |
core/dentity_verfication/.gitignore deleted
100644 → 0
| 1 | -/build |
core/dentity_verfication/build.gradle deleted
100644 → 0
| 1 | -apply plugin: 'com.android.library' | |
| 2 | - | |
| 3 | -android { | |
| 4 | - | |
| 5 | -} | |
| 6 | - | |
| 7 | -dependencies { | |
| 8 | - implementation fileTree(include: ['*.jar'], dir: 'libs') | |
| 9 | - implementation 'androidx.appcompat:appcompat:1.0.2' | |
| 10 | - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | |
| 11 | - implementation 'androidx.legacy:legacy-support-v4:1.0.0' | |
| 12 | - testImplementation 'junit:junit:4.12' | |
| 13 | - androidTestImplementation 'androidx.test.ext:junit:1.1.1' | |
| 14 | - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | |
| 15 | - implementation "com.cnlive.libs:mediapicker:$rootProject.libMediaPicker" | |
| 16 | - implementation files('libs/license.jar') | |
| 17 | -} |
core/dentity_verfication/consumer-rules.pro deleted
100644 → 0
core/dentity_verfication/libs/license.jar deleted
100644 → 0
No preview for this file type
core/dentity_verfication/libs/ocr-sdk.jar deleted
100644 → 0
No preview for this file type
core/dentity_verfication/proguard-rules.pro deleted
100644 → 0
| 1 | -# Add project specific ProGuard rules here. | |
| 2 | -# You can control the set of applied configuration files using the | |
| 3 | -# proguardFiles setting in build.gradle. | |
| 4 | -# | |
| 5 | -# For more details, see | |
| 6 | -# http://developer.android.com/guide/developing/tools/proguard.html | |
| 7 | - | |
| 8 | -# If your project uses WebView with JS, uncomment the following | |
| 9 | -# and specify the fully qualified class name to the JavaScript interface | |
| 10 | -# class: | |
| 11 | -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | |
| 12 | -# public *; | |
| 13 | -#} | |
| 14 | - | |
| 15 | -# Uncomment this to preserve the line number information for | |
| 16 | -# debugging stack traces. | |
| 17 | -#-keepattributes SourceFile,LineNumberTable | |
| 18 | - | |
| 19 | -# If you keep the line number information, uncomment this to | |
| 20 | -# hide the original source file name. | |
| 21 | -#-renamesourcefileattribute SourceFile |
core/dentity_verfication/src/main/AndroidManifest.xml deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="utf-8"?> | |
| 2 | -<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
| 3 | - package="com.cnlive.core.people_verfication"> | |
| 4 | - | |
| 5 | - <uses-permission android:name="android.permission.CAMERA" /> | |
| 6 | - <uses-permission android:name="android.permission.INTERNET" /> | |
| 7 | - <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | |
| 8 | - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |
| 9 | - | |
| 10 | - <uses-feature android:name="android.hardware.camera2.full" /> | |
| 11 | - <uses-feature android:name="android.hardware.camera" /> | |
| 12 | - <uses-feature android:name="android.hardware.camera.autofocus" /> | |
| 13 | - | |
| 14 | - <application> | |
| 15 | - <activity android:name=".activity.PersonCheckActivity"></activity> | |
| 16 | - <activity android:name=".activity.CheckResultActivity" /> | |
| 17 | - <activity android:name="com.cnlive.core.company_verfication.ui.activity.FillInCompanyDataActivity"></activity> | |
| 18 | - <activity android:name="com.cnlive.core.company_verfication.ui.activity.SelectCompanyDataActivity" /> | |
| 19 | - <activity android:name=".activity.TakeIdentityPictureActivity" /> | |
| 20 | - <activity | |
| 21 | - android:name="com.cnlive.core.ocr.ui.camera.CameraActivity" | |
| 22 | - android:configChanges="screenSize|orientation" | |
| 23 | - android:launchMode="singleTop" | |
| 24 | - android:screenOrientation="portrait" | |
| 25 | - android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" /> | |
| 26 | - </application> | |
| 27 | - | |
| 28 | -</manifest> | |
| 29 | 0 | \ No newline at end of file |
core/dentity_verfication/src/main/assets/models/integrity_model_secret.bin deleted
100644 → 0
No preview for this file type
core/dentity_verfication/src/main/assets/models/quality_model_secret.bin deleted
100644 → 0
No preview for this file type
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/activity/FillInCompanyDataActivity.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.activity; | |
| 2 | - | |
| 3 | -import com.cnlive.core.company_verfication.ui.fragment.FillInCompanyDataFragment; | |
| 4 | -import com.cnlive.core.libs.base.frame.activity.BaseActivity; | |
| 5 | -import com.cnlive.core.people_verfication.R; | |
| 6 | - | |
| 7 | -public class FillInCompanyDataActivity extends BaseActivity { | |
| 8 | - | |
| 9 | - @Override | |
| 10 | - protected void initView() { | |
| 11 | - loadRootFragment(new FillInCompanyDataFragment()); | |
| 12 | - } | |
| 13 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/activity/SelectCompanyDataActivity.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.activity; | |
| 2 | - | |
| 3 | -import androidx.databinding.ViewDataBinding; | |
| 4 | -import androidx.recyclerview.widget.LinearLayoutManager; | |
| 5 | - | |
| 6 | -import com.cnlive.core.company_verfication.ui.adapter.CompanyDataAdapter; | |
| 7 | -import com.cnlive.core.company_verfication.ui.fragment.SelectCompanyDataFragment; | |
| 8 | -import com.cnlive.core.libs.base.frame.activity.BaseActivity; | |
| 9 | -import com.cnlive.core.people_verfication.R; | |
| 10 | -import com.cnlive.core.people_verfication.databinding.FragmentFillInCompanyDataBinding; | |
| 11 | - | |
| 12 | -import java.util.ArrayList; | |
| 13 | -import java.util.List; | |
| 14 | - | |
| 15 | -public class SelectCompanyDataActivity extends BaseActivity { | |
| 16 | - | |
| 17 | - @Override | |
| 18 | - protected void initView() { | |
| 19 | - loadRootFragment(new SelectCompanyDataFragment()); | |
| 20 | - } | |
| 21 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/adapter/CompanyDataAdapter.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.adapter; | |
| 2 | - | |
| 3 | -import android.content.Context; | |
| 4 | -import android.view.LayoutInflater; | |
| 5 | -import android.view.View; | |
| 6 | -import android.view.ViewGroup; | |
| 7 | -import android.widget.TextView; | |
| 8 | - | |
| 9 | -import androidx.annotation.NonNull; | |
| 10 | -import androidx.databinding.DataBindingUtil; | |
| 11 | -import androidx.recyclerview.widget.RecyclerView; | |
| 12 | - | |
| 13 | -import com.cnlive.core.people_verfication.R; | |
| 14 | -import com.cnlive.core.people_verfication.databinding.ItemCompanyDateBinding; | |
| 15 | - | |
| 16 | -import java.util.List; | |
| 17 | - | |
| 18 | -public class CompanyDataAdapter extends RecyclerView.Adapter { | |
| 19 | - private Context context; | |
| 20 | - private List<String> data; | |
| 21 | - | |
| 22 | - public CompanyDataAdapter(Context context, List<String> data) { | |
| 23 | - this.context = context; | |
| 24 | - this.data = data; | |
| 25 | - } | |
| 26 | - | |
| 27 | - @NonNull | |
| 28 | - @Override | |
| 29 | - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | |
| 30 | - LayoutInflater inflater = LayoutInflater.from(context); | |
| 31 | - ItemCompanyDateBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_company_date, parent, false); | |
| 32 | - return new MyViewHolder(binding); | |
| 33 | - } | |
| 34 | - | |
| 35 | - @Override | |
| 36 | - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { | |
| 37 | - ItemCompanyDateBinding binding = ((MyViewHolder) holder).binding; | |
| 38 | - binding.includeAccountChild.llRoot.getBaselineAlignedChildIndex(); | |
| 39 | - binding.includeAccountChild.llChildAccountDelete.setVisibility(View.GONE); | |
| 40 | - } | |
| 41 | - | |
| 42 | - @Override | |
| 43 | - public int getItemCount() { | |
| 44 | - return data.size(); | |
| 45 | - } | |
| 46 | - | |
| 47 | - private class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { | |
| 48 | - private ItemCompanyDateBinding binding; | |
| 49 | - | |
| 50 | - public MyViewHolder(@NonNull ItemCompanyDateBinding binding) { | |
| 51 | - super(binding.getRoot()); | |
| 52 | - this.binding = binding; | |
| 53 | - binding.includeAddCircle.btnAddChildCircle.setOnClickListener(this); | |
| 54 | - binding.includeAddChildAccount.btnAddChildAccount.setOnClickListener(this); | |
| 55 | - } | |
| 56 | - | |
| 57 | - | |
| 58 | - @Override | |
| 59 | - public void onClick(View v) { | |
| 60 | - //添加圈子 | |
| 61 | - if (v.getId() == R.id.btn_addChildCircle) { | |
| 62 | - View child = LayoutInflater.from(context).inflate(R.layout.item_company_data_type_circle_child, null); | |
| 63 | - binding.includeCircleChild.llRoot.addView(child); | |
| 64 | - } | |
| 65 | - //添加群组 | |
| 66 | - else if (v.getId() == R.id.btn_addChildAccount) { | |
| 67 | - View child = LayoutInflater.from(context).inflate(R.layout.item_company_data_type_child_account, null); | |
| 68 | - int index=binding.includeAccountChild.llRoot.getChildCount() - 1; | |
| 69 | - binding.includeAccountChild.llRoot.addView(child, index); | |
| 70 | - TextView textView = child.findViewById(R.id.ll_child_account_delete); | |
| 71 | - textView.setVisibility(View.VISIBLE); | |
| 72 | - textView.setOnClickListener(this); | |
| 73 | - textView.setTag(child); | |
| 74 | -// textView.setOnClickListener(new View.OnClickListener() { | |
| 75 | -// @Override | |
| 76 | -// public void onClick(View v) { | |
| 77 | -// binding.includeAccountChild.llRoot.removeView(child); | |
| 78 | -// } | |
| 79 | -// }); | |
| 80 | - } else if (v.getId() == R.id.ll_child_account_delete) { | |
| 81 | - if (null!=v&&null!=v.getTag()){ | |
| 82 | - View child= (View) v.getTag(); | |
| 83 | - //获取当前子类 | |
| 84 | - binding.includeAccountChild.llRoot.removeView(child); | |
| 85 | - } | |
| 86 | - | |
| 87 | - } | |
| 88 | - } | |
| 89 | - } | |
| 90 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/adapter/CompanyItemDataAdapter.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.adapter; | |
| 2 | - | |
| 3 | -import android.content.Context; | |
| 4 | -import android.view.LayoutInflater; | |
| 5 | -import android.view.View; | |
| 6 | -import android.view.ViewGroup; | |
| 7 | -import android.widget.TextView; | |
| 8 | - | |
| 9 | -import com.cnlive.core.company_verfication.ui.model.CompanyItemData; | |
| 10 | -import com.cnlive.core.people_verfication.R; | |
| 11 | -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeAddChildAccountBinding; | |
| 12 | -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeAddCircleBinding; | |
| 13 | -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeAddOrganizationBinding; | |
| 14 | -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeChildAccountBinding; | |
| 15 | -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeCircleChildBinding; | |
| 16 | -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeOrganizationBinding; | |
| 17 | - | |
| 18 | -import java.util.List; | |
| 19 | - | |
| 20 | -import androidx.annotation.NonNull; | |
| 21 | -import androidx.databinding.DataBindingUtil; | |
| 22 | -import androidx.recyclerview.widget.RecyclerView; | |
| 23 | - | |
| 24 | -/* | |
| 25 | - *@date:2020/4/7 16:29 | |
| 26 | - *@author:杨帅 | |
| 27 | - */public class CompanyItemDataAdapter extends RecyclerView.Adapter { | |
| 28 | - private Context context; | |
| 29 | - private List<CompanyItemData> dataList; | |
| 30 | - private OnClickListener onClickListener; | |
| 31 | - | |
| 32 | - public CompanyItemDataAdapter(Context context, List<CompanyItemData> dataList) { | |
| 33 | - this.context = context; | |
| 34 | - this.dataList = dataList; | |
| 35 | - } | |
| 36 | - | |
| 37 | - public void setOnClickListener(OnClickListener onClickListener) { | |
| 38 | - this.onClickListener = onClickListener; | |
| 39 | - } | |
| 40 | - | |
| 41 | - @NonNull | |
| 42 | - @Override | |
| 43 | - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | |
| 44 | - switch (viewType) { | |
| 45 | - case CompanyItemData.TYPE_ORGANIZATION: | |
| 46 | - ItemCompanyDataTypeOrganizationBinding organizationBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_organization, parent, false); | |
| 47 | - OrganizactionHolder organizactionHolder = new OrganizactionHolder(organizationBinding); | |
| 48 | - return organizactionHolder; | |
| 49 | - case CompanyItemData.TYPE_CIRCLE: | |
| 50 | - ItemCompanyDataTypeCircleChildBinding circleChildBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_circle_child, parent, false); | |
| 51 | - CircleHolder circleHolder = new CircleHolder(circleChildBinding); | |
| 52 | - return circleHolder; | |
| 53 | - case CompanyItemData.TYPE_ADD_CIRCLE: | |
| 54 | - ItemCompanyDataTypeAddCircleBinding addCircleBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_add_circle, parent, false); | |
| 55 | - AddCircleHolder addCircleHolder = new AddCircleHolder(addCircleBinding); | |
| 56 | - return addCircleHolder; | |
| 57 | - case CompanyItemData.TYPE_CHILD_ACCOUNT: | |
| 58 | - ItemCompanyDataTypeChildAccountBinding childAccountBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_child_account, parent, false); | |
| 59 | - ChildAccountHolder childAccountHolder = new ChildAccountHolder(childAccountBinding); | |
| 60 | - return childAccountHolder; | |
| 61 | - case CompanyItemData.TYPE_ADD_CHILD_ACCOUNT: | |
| 62 | - ItemCompanyDataTypeAddChildAccountBinding addChildAccountBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_add_child_account, parent, false); | |
| 63 | - AddChildAccountHolder addChildAccountHolder = new AddChildAccountHolder(addChildAccountBinding); | |
| 64 | - return addChildAccountHolder; | |
| 65 | - case CompanyItemData.TYPE_ADD_ORGANIZATION: | |
| 66 | - ItemCompanyDataTypeAddOrganizationBinding addOrganizationBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_add_organization, parent, false); | |
| 67 | - AddOrganizactionHolder addOrganizactionHolder = new AddOrganizactionHolder(addOrganizationBinding); | |
| 68 | - return addOrganizactionHolder; | |
| 69 | - } | |
| 70 | - return null; | |
| 71 | - } | |
| 72 | - | |
| 73 | - @Override | |
| 74 | - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { | |
| 75 | - switch (getItemViewType(position)) { | |
| 76 | - case CompanyItemData.TYPE_ORGANIZATION: | |
| 77 | - OrganizactionHolder organizactionHolder = (OrganizactionHolder) holder; | |
| 78 | - organizactionHolder.binding.llTopLine.setVisibility(dataList.get(position).isShowTopLine() ? View.VISIBLE : View.GONE); | |
| 79 | - organizactionHolder.binding.ivOrganizationDelete.setVisibility(dataList.get(position).isShowOrganizactionDelete() ? View.VISIBLE : View.GONE); | |
| 80 | - | |
| 81 | - break; | |
| 82 | - case CompanyItemData.TYPE_CIRCLE: | |
| 83 | - CircleHolder circleHolder = (CircleHolder) holder; | |
| 84 | - circleHolder.binding.llCircleDelete.setVisibility(dataList.get(position).isShowDelete() ? View.VISIBLE : View.GONE); | |
| 85 | - break; | |
| 86 | - case CompanyItemData.TYPE_ADD_CIRCLE: | |
| 87 | - break; | |
| 88 | - case CompanyItemData.TYPE_CHILD_ACCOUNT: | |
| 89 | - ChildAccountHolder childAccountHolder = (ChildAccountHolder) holder; | |
| 90 | - childAccountHolder.binding.llChildAccountDelete.setVisibility(dataList.get(position).isShowDelete() ? View.VISIBLE : View.GONE); | |
| 91 | - break; | |
| 92 | - case CompanyItemData.TYPE_ADD_CHILD_ACCOUNT: | |
| 93 | - break; | |
| 94 | - case CompanyItemData.TYPE_ADD_ORGANIZATION: | |
| 95 | - | |
| 96 | - break; | |
| 97 | - } | |
| 98 | - } | |
| 99 | - | |
| 100 | - @Override | |
| 101 | - public int getItemCount() { | |
| 102 | - return dataList.size(); | |
| 103 | - } | |
| 104 | - | |
| 105 | - @Override | |
| 106 | - public int getItemViewType(int position) { | |
| 107 | - return dataList.get(position).getType(); | |
| 108 | - } | |
| 109 | - | |
| 110 | - | |
| 111 | - /** | |
| 112 | - * 所属机构 | |
| 113 | - */ | |
| 114 | - public class OrganizactionHolder extends RecyclerView.ViewHolder implements View.OnClickListener { | |
| 115 | - private ItemCompanyDataTypeOrganizationBinding binding; | |
| 116 | - | |
| 117 | - public OrganizactionHolder(@NonNull ItemCompanyDataTypeOrganizationBinding binding) { | |
| 118 | - super(binding.getRoot()); | |
| 119 | - this.binding = binding; | |
| 120 | - binding.ivOrganizationDelete.setOnClickListener(this); | |
| 121 | - binding.tvOrganization.setOnClickListener(this); | |
| 122 | - } | |
| 123 | - | |
| 124 | - @Override | |
| 125 | - public void onClick(View v) { | |
| 126 | - //删除机构 | |
| 127 | - if (v.getId() == R.id.iv_organization_delete) { | |
| 128 | - //获取当前所在逻辑位置 | |
| 129 | - int logicPosition = dataList.get(getLayoutPosition()).getLogicPosition(); | |
| 130 | - deleteLogicItem(logicPosition); | |
| 131 | - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_ORGANIZATION, dataList.get(dataList.size() - 1).getLogicPosition())); | |
| 132 | - notifyDataSetChanged(); | |
| 133 | - } | |
| 134 | - //选中机构 | |
| 135 | - else if (v.getId() == R.id.tv_organization) { | |
| 136 | - if (null != onClickListener) { | |
| 137 | - onClickListener.onClick(binding.tvOrganization); | |
| 138 | - } | |
| 139 | - } | |
| 140 | - } | |
| 141 | - } | |
| 142 | - | |
| 143 | - private void deleteLogicItem(int logicPosition) { | |
| 144 | - if (dataList.size() == 0) { | |
| 145 | - return; | |
| 146 | - } | |
| 147 | - for (int i = dataList.size() - 1; i >= 0; i--) { | |
| 148 | - if (dataList.get(i).getLogicPosition() == logicPosition) { | |
| 149 | - dataList.remove(i); | |
| 150 | - } | |
| 151 | - } | |
| 152 | - } | |
| 153 | - | |
| 154 | - /** | |
| 155 | - * 所属机构圈子 | |
| 156 | - */ | |
| 157 | - public class CircleHolder extends RecyclerView.ViewHolder implements View.OnClickListener { | |
| 158 | - private ItemCompanyDataTypeCircleChildBinding binding; | |
| 159 | - | |
| 160 | - public CircleHolder(@NonNull ItemCompanyDataTypeCircleChildBinding binding) { | |
| 161 | - super(binding.getRoot()); | |
| 162 | - this.binding = binding; | |
| 163 | - binding.llCircleDelete.setOnClickListener(this); | |
| 164 | - } | |
| 165 | - | |
| 166 | - @Override | |
| 167 | - public void onClick(View v) { | |
| 168 | - if (v.getId() == R.id.ll_circle_delete) { | |
| 169 | - int removeIndex = getLayoutPosition(); | |
| 170 | - dataList.remove(removeIndex); | |
| 171 | - notifyItemRemoved(removeIndex); | |
| 172 | - } | |
| 173 | - } | |
| 174 | - } | |
| 175 | - | |
| 176 | - /** | |
| 177 | - * 添加圈子 | |
| 178 | - */ | |
| 179 | - public class AddCircleHolder extends RecyclerView.ViewHolder implements View.OnClickListener { | |
| 180 | - private ItemCompanyDataTypeAddCircleBinding binding; | |
| 181 | - | |
| 182 | - public AddCircleHolder(@NonNull ItemCompanyDataTypeAddCircleBinding binding) { | |
| 183 | - super(binding.getRoot()); | |
| 184 | - this.binding = binding; | |
| 185 | - binding.btnAddChildCircle.setOnClickListener(this); | |
| 186 | - } | |
| 187 | - | |
| 188 | - @Override | |
| 189 | - public void onClick(View v) { | |
| 190 | - if (v.getId() == R.id.btn_addChildCircle) { | |
| 191 | - //获取当前逻辑上的数量 | |
| 192 | - int logicSize = dataList.get(getLayoutPosition()).getLogicPosition(); | |
| 193 | - dataList.add(getLayoutPosition(), new CompanyItemData(CompanyItemData.TYPE_CIRCLE, logicSize, true)); | |
| 194 | - notifyItemInserted(getLayoutPosition() + 1); | |
| 195 | - } | |
| 196 | - } | |
| 197 | - } | |
| 198 | - | |
| 199 | - /** | |
| 200 | - * 所属子账号 | |
| 201 | - */ | |
| 202 | - public class ChildAccountHolder extends RecyclerView.ViewHolder implements View.OnClickListener { | |
| 203 | - private ItemCompanyDataTypeChildAccountBinding binding; | |
| 204 | - | |
| 205 | - public ChildAccountHolder(@NonNull ItemCompanyDataTypeChildAccountBinding binding) { | |
| 206 | - super(binding.getRoot()); | |
| 207 | - this.binding = binding; | |
| 208 | - binding.llChildAccountDelete.setOnClickListener(this); | |
| 209 | - } | |
| 210 | - | |
| 211 | - @Override | |
| 212 | - public void onClick(View v) { | |
| 213 | - if (v.getId() == R.id.ll_child_account_delete) { | |
| 214 | - int removeIndex = getLayoutPosition(); | |
| 215 | - dataList.remove(removeIndex); | |
| 216 | - notifyItemRemoved(removeIndex); | |
| 217 | - | |
| 218 | - } | |
| 219 | - } | |
| 220 | - } | |
| 221 | - | |
| 222 | - /** | |
| 223 | - * 添加子账号 | |
| 224 | - */ | |
| 225 | - public class AddChildAccountHolder extends RecyclerView.ViewHolder implements View.OnClickListener { | |
| 226 | - private ItemCompanyDataTypeAddChildAccountBinding binding; | |
| 227 | - | |
| 228 | - public AddChildAccountHolder(@NonNull ItemCompanyDataTypeAddChildAccountBinding binding) { | |
| 229 | - super(binding.getRoot()); | |
| 230 | - this.binding = binding; | |
| 231 | - binding.btnAddChildAccount.setOnClickListener(this); | |
| 232 | - } | |
| 233 | - | |
| 234 | - @Override | |
| 235 | - public void onClick(View v) { | |
| 236 | - if (v.getId() == R.id.btn_addChildAccount) { | |
| 237 | - //获取当前逻辑上的数量 | |
| 238 | - int logicSize = dataList.get(getLayoutPosition()).getLogicPosition(); | |
| 239 | - dataList.add(getAdapterPosition(), new CompanyItemData(CompanyItemData.TYPE_CHILD_ACCOUNT, logicSize, true)); | |
| 240 | - notifyItemInserted(getLayoutPosition() + 1); | |
| 241 | - | |
| 242 | - } | |
| 243 | - } | |
| 244 | - } | |
| 245 | - | |
| 246 | - /** | |
| 247 | - * 添加机构 | |
| 248 | - */ | |
| 249 | - public class AddOrganizactionHolder extends RecyclerView.ViewHolder implements View.OnClickListener { | |
| 250 | - private ItemCompanyDataTypeAddOrganizationBinding binding; | |
| 251 | - | |
| 252 | - public AddOrganizactionHolder(@NonNull ItemCompanyDataTypeAddOrganizationBinding binding) { | |
| 253 | - super(binding.getRoot()); | |
| 254 | - this.binding = binding; | |
| 255 | - binding.btnAddOrganization.setOnClickListener(this); | |
| 256 | - } | |
| 257 | - | |
| 258 | - @Override | |
| 259 | - public void onClick(View v) { | |
| 260 | - if (v.getId() == R.id.btn_addOrganization) { | |
| 261 | - //获取当前逻辑上的数量 | |
| 262 | - int logicSize = dataList.get(getLayoutPosition()).getLogicPosition(); | |
| 263 | - int selectIndex = getLayoutPosition(); | |
| 264 | - dataList.remove(dataList.size() - 1); | |
| 265 | - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ORGANIZATION, logicSize + 1, true, true)); | |
| 266 | - dataList.add(new CompanyItemData(CompanyItemData.TYPE_CIRCLE, logicSize + 1)); | |
| 267 | - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CIRCLE, logicSize + 1)); | |
| 268 | - dataList.add(new CompanyItemData(CompanyItemData.TYPE_CHILD_ACCOUNT, logicSize + 1)); | |
| 269 | - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CHILD_ACCOUNT, logicSize + 1)); | |
| 270 | - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_ORGANIZATION, logicSize + 1)); | |
| 271 | - notifyItemInserted(selectIndex); | |
| 272 | - } | |
| 273 | - } | |
| 274 | - } | |
| 275 | - | |
| 276 | - public interface OnClickListener { | |
| 277 | - void onClick(TextView textView); | |
| 278 | - } | |
| 279 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/fragment/BottomSheetDialog.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.fragment; | |
| 2 | - | |
| 3 | -import android.os.Bundle; | |
| 4 | -import android.view.LayoutInflater; | |
| 5 | -import android.view.View; | |
| 6 | -import android.view.ViewGroup; | |
| 7 | - | |
| 8 | -import androidx.annotation.NonNull; | |
| 9 | -import androidx.annotation.Nullable; | |
| 10 | - | |
| 11 | -import com.cnlive.core.people_verfication.R; | |
| 12 | -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; | |
| 13 | - | |
| 14 | -public class BottomSheetDialog extends BottomSheetDialogFragment { | |
| 15 | - @Nullable | |
| 16 | - @Override | |
| 17 | - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | |
| 18 | - | |
| 19 | - return inflater.inflate(R.layout.fragment_bottom, container, false); | |
| 20 | - } | |
| 21 | - | |
| 22 | - @Override | |
| 23 | - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { | |
| 24 | - super.onViewCreated(view, savedInstanceState); | |
| 25 | - | |
| 26 | - | |
| 27 | - } | |
| 28 | -} | |
| 29 | 0 | \ No newline at end of file |
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/fragment/FillInCompanyDataFragment.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.fragment; | |
| 2 | - | |
| 3 | -import android.os.Bundle; | |
| 4 | -import android.view.View; | |
| 5 | - | |
| 6 | -import com.cnlive.core.libs.base.frame.fragment.BaseFragment; | |
| 7 | -import com.cnlive.core.people_verfication.R; | |
| 8 | -import com.cnlive.core.people_verfication.databinding.FragmentFillInCompanyDataBinding; | |
| 9 | - | |
| 10 | -import androidx.databinding.ViewDataBinding; | |
| 11 | - | |
| 12 | -/* | |
| 13 | - *@date:2020/4/7 14:50 | |
| 14 | - *@author:杨帅 | |
| 15 | - */public class FillInCompanyDataFragment extends BaseFragment { | |
| 16 | - private FragmentFillInCompanyDataBinding binding; | |
| 17 | - | |
| 18 | - public static FillInCompanyDataFragment newInstance(String userId) { | |
| 19 | - FillInCompanyDataFragment fragment = new FillInCompanyDataFragment(); | |
| 20 | - Bundle args = new Bundle(); | |
| 21 | - args.putString("userId", userId); | |
| 22 | - fragment.setArguments(args); | |
| 23 | - return fragment; | |
| 24 | - } | |
| 25 | - | |
| 26 | - @Override | |
| 27 | - protected int getBindLayoutId() { | |
| 28 | - return R.layout.fragment_fill_in_company_data; | |
| 29 | - } | |
| 30 | - | |
| 31 | - @Override | |
| 32 | - protected void initBindingLayoutData(ViewDataBinding baseBinding) { | |
| 33 | - super.initBindingLayoutData(baseBinding); | |
| 34 | - binding = (FragmentFillInCompanyDataBinding) baseBinding; | |
| 35 | - } | |
| 36 | - | |
| 37 | - @Override | |
| 38 | - protected void initView() { | |
| 39 | - showDefaultWhiteStatusBar(); | |
| 40 | - binding.topbar.setTitle("填写公司信息"); | |
| 41 | - binding.topbar.addLeftImageButton(R.drawable.icon_verficat_back,R.id.back_btn).setOnClickListener(new View.OnClickListener() { | |
| 42 | - @Override | |
| 43 | - public void onClick(View v) { | |
| 44 | - me.finish(); | |
| 45 | - } | |
| 46 | - }); | |
| 47 | - } | |
| 48 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/fragment/SelectCompanyDataFragment.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.fragment; | |
| 2 | - | |
| 3 | -import android.view.Gravity; | |
| 4 | -import android.view.View; | |
| 5 | -import android.view.ViewGroup; | |
| 6 | -import android.widget.LinearLayout; | |
| 7 | -import android.widget.RelativeLayout; | |
| 8 | -import android.widget.TextView; | |
| 9 | - | |
| 10 | -import com.cnlive.core.company_verfication.ui.adapter.CompanyDataAdapter; | |
| 11 | -import com.cnlive.core.company_verfication.ui.adapter.CompanyItemDataAdapter; | |
| 12 | -import com.cnlive.core.company_verfication.ui.model.CompanyItemData; | |
| 13 | -import com.cnlive.core.libs.base.frame.fragment.BaseFragment; | |
| 14 | -import com.cnlive.core.libs.base.util.StatusBarConfig; | |
| 15 | -import com.cnlive.core.libs.base.util.StatusBarUtil; | |
| 16 | -import com.cnlive.core.people_verfication.R; | |
| 17 | -import com.cnlive.core.people_verfication.databinding.FragmentSelectInCompanyDataBinding; | |
| 18 | -import com.google.android.material.bottomsheet.BottomSheetBehavior; | |
| 19 | - | |
| 20 | -import java.util.ArrayList; | |
| 21 | -import java.util.List; | |
| 22 | - | |
| 23 | -import androidx.annotation.NonNull; | |
| 24 | -import androidx.coordinatorlayout.widget.CoordinatorLayout; | |
| 25 | -import androidx.databinding.ViewDataBinding; | |
| 26 | -import androidx.recyclerview.widget.LinearLayoutManager; | |
| 27 | - | |
| 28 | -/* | |
| 29 | - *@date:2020/4/7 14:54 | |
| 30 | - *@author:杨帅 | |
| 31 | - */public class SelectCompanyDataFragment extends BaseFragment { | |
| 32 | - private List<String> data = new ArrayList<>(); | |
| 33 | - private FragmentSelectInCompanyDataBinding binding; | |
| 34 | - private CompanyItemDataAdapter itemDataAdapter; | |
| 35 | - private BottomSheetBehavior behavior; | |
| 36 | - | |
| 37 | - @Override | |
| 38 | - protected int getBindLayoutId() { | |
| 39 | - return R.layout.fragment_select_in_company_data; | |
| 40 | - } | |
| 41 | - | |
| 42 | - @Override | |
| 43 | - protected void initBindingLayoutData(ViewDataBinding baseBinding) { | |
| 44 | - super.initBindingLayoutData(baseBinding); | |
| 45 | - binding = (FragmentSelectInCompanyDataBinding) baseBinding; | |
| 46 | - } | |
| 47 | - | |
| 48 | - @Override | |
| 49 | - protected void initView() { | |
| 50 | - //设置沉浸式状态栏 | |
| 51 | - showImmersiveStatusBar(); | |
| 52 | - //设置状态栏提示文字颜色 | |
| 53 | - setStatusBarTextColor(StatusBarConfig.BLACK); | |
| 54 | - initTopBar(); | |
| 55 | - List<CompanyItemData> list = new ArrayList<>(); | |
| 56 | - list.add(new CompanyItemData(CompanyItemData.TYPE_ORGANIZATION, 0)); | |
| 57 | - list.add(new CompanyItemData(CompanyItemData.TYPE_CIRCLE, 0)); | |
| 58 | - list.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CIRCLE, 0)); | |
| 59 | - list.add(new CompanyItemData(CompanyItemData.TYPE_CHILD_ACCOUNT, 0)); | |
| 60 | - list.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CHILD_ACCOUNT, 0)); | |
| 61 | - list.add(new CompanyItemData(CompanyItemData.TYPE_ADD_ORGANIZATION, 0)); | |
| 62 | - itemDataAdapter = new CompanyItemDataAdapter(me, list); | |
| 63 | - binding.recyclerView.setLayoutManager(new LinearLayoutManager(me)); | |
| 64 | - binding.recyclerView.setAdapter(itemDataAdapter); | |
| 65 | - binding.viewMask.setVisibility(View.GONE); | |
| 66 | - behavior = BottomSheetBehavior.from(binding.llBottom); | |
| 67 | - behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { | |
| 68 | - @Override | |
| 69 | - public void onStateChanged(@NonNull View bottomSheet, @BottomSheetBehavior.State int newState) { | |
| 70 | - String state = "null"; | |
| 71 | - switch (newState) { | |
| 72 | - case 1: | |
| 73 | - state = "STATE_DRAGGING";//过渡状态此时用户正在向上或者向下拖动bottom sheet | |
| 74 | - break; | |
| 75 | - case 2: | |
| 76 | - state = "STATE_SETTLING"; // 视图从脱离手指自由滑动到最终停下的这一小段时间 | |
| 77 | - break; | |
| 78 | - case 3: | |
| 79 | - state = "STATE_EXPANDED"; //处于完全展开的状态 | |
| 80 | - | |
| 81 | - break; | |
| 82 | - case 4: | |
| 83 | - state = "STATE_COLLAPSED"; //默认的折叠状态 | |
| 84 | - binding.viewMask.setVisibility(View.GONE); | |
| 85 | - break; | |
| 86 | - case 5: | |
| 87 | - state = "STATE_HIDDEN"; //下滑动完全隐藏 bottom sheet | |
| 88 | - binding.viewMask.setVisibility(View.GONE); | |
| 89 | - break; | |
| 90 | - } | |
| 91 | - | |
| 92 | - } | |
| 93 | - | |
| 94 | - @Override | |
| 95 | - public void onSlide(@NonNull View view, float v) { | |
| 96 | - | |
| 97 | - } | |
| 98 | - }); | |
| 99 | - //蒙版点击 | |
| 100 | - binding.viewMask.setOnClickListener(new View.OnClickListener() { | |
| 101 | - @Override | |
| 102 | - public void onClick(View v) { | |
| 103 | - if (!isNull(behavior)) { | |
| 104 | - binding.viewMask.setVisibility(View.GONE); | |
| 105 | - behavior.setState(BottomSheetBehavior.STATE_HIDDEN); | |
| 106 | - } | |
| 107 | - } | |
| 108 | - }); | |
| 109 | - | |
| 110 | - itemDataAdapter.setOnClickListener(new CompanyItemDataAdapter.OnClickListener() { | |
| 111 | - @Override | |
| 112 | - public void onClick(TextView textView) { | |
| 113 | - if (!isNull(behavior)) { | |
| 114 | - binding.viewMask.setVisibility(View.VISIBLE); | |
| 115 | - behavior.setState(BottomSheetBehavior.STATE_EXPANDED); | |
| 116 | - } | |
| 117 | -// BottomSheetDialog bottomSheetDialog=new BottomSheetDialog(); | |
| 118 | -// bottomSheetDialog.show(getFragmentManager(),TAG); | |
| 119 | - } | |
| 120 | - }); | |
| 121 | - } | |
| 122 | - | |
| 123 | - private void initTopBar() { | |
| 124 | - // 设置标题栏的内容在状态栏之下 | |
| 125 | - binding.topbar.setTitle("填写公司信息"); | |
| 126 | - // 设置标题栏 + 状态栏的高度 | |
| 127 | - setTitleViewAdjustImmersiveStatusBar(binding.llTop); | |
| 128 | - binding.topbar.addLeftImageButton(R.drawable.icon_verficat_back, R.id.back_btn).setOnClickListener(new View.OnClickListener() { | |
| 129 | - @Override | |
| 130 | - public void onClick(View v) { | |
| 131 | - me.finish(); | |
| 132 | - } | |
| 133 | - }); | |
| 134 | - } | |
| 135 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/model/CompanyItemData.java deleted
100644 → 0
| 1 | -package com.cnlive.core.company_verfication.ui.model; | |
| 2 | - | |
| 3 | -/*机构数据 | |
| 4 | - *@date:2020/4/7 16:24 | |
| 5 | - *@author:杨帅 | |
| 6 | - */public class CompanyItemData { | |
| 7 | - public static final int TYPE_ORGANIZATION = 0;//所属机构 | |
| 8 | - public static final int TYPE_CIRCLE = 1;//您的圈子 | |
| 9 | - public static final int TYPE_ADD_CIRCLE = 2;//添加圈子 | |
| 10 | - public static final int TYPE_CHILD_ACCOUNT = 3;//相关账号 | |
| 11 | - public static final int TYPE_ADD_CHILD_ACCOUNT = 4;//添加子账号 | |
| 12 | - public static final int TYPE_ADD_ORGANIZATION = 5;//添加机构 | |
| 13 | - | |
| 14 | - private int type; | |
| 15 | - private boolean showDelete; | |
| 16 | - private int logicPosition;//逻辑上数量 | |
| 17 | - private boolean showTopLine; | |
| 18 | - private boolean showOrganizactionDelete; | |
| 19 | - | |
| 20 | - public int getType() { | |
| 21 | - return type; | |
| 22 | - } | |
| 23 | - | |
| 24 | - public void setType(int type) { | |
| 25 | - this.type = type; | |
| 26 | - } | |
| 27 | - | |
| 28 | - public boolean isShowDelete() { | |
| 29 | - return showDelete; | |
| 30 | - } | |
| 31 | - | |
| 32 | - public void setShowDelete(boolean showDelete) { | |
| 33 | - this.showDelete = showDelete; | |
| 34 | - } | |
| 35 | - public CompanyItemData(int type, int logicPosition) { | |
| 36 | - this.type = type; | |
| 37 | - this.logicPosition = logicPosition; | |
| 38 | - } | |
| 39 | - | |
| 40 | - public CompanyItemData(int type, int logicPosition, boolean showTopLine, boolean showOrganizactionDelete) { | |
| 41 | - this.type = type; | |
| 42 | - this.logicPosition = logicPosition; | |
| 43 | - this.showTopLine = showTopLine; | |
| 44 | - this.showOrganizactionDelete = showOrganizactionDelete; | |
| 45 | - } | |
| 46 | - | |
| 47 | - public CompanyItemData(int type, int logicPosition, boolean showDelete) { | |
| 48 | - this.type = type; | |
| 49 | - this.logicPosition = logicPosition; | |
| 50 | - this.showDelete = showDelete; | |
| 51 | - } | |
| 52 | - | |
| 53 | - public boolean isShowTopLine() { | |
| 54 | - return showTopLine; | |
| 55 | - } | |
| 56 | - | |
| 57 | - public void setShowTopLine(boolean showTopLine) { | |
| 58 | - this.showTopLine = showTopLine; | |
| 59 | - } | |
| 60 | - | |
| 61 | - public int getLogicPosition() { | |
| 62 | - return logicPosition; | |
| 63 | - } | |
| 64 | - | |
| 65 | - public void setLogicPosition(int logicPosition) { | |
| 66 | - this.logicPosition = logicPosition; | |
| 67 | - } | |
| 68 | - | |
| 69 | - public boolean isShowOrganizactionDelete() { | |
| 70 | - return showOrganizactionDelete; | |
| 71 | - } | |
| 72 | - | |
| 73 | - public void setShowOrganizactionDelete(boolean showOrganizactionDelete) { | |
| 74 | - this.showOrganizactionDelete = showOrganizactionDelete; | |
| 75 | - } | |
| 76 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/RecognizeService.java deleted
100644 → 0
| 1 | -package com.cnlive.core.ocr; | |
| 2 | - | |
| 3 | -import android.content.Context; | |
| 4 | -import android.util.Log; | |
| 5 | - | |
| 6 | -import com.baidu.ocr.sdk.OCR; | |
| 7 | -import com.baidu.ocr.sdk.OnResultListener; | |
| 8 | -import com.baidu.ocr.sdk.exception.OCRError; | |
| 9 | -import com.baidu.ocr.sdk.model.AccessToken; | |
| 10 | -import com.baidu.ocr.sdk.model.BankCardParams; | |
| 11 | -import com.baidu.ocr.sdk.model.BankCardResult; | |
| 12 | -import com.baidu.ocr.sdk.model.IDCardParams; | |
| 13 | -import com.baidu.ocr.sdk.model.IDCardResult; | |
| 14 | - | |
| 15 | -import java.io.File; | |
| 16 | - | |
| 17 | -/** | |
| 18 | - * @author Lynn | |
| 19 | - * @date 2018/1/4 | |
| 20 | - */ | |
| 21 | - | |
| 22 | -public class RecognizeService { | |
| 23 | - | |
| 24 | - /** | |
| 25 | - * 识别银行卡 | |
| 26 | - * | |
| 27 | - * @param filePath 文件路径 | |
| 28 | - * @param listener 回调 | |
| 29 | - */ | |
| 30 | - public static void recBankCard(String filePath, OnResultListener<BankCardResult> listener) { | |
| 31 | - BankCardParams params = new BankCardParams(); | |
| 32 | - params.setImageFile(new File(filePath)); | |
| 33 | - OCR.getInstance().recognizeBankCard(params, listener); | |
| 34 | - } | |
| 35 | - | |
| 36 | - /** | |
| 37 | - * 识别身份证 | |
| 38 | - * | |
| 39 | - * @param idCardSide 身份证正反面 | |
| 40 | - * @param filePath 文件路径 | |
| 41 | - * @param listener 回调 | |
| 42 | - */ | |
| 43 | - public static void recIDCard(String idCardSide, String filePath, OnResultListener<IDCardResult> listener) { | |
| 44 | - IDCardParams param = new IDCardParams(); | |
| 45 | - param.setImageFile(new File(filePath)); | |
| 46 | - // 设置身份证正反面 | |
| 47 | - param.setIdCardSide(idCardSide); | |
| 48 | - // 设置方向检测 | |
| 49 | - param.setDetectDirection(true); | |
| 50 | - // 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20 | |
| 51 | - param.setImageQuality(20); | |
| 52 | - OCR.getInstance().recognizeIDCard(param, listener); | |
| 53 | - } | |
| 54 | - | |
| 55 | - /** | |
| 56 | - * 初始化 with AK & SK | |
| 57 | - * | |
| 58 | - * @param context context | |
| 59 | - */ | |
| 60 | - public static void initAccessTokenWithAkSk(final Context context) { | |
| 61 | - OCR.getInstance().initAccessTokenWithAkSk(new OnResultListener<AccessToken>() { | |
| 62 | - @Override | |
| 63 | - public void onResult(AccessToken result) { | |
| 64 | - String token = result.getAccessToken(); | |
| 65 | - Log.e("LynnTest", result.toString()); | |
| 66 | - } | |
| 67 | - | |
| 68 | - @Override | |
| 69 | - public void onError(OCRError error) { | |
| 70 | - error.printStackTrace(); | |
| 71 | - Log.e("LynnTest", error.getMessage()); | |
| 72 | - } | |
| 73 | - }, context, "YIGsVzdh35y3GCaNUDsxM3cC", "neAe1orXgeTaiHkAbygrgCevKe1fPrG1"); | |
| 74 | - } | |
| 75 | - | |
| 76 | - /** | |
| 77 | - * 初始化 授权文件(安全模式) | |
| 78 | - * | |
| 79 | - * @param context | |
| 80 | - */ | |
| 81 | - public static void initAccessToken(Context context) { | |
| 82 | - OCR.getInstance().initAccessToken(new OnResultListener<AccessToken>() { | |
| 83 | - @Override | |
| 84 | - public void onResult(AccessToken accessToken) { | |
| 85 | - String token = accessToken.getAccessToken(); | |
| 86 | - } | |
| 87 | - | |
| 88 | - @Override | |
| 89 | - public void onError(OCRError ocrError) { | |
| 90 | - | |
| 91 | - } | |
| 92 | - }, context); | |
| 93 | - } | |
| 94 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/idcardquality/IDcardQualityProcess.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.idcardquality; | |
| 5 | - | |
| 6 | -import android.content.res.AssetManager; | |
| 7 | -import android.graphics.Bitmap; | |
| 8 | - | |
| 9 | -import com.baidu.idl.authority.AlgorithmOnMainThreadException; | |
| 10 | -import com.baidu.idl.authority.IDLAuthorityException; | |
| 11 | -import com.baidu.idl.license.License; | |
| 12 | -import com.baidu.idl.util.UIThread; | |
| 13 | - | |
| 14 | - | |
| 15 | -public class IDcardQualityProcess { | |
| 16 | - | |
| 17 | - private static IDcardQualityProcess mInstance; | |
| 18 | - private static String tokenString; | |
| 19 | - private static int mAuthorityStatus; | |
| 20 | - private static Throwable loadNativeException = null; | |
| 21 | - private static volatile boolean hasReleased; | |
| 22 | - | |
| 23 | - public IDcardQualityProcess() { | |
| 24 | - } | |
| 25 | - | |
| 26 | - public static synchronized IDcardQualityProcess getInstance() { | |
| 27 | - if (null == mInstance) { | |
| 28 | - mInstance = new IDcardQualityProcess(); | |
| 29 | - } | |
| 30 | - | |
| 31 | - return mInstance; | |
| 32 | - } | |
| 33 | - | |
| 34 | - public native byte[] convertRGBImage(int[] colors, int width, int height); | |
| 35 | - | |
| 36 | - public native int idcardQualityModelInit(AssetManager var1, String var2); | |
| 37 | - | |
| 38 | - public native int idcardQualityCaptchaRelease(); | |
| 39 | - | |
| 40 | - public native int idcardQualityProcess(byte[] var1, int var2, int var3, boolean var4, int var5); | |
| 41 | - | |
| 42 | - public static synchronized int init(String token) throws AlgorithmOnMainThreadException, IDLAuthorityException { | |
| 43 | - if (UIThread.isUITread()) { | |
| 44 | - throw new AlgorithmOnMainThreadException(); | |
| 45 | - } else { | |
| 46 | - tokenString = token; | |
| 47 | - | |
| 48 | - try { | |
| 49 | - mAuthorityStatus = License.getInstance().init(tokenString); | |
| 50 | - } catch (Exception var2) { | |
| 51 | - if (var2!=null) | |
| 52 | - var2.printStackTrace(); | |
| 53 | - } | |
| 54 | - | |
| 55 | - return mAuthorityStatus; | |
| 56 | - } | |
| 57 | - } | |
| 58 | - | |
| 59 | - public int idcardQualityInit(AssetManager assetManager, String modelPath) { | |
| 60 | - if (mAuthorityStatus == 0) { | |
| 61 | - hasReleased = false; | |
| 62 | - return this.idcardQualityModelInit(assetManager, modelPath); | |
| 63 | - } else { | |
| 64 | - return mAuthorityStatus; | |
| 65 | - } | |
| 66 | - } | |
| 67 | - | |
| 68 | - public int idcardQualityRelease() { | |
| 69 | - if (mAuthorityStatus == 0) { | |
| 70 | - hasReleased = true; | |
| 71 | - this.idcardQualityCaptchaRelease(); | |
| 72 | - return 0; | |
| 73 | - } else { | |
| 74 | - return mAuthorityStatus; | |
| 75 | - } | |
| 76 | - } | |
| 77 | - | |
| 78 | - public int idcardQualityDetectionImg(Bitmap img, boolean isfont) { | |
| 79 | - if (mAuthorityStatus == 0) { | |
| 80 | - if (hasReleased) { | |
| 81 | - return -1; | |
| 82 | - } | |
| 83 | - int imgHeight = img.getHeight(); | |
| 84 | - int imgWidth = img.getWidth(); | |
| 85 | - byte[] imageData = this.getRGBImageData(img); | |
| 86 | - return this.idcardQualityProcess(imageData, imgHeight, imgWidth, isfont, 3); | |
| 87 | - } else { | |
| 88 | - return mAuthorityStatus; | |
| 89 | - } | |
| 90 | - } | |
| 91 | - | |
| 92 | - public static Throwable getLoadSoException() { | |
| 93 | - return loadNativeException; | |
| 94 | - } | |
| 95 | - | |
| 96 | - public byte[] getRGBImageData(Bitmap img) { | |
| 97 | - int imgWidth = img.getWidth(); | |
| 98 | - int imgHeight = img.getHeight(); | |
| 99 | - int[] pixels = new int[imgWidth * imgHeight]; | |
| 100 | - img.getPixels(pixels, 0, imgWidth, 0, 0, imgWidth, imgHeight); | |
| 101 | - byte[] imageData = convertRGBImage(pixels, imgWidth, imgHeight); | |
| 102 | - return imageData; | |
| 103 | - } | |
| 104 | - | |
| 105 | - public void releaseModel() { | |
| 106 | - this.idcardQualityRelease(); | |
| 107 | - } | |
| 108 | - | |
| 109 | - static { | |
| 110 | - try { | |
| 111 | - System.loadLibrary("idl_license"); | |
| 112 | - System.loadLibrary("idcard_quality.1.1.1"); | |
| 113 | - } catch (Throwable e) { | |
| 114 | - loadNativeException = e; | |
| 115 | - } | |
| 116 | - mInstance = null; | |
| 117 | - mAuthorityStatus = 256; | |
| 118 | - } | |
| 119 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/Camera1Control.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | -import android.Manifest; | |
| 7 | -import android.content.Context; | |
| 8 | -import android.content.pm.FeatureInfo; | |
| 9 | -import android.content.pm.PackageManager; | |
| 10 | -import android.graphics.ImageFormat; | |
| 11 | -import android.graphics.Rect; | |
| 12 | -import android.graphics.SurfaceTexture; | |
| 13 | -import android.graphics.YuvImage; | |
| 14 | -import android.hardware.Camera; | |
| 15 | -import android.os.Build; | |
| 16 | -import android.util.Log; | |
| 17 | -import android.view.TextureView; | |
| 18 | -import android.view.View; | |
| 19 | -import android.widget.FrameLayout; | |
| 20 | - | |
| 21 | -import com.cnlive.core.libs.base.util.AlertUtil; | |
| 22 | - | |
| 23 | -import java.io.ByteArrayOutputStream; | |
| 24 | -import java.io.IOException; | |
| 25 | -import java.util.ArrayList; | |
| 26 | -import java.util.Collections; | |
| 27 | -import java.util.Comparator; | |
| 28 | -import java.util.List; | |
| 29 | -import java.util.concurrent.atomic.AtomicBoolean; | |
| 30 | - | |
| 31 | -import androidx.core.app.ActivityCompat; | |
| 32 | - | |
| 33 | -/** | |
| 34 | - * 5.0以下相机API的封装。 | |
| 35 | - */ | |
| 36 | -@SuppressWarnings("deprecation") | |
| 37 | -public class Camera1Control implements ICameraControl { | |
| 38 | - | |
| 39 | - private int displayOrientation = 0; | |
| 40 | - private int cameraId = 0; | |
| 41 | - private int flashMode; | |
| 42 | - private AtomicBoolean takingPicture = new AtomicBoolean(false); | |
| 43 | - private AtomicBoolean abortingScan = new AtomicBoolean(false); | |
| 44 | - private Context context; | |
| 45 | - private Camera camera; | |
| 46 | - | |
| 47 | - private Camera.Parameters parameters; | |
| 48 | - private PermissionCallback permissionCallback; | |
| 49 | - private Rect previewFrame = new Rect(); | |
| 50 | - | |
| 51 | - private PreviewView previewView; | |
| 52 | - private View displayView; | |
| 53 | - private int rotation = 0; | |
| 54 | - private OnDetectPictureCallback detectCallback; | |
| 55 | - private int previewFrameCount = 0; | |
| 56 | - private Camera.Size optSize; | |
| 57 | - | |
| 58 | - /* | |
| 59 | - * 非扫描模式 | |
| 60 | - */ | |
| 61 | - private final int MODEL_NOSCAN = 0; | |
| 62 | - | |
| 63 | - /* | |
| 64 | - * 本地质量控制扫描模式 | |
| 65 | - */ | |
| 66 | - private final int MODEL_SCAN = 1; | |
| 67 | - | |
| 68 | - private int detectType = MODEL_NOSCAN; | |
| 69 | - | |
| 70 | - public int getCameraRotation() { | |
| 71 | - return rotation; | |
| 72 | - } | |
| 73 | - | |
| 74 | - public AtomicBoolean getAbortingScan() { | |
| 75 | - return abortingScan; | |
| 76 | - } | |
| 77 | - | |
| 78 | - @Override | |
| 79 | - public void setDetectCallback(OnDetectPictureCallback callback) { | |
| 80 | - detectType = MODEL_SCAN; | |
| 81 | - detectCallback = callback; | |
| 82 | - } | |
| 83 | - | |
| 84 | - private void onRequestDetect(byte[] data) { | |
| 85 | - // 相机已经关闭 | |
| 86 | - if (camera == null || data == null) { | |
| 87 | - return; | |
| 88 | - } | |
| 89 | - | |
| 90 | - YuvImage img = new YuvImage(data, ImageFormat.NV21, optSize.width, optSize.height, null); | |
| 91 | - ByteArrayOutputStream os = null; | |
| 92 | - try { | |
| 93 | - os = new ByteArrayOutputStream(data.length); | |
| 94 | - img.compressToJpeg(new Rect(0, 0, optSize.width, optSize.height), 80, os); | |
| 95 | - byte[] jpeg = os.toByteArray(); | |
| 96 | - int status = detectCallback.onDetect(jpeg, getCameraRotation()); | |
| 97 | - | |
| 98 | - if (status == 0) { | |
| 99 | - clearPreviewCallback(); | |
| 100 | - } | |
| 101 | - } catch (OutOfMemoryError e) { | |
| 102 | - // 内存溢出则取消当次操作 | |
| 103 | - } finally { | |
| 104 | - try { | |
| 105 | - os.close(); | |
| 106 | - } catch (Throwable e) { | |
| 107 | - e.printStackTrace(); | |
| 108 | - } | |
| 109 | - } | |
| 110 | - | |
| 111 | - } | |
| 112 | - | |
| 113 | - @Override | |
| 114 | - public void setDisplayOrientation(@CameraView.Orientation int displayOrientation) { | |
| 115 | - this.displayOrientation = displayOrientation; | |
| 116 | - switch (displayOrientation) { | |
| 117 | - case CameraView.ORIENTATION_PORTRAIT: | |
| 118 | - rotation = 90; | |
| 119 | - break; | |
| 120 | - case CameraView.ORIENTATION_HORIZONTAL: | |
| 121 | - rotation = 0; | |
| 122 | - break; | |
| 123 | - case CameraView.ORIENTATION_INVERT: | |
| 124 | - rotation = 180; | |
| 125 | - break; | |
| 126 | - default: | |
| 127 | - rotation = 0; | |
| 128 | - } | |
| 129 | - previewView.requestLayout(); | |
| 130 | - } | |
| 131 | - | |
| 132 | - /** | |
| 133 | - * {@inheritDoc} | |
| 134 | - */ | |
| 135 | - @Override | |
| 136 | - public void refreshPermission() { | |
| 137 | - startPreview(true); | |
| 138 | - } | |
| 139 | - | |
| 140 | - /** | |
| 141 | - * {@inheritDoc} | |
| 142 | - */ | |
| 143 | - @Override | |
| 144 | - public void setFlashMode(@FlashMode int flashMode) { | |
| 145 | - if (this.flashMode == flashMode) { | |
| 146 | - return; | |
| 147 | - } | |
| 148 | - this.flashMode = flashMode; | |
| 149 | - updateFlashMode(flashMode); | |
| 150 | - } | |
| 151 | - | |
| 152 | - @Override | |
| 153 | - public int getFlashMode() { | |
| 154 | - return flashMode; | |
| 155 | - } | |
| 156 | - | |
| 157 | - @Override | |
| 158 | - public void start() { | |
| 159 | - | |
| 160 | - } | |
| 161 | - | |
| 162 | - @Override | |
| 163 | - public void stop() { | |
| 164 | - if (camera != null) { | |
| 165 | - camera.setPreviewCallback(null); | |
| 166 | - stopPreview(); | |
| 167 | - // 避免同步代码,为了先设置null后release | |
| 168 | - Camera tempC = camera; | |
| 169 | - camera = null; | |
| 170 | - tempC.release(); | |
| 171 | - camera = null; | |
| 172 | - buffer = null; | |
| 173 | - } | |
| 174 | - } | |
| 175 | - | |
| 176 | - private void stopPreview() { | |
| 177 | - if (camera != null) { | |
| 178 | - camera.stopPreview(); | |
| 179 | - } | |
| 180 | - } | |
| 181 | - | |
| 182 | - @Override | |
| 183 | - public void pause() { | |
| 184 | - if (camera != null) { | |
| 185 | - stopPreview(); | |
| 186 | - } | |
| 187 | - setFlashMode(FLASH_MODE_OFF); | |
| 188 | - } | |
| 189 | - | |
| 190 | - @Override | |
| 191 | - public void resume() { | |
| 192 | - takingPicture.set(false); | |
| 193 | - if (camera == null) { | |
| 194 | - openCamera(); | |
| 195 | - } else { | |
| 196 | - previewView.textureView.setSurfaceTextureListener(surfaceTextureListener); | |
| 197 | - if (previewView.textureView.isAvailable()) { | |
| 198 | - startPreview(false); | |
| 199 | - } | |
| 200 | - } | |
| 201 | - } | |
| 202 | - | |
| 203 | - @Override | |
| 204 | - public View getDisplayView() { | |
| 205 | - return displayView; | |
| 206 | - } | |
| 207 | - | |
| 208 | - @Override | |
| 209 | - public void takePicture(final OnTakePictureCallback onTakePictureCallback) { | |
| 210 | - if (takingPicture.get()) { | |
| 211 | - return; | |
| 212 | - } | |
| 213 | - try { | |
| 214 | - switch (displayOrientation) { | |
| 215 | - case CameraView.ORIENTATION_PORTRAIT: | |
| 216 | - parameters.setRotation(90); | |
| 217 | - break; | |
| 218 | - case CameraView.ORIENTATION_HORIZONTAL: | |
| 219 | - parameters.setRotation(0); | |
| 220 | - break; | |
| 221 | - case CameraView.ORIENTATION_INVERT: | |
| 222 | - parameters.setRotation(180); | |
| 223 | - break; | |
| 224 | - } | |
| 225 | - Camera.Size picSize = getOptimalSize(camera.getParameters().getSupportedPictureSizes()); | |
| 226 | - parameters.setPictureSize(picSize.width, picSize.height); | |
| 227 | - camera.setParameters(parameters); | |
| 228 | - takingPicture.set(true); | |
| 229 | - | |
| 230 | - camera.takePicture(null, null, new Camera.PictureCallback() { | |
| 231 | - @Override | |
| 232 | - public void onPictureTaken(byte[] data, Camera camera) { | |
| 233 | - startPreview(false); | |
| 234 | - takingPicture.set(false); | |
| 235 | - if (onTakePictureCallback != null) { | |
| 236 | - onTakePictureCallback.onPictureTaken(data); | |
| 237 | - } | |
| 238 | - } | |
| 239 | - }); | |
| 240 | - } catch (RuntimeException e) { | |
| 241 | - e.printStackTrace(); | |
| 242 | - startPreview(false); | |
| 243 | - ; | |
| 244 | - takingPicture.set(false); | |
| 245 | - } | |
| 246 | - } | |
| 247 | - | |
| 248 | - @Override | |
| 249 | - public void setPermissionCallback(PermissionCallback callback) { | |
| 250 | - this.permissionCallback = callback; | |
| 251 | - } | |
| 252 | - | |
| 253 | - public Camera1Control(Context context) { | |
| 254 | - this.context = context; | |
| 255 | - previewView = new PreviewView(context); | |
| 256 | - openCamera(); | |
| 257 | - } | |
| 258 | - | |
| 259 | - private void openCamera() { | |
| 260 | - setupDisplayView(); | |
| 261 | - } | |
| 262 | - | |
| 263 | - private void setupDisplayView() { | |
| 264 | - final TextureView textureView = new TextureView(context); | |
| 265 | - previewView.textureView = textureView; | |
| 266 | - previewView.setTextureView(textureView); | |
| 267 | - displayView = previewView; | |
| 268 | - textureView.setSurfaceTextureListener(surfaceTextureListener); | |
| 269 | - } | |
| 270 | - | |
| 271 | - private SurfaceTexture surfaceCache; | |
| 272 | - | |
| 273 | - private byte[] buffer = null; | |
| 274 | - | |
| 275 | - private void setPreviewCallbackImpl() { | |
| 276 | - if (buffer == null) { | |
| 277 | - buffer = new byte[displayView.getWidth() | |
| 278 | - * displayView.getHeight() * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8]; | |
| 279 | - } | |
| 280 | - if (camera != null && detectType == MODEL_SCAN) { | |
| 281 | - camera.addCallbackBuffer(buffer); | |
| 282 | - camera.setPreviewCallback(previewCallback); | |
| 283 | - } | |
| 284 | - } | |
| 285 | - | |
| 286 | - private void clearPreviewCallback() { | |
| 287 | - if (camera != null && detectType == MODEL_SCAN) { | |
| 288 | - camera.setPreviewCallback(null); | |
| 289 | - stopPreview(); | |
| 290 | - } | |
| 291 | - } | |
| 292 | - | |
| 293 | - Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() { | |
| 294 | - @Override | |
| 295 | - public void onPreviewFrame(final byte[] data, Camera camera) { | |
| 296 | - // 扫描成功阻止打开新线程处理 | |
| 297 | - if (abortingScan.get()) { | |
| 298 | - return; | |
| 299 | - } | |
| 300 | - // 节流 | |
| 301 | - if (previewFrameCount++ % 5 != 0) { | |
| 302 | - return; | |
| 303 | - } | |
| 304 | - | |
| 305 | - // 在某些机型和某项项目中,某些帧的data的数据不符合nv21的格式,需要过滤,否则后续处理会导致crash | |
| 306 | - if (data.length != parameters.getPreviewSize().width * parameters.getPreviewSize().height * 1.5) { | |
| 307 | - return; | |
| 308 | - } | |
| 309 | - | |
| 310 | - camera.addCallbackBuffer(buffer); | |
| 311 | - | |
| 312 | - CameraThreadPool.execute(new Runnable() { | |
| 313 | - @Override | |
| 314 | - public void run() { | |
| 315 | - Camera1Control.this.onRequestDetect(data); | |
| 316 | - } | |
| 317 | - }); | |
| 318 | - } | |
| 319 | - }; | |
| 320 | - | |
| 321 | - | |
| 322 | - private void initCamera() { | |
| 323 | - try { | |
| 324 | - if (camera == null) { | |
| 325 | - Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); | |
| 326 | - for (int i = 0; i < Camera.getNumberOfCameras(); i++) { | |
| 327 | - Camera.getCameraInfo(i, cameraInfo); | |
| 328 | - if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { | |
| 329 | - cameraId = i; | |
| 330 | - } | |
| 331 | - } | |
| 332 | - try { | |
| 333 | - camera = Camera.open(cameraId); | |
| 334 | - } catch (Throwable e) { | |
| 335 | - e.printStackTrace(); | |
| 336 | - startPreview(true); | |
| 337 | - return; | |
| 338 | - } | |
| 339 | - | |
| 340 | - } | |
| 341 | - if (parameters == null) { | |
| 342 | - parameters = camera.getParameters(); | |
| 343 | - parameters.setPreviewFormat(ImageFormat.NV21); | |
| 344 | - } | |
| 345 | - opPreviewSize(previewView.getWidth(), previewView.getHeight()); | |
| 346 | - camera.setPreviewTexture(surfaceCache); | |
| 347 | - setPreviewCallbackImpl(); | |
| 348 | - startPreview(false); | |
| 349 | - } catch (IOException e) { | |
| 350 | - e.printStackTrace(); | |
| 351 | - } | |
| 352 | - } | |
| 353 | - | |
| 354 | - private TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() { | |
| 355 | - @Override | |
| 356 | - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { | |
| 357 | - surfaceCache = surface; | |
| 358 | - initCamera(); | |
| 359 | - } | |
| 360 | - | |
| 361 | - @Override | |
| 362 | - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { | |
| 363 | - opPreviewSize(previewView.getWidth(), previewView.getHeight()); | |
| 364 | - setPreviewCallbackImpl(); | |
| 365 | - } | |
| 366 | - | |
| 367 | - @Override | |
| 368 | - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { | |
| 369 | - return false; | |
| 370 | - } | |
| 371 | - | |
| 372 | - @Override | |
| 373 | - public void onSurfaceTextureUpdated(SurfaceTexture surface) { | |
| 374 | - setPreviewCallbackImpl(); | |
| 375 | - } | |
| 376 | - }; | |
| 377 | - | |
| 378 | - // 开启预览 | |
| 379 | - private void startPreview(boolean checkPermission) { | |
| 380 | - if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) | |
| 381 | - != PackageManager.PERMISSION_GRANTED) { | |
| 382 | - if (checkPermission && permissionCallback != null) { | |
| 383 | - permissionCallback.onRequestPermission(); | |
| 384 | - } | |
| 385 | - return; | |
| 386 | - } | |
| 387 | - if (camera == null) { | |
| 388 | - initCamera(); | |
| 389 | - } else { | |
| 390 | - try { | |
| 391 | - camera.startPreview(); | |
| 392 | - CameraThreadPool.createAutoFocusTimerTask(new Runnable() { | |
| 393 | - @Override | |
| 394 | - public void run() { | |
| 395 | - synchronized (Camera1Control.this) { | |
| 396 | - if (camera != null && !takingPicture.get()) { | |
| 397 | - try { | |
| 398 | - camera.autoFocus(new Camera.AutoFocusCallback() { | |
| 399 | - @Override | |
| 400 | - public void onAutoFocus(boolean success, Camera camera) { | |
| 401 | - } | |
| 402 | - }); | |
| 403 | - } catch (Throwable e) { | |
| 404 | - // startPreview是异步实现,可能在某些机器上前几次调用会autofocus failß | |
| 405 | - } | |
| 406 | - } | |
| 407 | - } | |
| 408 | - } | |
| 409 | - }); | |
| 410 | - } catch (Exception e) { | |
| 411 | - Log.e("ocr_ui startPreview", "startPreview: " + (e == null ? "" : e.getMessage())); | |
| 412 | - } | |
| 413 | - } | |
| 414 | - } | |
| 415 | - | |
| 416 | - private void opPreviewSize(int width, @SuppressWarnings("unused") int height) { | |
| 417 | - | |
| 418 | - if (parameters != null && camera != null && width > 0) { | |
| 419 | - try { | |
| 420 | - optSize = getOptimalSize(camera.getParameters().getSupportedPreviewSizes()); | |
| 421 | - }catch (Exception e){ | |
| 422 | - e.printStackTrace(); | |
| 423 | - } | |
| 424 | - optSize = getOptimalSize(camera.getParameters().getSupportedPreviewSizes()); | |
| 425 | - parameters.setPreviewSize(optSize.width, optSize.height); | |
| 426 | - previewView.setRatio(1.0f * optSize.width / optSize.height); | |
| 427 | - | |
| 428 | - camera.setDisplayOrientation(getSurfaceOrientation()); | |
| 429 | - stopPreview(); | |
| 430 | - try { | |
| 431 | - camera.setParameters(parameters); | |
| 432 | - } catch (RuntimeException e) { | |
| 433 | - e.printStackTrace(); | |
| 434 | - | |
| 435 | - } | |
| 436 | - startPreview(false); | |
| 437 | - } | |
| 438 | - } | |
| 439 | - | |
| 440 | - private Camera.Size getOptimalSize(List<Camera.Size> sizes) { | |
| 441 | - int width = previewView.textureView.getWidth(); | |
| 442 | - int height = previewView.textureView.getHeight(); | |
| 443 | - Camera.Size pictureSize = sizes.get(0); | |
| 444 | - | |
| 445 | - List<Camera.Size> candidates = new ArrayList<>(); | |
| 446 | - | |
| 447 | - for (Camera.Size size : sizes) { | |
| 448 | - if (size.width >= width && size.height >= height && size.width * height == size.height * width) { | |
| 449 | - // 比例相同 | |
| 450 | - candidates.add(size); | |
| 451 | - } else if (size.height >= width && size.width >= height && size.width * width == size.height * height) { | |
| 452 | - // 反比例 | |
| 453 | - candidates.add(size); | |
| 454 | - } | |
| 455 | - } | |
| 456 | - if (!candidates.isEmpty()) { | |
| 457 | - return Collections.min(candidates, sizeComparator); | |
| 458 | - } | |
| 459 | - | |
| 460 | - for (Camera.Size size : sizes) { | |
| 461 | - if (size.width > width && size.height > height) { | |
| 462 | - return size; | |
| 463 | - } | |
| 464 | - } | |
| 465 | - | |
| 466 | - return pictureSize; | |
| 467 | - } | |
| 468 | - | |
| 469 | - private Comparator<Camera.Size> sizeComparator = new Comparator<Camera.Size>() { | |
| 470 | - @Override | |
| 471 | - public int compare(Camera.Size lhs, Camera.Size rhs) { | |
| 472 | - return Long.signum((long) lhs.width * lhs.height - (long) rhs.width * rhs.height); | |
| 473 | - } | |
| 474 | - }; | |
| 475 | - | |
| 476 | - private void updateFlashMode(int flashMode) { | |
| 477 | - switch (flashMode) { | |
| 478 | - case FLASH_MODE_TORCH: | |
| 479 | - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
| 480 | - try { | |
| 481 | - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); | |
| 482 | - } catch (Exception e) { | |
| 483 | - e.printStackTrace(); | |
| 484 | - } | |
| 485 | - }else { | |
| 486 | - boolean isUse = false; | |
| 487 | - PackageManager packageManager = context.getPackageManager(); | |
| 488 | - FeatureInfo[] features = packageManager.getSystemAvailableFeatures(); | |
| 489 | - for (FeatureInfo featureInfo : features) { | |
| 490 | - if (PackageManager.FEATURE_CAMERA_FLASH.equals(featureInfo.name)) { // 断设备是否支持闪光灯 | |
| 491 | - try { | |
| 492 | - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); | |
| 493 | - isUse = true; | |
| 494 | - } catch (Exception e) { | |
| 495 | - e.printStackTrace(); | |
| 496 | - } | |
| 497 | - } | |
| 498 | - } | |
| 499 | - if(!isUse) AlertUtil.showDeftToast(context,"该设备不支持闪光灯"); | |
| 500 | - } | |
| 501 | - break; | |
| 502 | - case FLASH_MODE_OFF: | |
| 503 | - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); | |
| 504 | - break; | |
| 505 | - case ICameraControl.FLASH_MODE_AUTO: | |
| 506 | - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); | |
| 507 | - break; | |
| 508 | - default: | |
| 509 | - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); | |
| 510 | - break; | |
| 511 | - } | |
| 512 | - if (parameters == null || camera == null) | |
| 513 | - return; | |
| 514 | - camera.setParameters(parameters); | |
| 515 | - } | |
| 516 | - | |
| 517 | - private int getSurfaceOrientation() { | |
| 518 | - @CameraView.Orientation | |
| 519 | - int orientation = displayOrientation; | |
| 520 | - switch (orientation) { | |
| 521 | - case CameraView.ORIENTATION_PORTRAIT: | |
| 522 | - return 90; | |
| 523 | - case CameraView.ORIENTATION_HORIZONTAL: | |
| 524 | - return 0; | |
| 525 | - case CameraView.ORIENTATION_INVERT: | |
| 526 | - return 180; | |
| 527 | - default: | |
| 528 | - return 90; | |
| 529 | - } | |
| 530 | - } | |
| 531 | - | |
| 532 | - /** | |
| 533 | - * 有些相机匹配不到完美的比例。比如。我们的layout是4:3的。预览只有16:9 | |
| 534 | - * 的,如果直接显示图片会拉伸,变形。缩放的话,又有黑边。所以我们采取的策略 | |
| 535 | - * 是,等比例放大。这样预览的有一部分会超出屏幕。拍照后再进行裁剪处理。 | |
| 536 | - */ | |
| 537 | - private class PreviewView extends FrameLayout { | |
| 538 | - | |
| 539 | - private TextureView textureView; | |
| 540 | - | |
| 541 | - private float ratio = 0.75f; | |
| 542 | - | |
| 543 | - void setTextureView(TextureView textureView) { | |
| 544 | - this.textureView = textureView; | |
| 545 | - removeAllViews(); | |
| 546 | - addView(textureView); | |
| 547 | - } | |
| 548 | - | |
| 549 | - void setRatio(float ratio) { | |
| 550 | - this.ratio = ratio; | |
| 551 | - requestLayout(); | |
| 552 | - relayout(getWidth(), getHeight()); | |
| 553 | - } | |
| 554 | - | |
| 555 | - public PreviewView(Context context) { | |
| 556 | - super(context); | |
| 557 | - } | |
| 558 | - | |
| 559 | - @Override | |
| 560 | - protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
| 561 | - super.onSizeChanged(w, h, oldw, oldh); | |
| 562 | - relayout(w, h); | |
| 563 | - } | |
| 564 | - | |
| 565 | - private void relayout(int w, int h) { | |
| 566 | - int width = w; | |
| 567 | - int height = h; | |
| 568 | - if (w < h) { | |
| 569 | - // 垂直模式,高度固定。 | |
| 570 | - height = (int) (width * ratio); | |
| 571 | - } else { | |
| 572 | - // 水平模式,宽度固定。 | |
| 573 | - width = (int) (height * ratio); | |
| 574 | - } | |
| 575 | - | |
| 576 | - int l = (getWidth() - width) / 2; | |
| 577 | - int t = (getHeight() - height) / 2; | |
| 578 | - | |
| 579 | - previewFrame.left = l; | |
| 580 | - previewFrame.top = t; | |
| 581 | - previewFrame.right = l + width; | |
| 582 | - previewFrame.bottom = t + height; | |
| 583 | - } | |
| 584 | - | |
| 585 | - @Override | |
| 586 | - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | |
| 587 | - super.onLayout(changed, left, top, right, bottom); | |
| 588 | - textureView.layout(previewFrame.left, previewFrame.top, previewFrame.right, previewFrame.bottom); | |
| 589 | - } | |
| 590 | - } | |
| 591 | - | |
| 592 | - @Override | |
| 593 | - public Rect getPreviewFrame() { | |
| 594 | - return previewFrame; | |
| 595 | - } | |
| 596 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/Camera2Control.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | - | |
| 5 | -package com.cnlive.core.ocr.ui.camera; | |
| 6 | - | |
| 7 | -import android.Manifest; | |
| 8 | -import android.annotation.SuppressLint; | |
| 9 | -import android.annotation.TargetApi; | |
| 10 | -import android.content.Context; | |
| 11 | -import android.content.pm.PackageManager; | |
| 12 | -import android.graphics.ImageFormat; | |
| 13 | -import android.graphics.Matrix; | |
| 14 | -import android.graphics.Point; | |
| 15 | -import android.graphics.Rect; | |
| 16 | -import android.graphics.RectF; | |
| 17 | -import android.graphics.SurfaceTexture; | |
| 18 | -import android.hardware.camera2.CameraAccessException; | |
| 19 | -import android.hardware.camera2.CameraCaptureSession; | |
| 20 | -import android.hardware.camera2.CameraCharacteristics; | |
| 21 | -import android.hardware.camera2.CameraDevice; | |
| 22 | -import android.hardware.camera2.CameraManager; | |
| 23 | -import android.hardware.camera2.CameraMetadata; | |
| 24 | -import android.hardware.camera2.CaptureFailure; | |
| 25 | -import android.hardware.camera2.CaptureRequest; | |
| 26 | -import android.hardware.camera2.CaptureResult; | |
| 27 | -import android.hardware.camera2.TotalCaptureResult; | |
| 28 | -import android.hardware.camera2.params.StreamConfigurationMap; | |
| 29 | -import android.media.Image; | |
| 30 | -import android.media.ImageReader; | |
| 31 | -import android.os.Build; | |
| 32 | -import android.os.Handler; | |
| 33 | -import android.os.HandlerThread; | |
| 34 | -import android.util.Size; | |
| 35 | -import android.util.SparseIntArray; | |
| 36 | -import android.view.Surface; | |
| 37 | -import android.view.TextureView; | |
| 38 | -import android.view.View; | |
| 39 | -import android.view.WindowManager; | |
| 40 | - | |
| 41 | -import java.nio.ByteBuffer; | |
| 42 | -import java.util.ArrayList; | |
| 43 | -import java.util.Arrays; | |
| 44 | -import java.util.Collections; | |
| 45 | -import java.util.Comparator; | |
| 46 | -import java.util.List; | |
| 47 | -import java.util.concurrent.Semaphore; | |
| 48 | -import java.util.concurrent.TimeUnit; | |
| 49 | -import java.util.concurrent.atomic.AtomicBoolean; | |
| 50 | - | |
| 51 | -import androidx.annotation.NonNull; | |
| 52 | -import androidx.core.content.ContextCompat; | |
| 53 | - | |
| 54 | -@TargetApi(Build.VERSION_CODES.LOLLIPOP) | |
| 55 | -public class Camera2Control implements ICameraControl { | |
| 56 | - @Override | |
| 57 | - public void setDetectCallback(OnDetectPictureCallback callback) { | |
| 58 | - // TODO 暂时只用camera | |
| 59 | - } | |
| 60 | - | |
| 61 | - @Override | |
| 62 | - public AtomicBoolean getAbortingScan() { | |
| 63 | - // TODO 暂时只用camera | |
| 64 | - return null; | |
| 65 | - } | |
| 66 | - | |
| 67 | - /** | |
| 68 | - * Conversion from screen rotation to JPEG orientation. | |
| 69 | - */ | |
| 70 | - private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); | |
| 71 | - private static final int MAX_PREVIEW_SIZE = 2048; | |
| 72 | - | |
| 73 | - static { | |
| 74 | - ORIENTATIONS.append(Surface.ROTATION_0, 90); | |
| 75 | - ORIENTATIONS.append(Surface.ROTATION_90, 0); | |
| 76 | - ORIENTATIONS.append(Surface.ROTATION_180, 270); | |
| 77 | - ORIENTATIONS.append(Surface.ROTATION_270, 180); | |
| 78 | - } | |
| 79 | - | |
| 80 | - private static final int STATE_PREVIEW = 0; | |
| 81 | - private static final int STATE_WAITING_FOR_LOCK = 1; | |
| 82 | - private static final int STATE_WAITING_FOR_CAPTURE = 2; | |
| 83 | - private static final int STATE_CAPTURING = 3; | |
| 84 | - private static final int STATE_PICTURE_TAKEN = 4; | |
| 85 | - | |
| 86 | - private static final int MAX_PREVIEW_WIDTH = 1920; | |
| 87 | - private static final int MAX_PREVIEW_HEIGHT = 1080; | |
| 88 | - | |
| 89 | - private int flashMode; | |
| 90 | - private int orientation = 0; | |
| 91 | - private int state = STATE_PREVIEW; | |
| 92 | - | |
| 93 | - private Context context; | |
| 94 | - private OnTakePictureCallback onTakePictureCallback; | |
| 95 | - private PermissionCallback permissionCallback; | |
| 96 | - | |
| 97 | - private String cameraId; | |
| 98 | - private TextureView textureView; | |
| 99 | - private Size previewSize; | |
| 100 | - private Rect previewFrame = new Rect(); | |
| 101 | - | |
| 102 | - private HandlerThread backgroundThread; | |
| 103 | - private Handler backgroundHandler; | |
| 104 | - private ImageReader imageReader; | |
| 105 | - private CameraCaptureSession captureSession; | |
| 106 | - private CameraDevice cameraDevice; | |
| 107 | - | |
| 108 | - private CaptureRequest.Builder previewRequestBuilder; | |
| 109 | - private CaptureRequest previewRequest; | |
| 110 | - | |
| 111 | - private Semaphore cameraLock = new Semaphore(1); | |
| 112 | - private int sensorOrientation; | |
| 113 | - | |
| 114 | - @Override | |
| 115 | - public void start() { | |
| 116 | - startBackgroundThread(); | |
| 117 | - if (textureView.isAvailable()) { | |
| 118 | - openCamera(textureView.getWidth(), textureView.getHeight()); | |
| 119 | - textureView.setSurfaceTextureListener(surfaceTextureListener); | |
| 120 | - } else { | |
| 121 | - textureView.setSurfaceTextureListener(surfaceTextureListener); | |
| 122 | - } | |
| 123 | - } | |
| 124 | - | |
| 125 | - @Override | |
| 126 | - public void stop() { | |
| 127 | - textureView.setSurfaceTextureListener(null); | |
| 128 | - closeCamera(); | |
| 129 | - stopBackgroundThread(); | |
| 130 | - } | |
| 131 | - | |
| 132 | - @Override | |
| 133 | - public void pause() { | |
| 134 | - setFlashMode(FLASH_MODE_OFF); | |
| 135 | - } | |
| 136 | - | |
| 137 | - @Override | |
| 138 | - public void resume() { | |
| 139 | - state = STATE_PREVIEW; | |
| 140 | - } | |
| 141 | - | |
| 142 | - @Override | |
| 143 | - public View getDisplayView() { | |
| 144 | - return textureView; | |
| 145 | - } | |
| 146 | - | |
| 147 | - @Override | |
| 148 | - public Rect getPreviewFrame() { | |
| 149 | - return previewFrame; | |
| 150 | - } | |
| 151 | - | |
| 152 | - @Override | |
| 153 | - public void takePicture(OnTakePictureCallback callback) { | |
| 154 | - this.onTakePictureCallback = callback; | |
| 155 | - // 拍照第一步,对焦 | |
| 156 | - lockFocus(); | |
| 157 | - } | |
| 158 | - | |
| 159 | - @Override | |
| 160 | - public void setPermissionCallback(PermissionCallback callback) { | |
| 161 | - this.permissionCallback = callback; | |
| 162 | - } | |
| 163 | - | |
| 164 | - @Override | |
| 165 | - public void setDisplayOrientation(@CameraView.Orientation int displayOrientation) { | |
| 166 | - this.orientation = displayOrientation / 90; | |
| 167 | - } | |
| 168 | - | |
| 169 | - @Override | |
| 170 | - public void refreshPermission() { | |
| 171 | - openCamera(textureView.getWidth(), textureView.getHeight()); | |
| 172 | - } | |
| 173 | - | |
| 174 | - @Override | |
| 175 | - public void setFlashMode(@FlashMode int flashMode) { | |
| 176 | - if (this.flashMode == flashMode) { | |
| 177 | - return; | |
| 178 | - } | |
| 179 | - this.flashMode = flashMode; | |
| 180 | - try { | |
| 181 | - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, | |
| 182 | - CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); | |
| 183 | - updateFlashMode(flashMode, previewRequestBuilder); | |
| 184 | - previewRequest = previewRequestBuilder.build(); | |
| 185 | - captureSession.setRepeatingRequest(previewRequest, captureCallback, backgroundHandler); | |
| 186 | - } catch (Exception e) { | |
| 187 | - if (e!=null) | |
| 188 | - e.printStackTrace(); | |
| 189 | - } | |
| 190 | - } | |
| 191 | - | |
| 192 | - @Override | |
| 193 | - public int getFlashMode() { | |
| 194 | - return flashMode; | |
| 195 | - } | |
| 196 | - | |
| 197 | - public Camera2Control(Context activity) { | |
| 198 | - this.context = activity; | |
| 199 | - textureView = new TextureView(activity); | |
| 200 | - } | |
| 201 | - | |
| 202 | - private final TextureView.SurfaceTextureListener surfaceTextureListener = | |
| 203 | - new TextureView.SurfaceTextureListener() { | |
| 204 | - @Override | |
| 205 | - public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) { | |
| 206 | - openCamera(width, height); | |
| 207 | - } | |
| 208 | - | |
| 209 | - @Override | |
| 210 | - public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) { | |
| 211 | - configureTransform(width, height); | |
| 212 | - previewFrame.left = 0; | |
| 213 | - previewFrame.top = 0; | |
| 214 | - previewFrame.right = width; | |
| 215 | - previewFrame.bottom = height; | |
| 216 | - } | |
| 217 | - | |
| 218 | - @Override | |
| 219 | - public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) { | |
| 220 | - stop(); | |
| 221 | - return true; | |
| 222 | - } | |
| 223 | - | |
| 224 | - @Override | |
| 225 | - public void onSurfaceTextureUpdated(SurfaceTexture texture) { | |
| 226 | - } | |
| 227 | - }; | |
| 228 | - | |
| 229 | - @SuppressLint("MissingPermission") | |
| 230 | - private void openCamera(int width, int height) { | |
| 231 | - // 6.0+的系统需要检查系统权限 。 | |
| 232 | - if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) | |
| 233 | - != PackageManager.PERMISSION_GRANTED) { | |
| 234 | - requestCameraPermission(); | |
| 235 | - return; | |
| 236 | - } | |
| 237 | - setUpCameraOutputs(width, height); | |
| 238 | - configureTransform(width, height); | |
| 239 | - CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); | |
| 240 | - try { | |
| 241 | - if (!cameraLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { | |
| 242 | - throw new RuntimeException("Time out waiting to lock camera opening."); | |
| 243 | - } | |
| 244 | - manager.openCamera(cameraId, deviceStateCallback, backgroundHandler); | |
| 245 | - } catch (CameraAccessException e) { | |
| 246 | - if (e!=null) | |
| 247 | - e.printStackTrace(); | |
| 248 | - } catch (InterruptedException e) { | |
| 249 | - if (e!=null) | |
| 250 | - throw new RuntimeException("Interrupted while trying to lock camera opening.", e); | |
| 251 | - } | |
| 252 | - } | |
| 253 | - | |
| 254 | - private final CameraDevice.StateCallback deviceStateCallback = new CameraDevice.StateCallback() { | |
| 255 | - @Override | |
| 256 | - public void onOpened(@NonNull CameraDevice cameraDevice) { | |
| 257 | - cameraLock.release(); | |
| 258 | - Camera2Control.this.cameraDevice = cameraDevice; | |
| 259 | - createCameraPreviewSession(); | |
| 260 | - } | |
| 261 | - | |
| 262 | - @Override | |
| 263 | - public void onDisconnected(@NonNull CameraDevice cameraDevice) { | |
| 264 | - cameraLock.release(); | |
| 265 | - cameraDevice.close(); | |
| 266 | - Camera2Control.this.cameraDevice = null; | |
| 267 | - } | |
| 268 | - | |
| 269 | - @Override | |
| 270 | - public void onError(@NonNull CameraDevice cameraDevice, int error) { | |
| 271 | - cameraLock.release(); | |
| 272 | - cameraDevice.close(); | |
| 273 | - Camera2Control.this.cameraDevice = null; | |
| 274 | - } | |
| 275 | - }; | |
| 276 | - | |
| 277 | - private void createCameraPreviewSession() { | |
| 278 | - try { | |
| 279 | - SurfaceTexture texture = textureView.getSurfaceTexture(); | |
| 280 | - assert texture != null; | |
| 281 | - texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); | |
| 282 | - Surface surface = new Surface(texture); | |
| 283 | - previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); | |
| 284 | - previewRequestBuilder.addTarget(surface); | |
| 285 | - updateFlashMode(this.flashMode, previewRequestBuilder); | |
| 286 | - cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), | |
| 287 | - new CameraCaptureSession.StateCallback() { | |
| 288 | - | |
| 289 | - @Override | |
| 290 | - public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { | |
| 291 | - // The camera is already closed | |
| 292 | - if (null == cameraDevice) { | |
| 293 | - return; | |
| 294 | - } | |
| 295 | - captureSession = cameraCaptureSession; | |
| 296 | - try { | |
| 297 | - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, | |
| 298 | - CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); | |
| 299 | - previewRequest = previewRequestBuilder.build(); | |
| 300 | - captureSession.setRepeatingRequest(previewRequest, | |
| 301 | - captureCallback, backgroundHandler); | |
| 302 | - } catch (CameraAccessException e) { | |
| 303 | - if (e!=null) | |
| 304 | - e.printStackTrace(); | |
| 305 | - } | |
| 306 | - } | |
| 307 | - | |
| 308 | - @Override | |
| 309 | - public void onConfigureFailed( | |
| 310 | - @NonNull CameraCaptureSession cameraCaptureSession) { | |
| 311 | - // TODO | |
| 312 | - } | |
| 313 | - }, null | |
| 314 | - ); | |
| 315 | - } catch (CameraAccessException e) { | |
| 316 | - if (e!=null) | |
| 317 | - e.printStackTrace(); | |
| 318 | - } | |
| 319 | - } | |
| 320 | - | |
| 321 | - private final ImageReader.OnImageAvailableListener onImageAvailableListener = | |
| 322 | - new ImageReader.OnImageAvailableListener() { | |
| 323 | - @Override | |
| 324 | - public void onImageAvailable(ImageReader reader) { | |
| 325 | - if (onTakePictureCallback != null) { | |
| 326 | - Image image = reader.acquireNextImage(); | |
| 327 | - ByteBuffer buffer = image.getPlanes()[0].getBuffer(); | |
| 328 | - byte[] bytes = new byte[buffer.remaining()]; | |
| 329 | - buffer.get(bytes); | |
| 330 | - | |
| 331 | - image.close(); | |
| 332 | - onTakePictureCallback.onPictureTaken(bytes); | |
| 333 | - } | |
| 334 | - } | |
| 335 | - }; | |
| 336 | - | |
| 337 | - private CameraCaptureSession.CaptureCallback captureCallback = | |
| 338 | - new CameraCaptureSession.CaptureCallback() { | |
| 339 | - private void process(CaptureResult result) { | |
| 340 | - switch (state) { | |
| 341 | - case STATE_PREVIEW: { | |
| 342 | - break; | |
| 343 | - } | |
| 344 | - case STATE_WAITING_FOR_LOCK: { | |
| 345 | - Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); | |
| 346 | - if (afState == null) { | |
| 347 | - captureStillPicture(); | |
| 348 | - return; | |
| 349 | - } | |
| 350 | - switch (afState) { | |
| 351 | - case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED: | |
| 352 | - case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: | |
| 353 | - case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED: { | |
| 354 | - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); | |
| 355 | - if (aeState == null | |
| 356 | - || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { | |
| 357 | - captureStillPicture(); | |
| 358 | - } else { | |
| 359 | - runPreCaptureSequence(); | |
| 360 | - } | |
| 361 | - break; | |
| 362 | - } | |
| 363 | - default: | |
| 364 | - captureStillPicture(); | |
| 365 | - } | |
| 366 | - break; | |
| 367 | - } | |
| 368 | - case STATE_WAITING_FOR_CAPTURE: { | |
| 369 | - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); | |
| 370 | - if (aeState == null | |
| 371 | - || aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE | |
| 372 | - || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) { | |
| 373 | - state = STATE_CAPTURING; | |
| 374 | - } else { | |
| 375 | - if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { | |
| 376 | - captureStillPicture(); | |
| 377 | - } | |
| 378 | - } | |
| 379 | - break; | |
| 380 | - } | |
| 381 | - case STATE_CAPTURING: { | |
| 382 | - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); | |
| 383 | - if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) { | |
| 384 | - captureStillPicture(); | |
| 385 | - } | |
| 386 | - break; | |
| 387 | - } | |
| 388 | - default: | |
| 389 | - break; | |
| 390 | - } | |
| 391 | - } | |
| 392 | - | |
| 393 | - @Override | |
| 394 | - public void onCaptureProgressed(@NonNull CameraCaptureSession session, | |
| 395 | - @NonNull CaptureRequest request, | |
| 396 | - @NonNull CaptureResult partialResult) { | |
| 397 | - process(partialResult); | |
| 398 | - } | |
| 399 | - | |
| 400 | - @Override | |
| 401 | - public void onCaptureCompleted(@NonNull CameraCaptureSession session, | |
| 402 | - @NonNull CaptureRequest request, | |
| 403 | - @NonNull TotalCaptureResult result) { | |
| 404 | - process(result); | |
| 405 | - } | |
| 406 | - | |
| 407 | - }; | |
| 408 | - | |
| 409 | - private Size getOptimalSize(Size[] choices, int textureViewWidth, | |
| 410 | - int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) { | |
| 411 | - List<Size> bigEnough = new ArrayList<>(); | |
| 412 | - List<Size> notBigEnough = new ArrayList<>(); | |
| 413 | - int w = aspectRatio.getWidth(); | |
| 414 | - int h = aspectRatio.getHeight(); | |
| 415 | - for (Size option : choices) { | |
| 416 | - if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight | |
| 417 | - && option.getHeight() == option.getWidth() * h / w) { | |
| 418 | - if (option.getWidth() >= textureViewWidth | |
| 419 | - && option.getHeight() >= textureViewHeight) { | |
| 420 | - bigEnough.add(option); | |
| 421 | - } else { | |
| 422 | - notBigEnough.add(option); | |
| 423 | - } | |
| 424 | - } | |
| 425 | - } | |
| 426 | - | |
| 427 | - // Pick the smallest of those big enough. If there is no one big enough, pick the | |
| 428 | - // largest of those not big enough. | |
| 429 | - if (bigEnough.size() > 0) { | |
| 430 | - return Collections.min(bigEnough, sizeComparator); | |
| 431 | - } | |
| 432 | - | |
| 433 | - for (Size option : choices) { | |
| 434 | - if (option.getWidth() >= maxWidth && option.getHeight() >= maxHeight) { | |
| 435 | - return option; | |
| 436 | - } | |
| 437 | - } | |
| 438 | - | |
| 439 | - if (notBigEnough.size() > 0) { | |
| 440 | - return Collections.max(notBigEnough, sizeComparator); | |
| 441 | - } | |
| 442 | - | |
| 443 | - return choices[0]; | |
| 444 | - } | |
| 445 | - | |
| 446 | - private Comparator<Size> sizeComparator = new Comparator<Size>() { | |
| 447 | - @Override | |
| 448 | - public int compare(Size lhs, Size rhs) { | |
| 449 | - return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight()); | |
| 450 | - } | |
| 451 | - }; | |
| 452 | - | |
| 453 | - private void requestCameraPermission() { | |
| 454 | - if (permissionCallback != null) { | |
| 455 | - permissionCallback.onRequestPermission(); | |
| 456 | - } | |
| 457 | - } | |
| 458 | - | |
| 459 | - @SuppressWarnings("SuspiciousNameCombination") | |
| 460 | - private void setUpCameraOutputs(int width, int height) { | |
| 461 | - CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); | |
| 462 | - try { | |
| 463 | - for (String cameraId : manager.getCameraIdList()) { | |
| 464 | - CameraCharacteristics characteristics = | |
| 465 | - manager.getCameraCharacteristics(cameraId); | |
| 466 | - | |
| 467 | - Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); | |
| 468 | - if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) { | |
| 469 | - continue; | |
| 470 | - } | |
| 471 | - | |
| 472 | - StreamConfigurationMap map = characteristics.get( | |
| 473 | - CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); | |
| 474 | - if (map == null) { | |
| 475 | - continue; | |
| 476 | - } | |
| 477 | - | |
| 478 | - // int preferredPictureSize = (int) (Math.max(textureView.getWidth(), textureView | |
| 479 | - // .getHeight()) * 1.5); | |
| 480 | - // preferredPictureSize = Math.min(preferredPictureSize, 2560); | |
| 481 | - | |
| 482 | - WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); | |
| 483 | - Point screenSize = new Point(); | |
| 484 | - windowManager.getDefaultDisplay().getSize(screenSize); | |
| 485 | - int maxImageSize = Math.max(MAX_PREVIEW_SIZE, screenSize.y * 3 / 2); | |
| 486 | - | |
| 487 | - Size size = getOptimalSize(map.getOutputSizes(ImageFormat.JPEG), textureView.getWidth(), | |
| 488 | - textureView.getHeight(), maxImageSize, maxImageSize, new Size(4, 3)); | |
| 489 | - | |
| 490 | - imageReader = ImageReader.newInstance(size.getWidth(), size.getHeight(), | |
| 491 | - ImageFormat.JPEG, 1); | |
| 492 | - imageReader.setOnImageAvailableListener( | |
| 493 | - onImageAvailableListener, backgroundHandler); | |
| 494 | - | |
| 495 | - int displayRotation = orientation; | |
| 496 | - // noinspection ConstantConditions | |
| 497 | - sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); | |
| 498 | - boolean swappedDimensions = false; | |
| 499 | - switch (displayRotation) { | |
| 500 | - case Surface.ROTATION_0: | |
| 501 | - case Surface.ROTATION_180: | |
| 502 | - if (sensorOrientation == 90 || sensorOrientation == 270) { | |
| 503 | - swappedDimensions = true; | |
| 504 | - } | |
| 505 | - break; | |
| 506 | - case Surface.ROTATION_90: | |
| 507 | - case Surface.ROTATION_270: | |
| 508 | - if (sensorOrientation == 0 || sensorOrientation == 180) { | |
| 509 | - swappedDimensions = true; | |
| 510 | - } | |
| 511 | - break; | |
| 512 | - default: | |
| 513 | - } | |
| 514 | - | |
| 515 | - int rotatedPreviewWidth = width; | |
| 516 | - int rotatedPreviewHeight = height; | |
| 517 | - int maxPreviewWidth = screenSize.x; | |
| 518 | - int maxPreviewHeight = screenSize.y; | |
| 519 | - | |
| 520 | - if (swappedDimensions) { | |
| 521 | - rotatedPreviewWidth = height; | |
| 522 | - rotatedPreviewHeight = width; | |
| 523 | - maxPreviewWidth = screenSize.y; | |
| 524 | - maxPreviewHeight = screenSize.x; | |
| 525 | - } | |
| 526 | - | |
| 527 | - maxPreviewWidth = Math.min(maxPreviewWidth, MAX_PREVIEW_WIDTH); | |
| 528 | - maxPreviewHeight = Math.min(maxPreviewHeight, MAX_PREVIEW_HEIGHT); | |
| 529 | - | |
| 530 | - previewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), | |
| 531 | - rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth, | |
| 532 | - maxPreviewHeight, size); | |
| 533 | - this.cameraId = cameraId; | |
| 534 | - return; | |
| 535 | - } | |
| 536 | - } catch (CameraAccessException | NullPointerException e) { | |
| 537 | - if (e!=null) | |
| 538 | - e.printStackTrace(); | |
| 539 | - } | |
| 540 | - } | |
| 541 | - | |
| 542 | - private void closeCamera() { | |
| 543 | - try { | |
| 544 | - cameraLock.acquire(); | |
| 545 | - if (null != captureSession) { | |
| 546 | - captureSession.close(); | |
| 547 | - captureSession = null; | |
| 548 | - } | |
| 549 | - if (null != cameraDevice) { | |
| 550 | - cameraDevice.close(); | |
| 551 | - cameraDevice = null; | |
| 552 | - } | |
| 553 | - if (null != imageReader) { | |
| 554 | - imageReader.close(); | |
| 555 | - imageReader = null; | |
| 556 | - } | |
| 557 | - } catch (InterruptedException e) { | |
| 558 | - throw new RuntimeException("Interrupted while trying to lock camera closing.", e); | |
| 559 | - } finally { | |
| 560 | - cameraLock.release(); | |
| 561 | - } | |
| 562 | - } | |
| 563 | - | |
| 564 | - private void startBackgroundThread() { | |
| 565 | - backgroundThread = new HandlerThread("ocr_camera"); | |
| 566 | - backgroundThread.start(); | |
| 567 | - backgroundHandler = new Handler(backgroundThread.getLooper()); | |
| 568 | - } | |
| 569 | - | |
| 570 | - private void stopBackgroundThread() { | |
| 571 | - if (backgroundThread != null) { | |
| 572 | - backgroundThread.quitSafely(); | |
| 573 | - backgroundThread = null; | |
| 574 | - backgroundHandler = null; | |
| 575 | - } | |
| 576 | - } | |
| 577 | - | |
| 578 | - private void configureTransform(int viewWidth, int viewHeight) { | |
| 579 | - if (null == textureView || null == previewSize || null == context) { | |
| 580 | - return; | |
| 581 | - } | |
| 582 | - int rotation = orientation; | |
| 583 | - Matrix matrix = new Matrix(); | |
| 584 | - RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); | |
| 585 | - RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth()); | |
| 586 | - float centerX = viewRect.centerX(); | |
| 587 | - float centerY = viewRect.centerY(); | |
| 588 | - if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { | |
| 589 | - bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); | |
| 590 | - matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); | |
| 591 | - float scale = Math.max( | |
| 592 | - (float) viewHeight / previewSize.getHeight(), | |
| 593 | - (float) viewWidth / previewSize.getWidth()); | |
| 594 | - matrix.postScale(scale, scale, centerX, centerY); | |
| 595 | - matrix.postRotate(90 * (rotation - 2), centerX, centerY); | |
| 596 | - } else if (Surface.ROTATION_180 == rotation) { | |
| 597 | - matrix.postRotate(180, centerX, centerY); | |
| 598 | - } | |
| 599 | - textureView.setTransform(matrix); | |
| 600 | - } | |
| 601 | - | |
| 602 | - // 拍照前,先对焦 | |
| 603 | - private void lockFocus() { | |
| 604 | - if (captureSession != null && state == STATE_PREVIEW) { | |
| 605 | - try { | |
| 606 | - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, | |
| 607 | - CameraMetadata.CONTROL_AF_TRIGGER_START); | |
| 608 | - state = STATE_WAITING_FOR_LOCK; | |
| 609 | - captureSession.capture(previewRequestBuilder.build(), captureCallback, | |
| 610 | - backgroundHandler); | |
| 611 | - } catch (CameraAccessException e) { | |
| 612 | - if (e!=null) | |
| 613 | - e.printStackTrace(); | |
| 614 | - } | |
| 615 | - } | |
| 616 | - } | |
| 617 | - | |
| 618 | - private void runPreCaptureSequence() { | |
| 619 | - try { | |
| 620 | - previewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, | |
| 621 | - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); | |
| 622 | - state = STATE_WAITING_FOR_CAPTURE; | |
| 623 | - captureSession.capture(previewRequestBuilder.build(), captureCallback, | |
| 624 | - backgroundHandler); | |
| 625 | - } catch (CameraAccessException e) { | |
| 626 | - if (e!=null) | |
| 627 | - e.printStackTrace(); | |
| 628 | - } | |
| 629 | - } | |
| 630 | - | |
| 631 | - // 拍照session | |
| 632 | - private void captureStillPicture() { | |
| 633 | - try { | |
| 634 | - if (null == context || null == cameraDevice) { | |
| 635 | - return; | |
| 636 | - } | |
| 637 | - final CaptureRequest.Builder captureBuilder = | |
| 638 | - cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); | |
| 639 | - captureBuilder.addTarget(imageReader.getSurface()); | |
| 640 | - captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, | |
| 641 | - CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); | |
| 642 | - | |
| 643 | - captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(orientation)); | |
| 644 | - updateFlashMode(this.flashMode, captureBuilder); | |
| 645 | - CameraCaptureSession.CaptureCallback captureCallback = | |
| 646 | - new CameraCaptureSession.CaptureCallback() { | |
| 647 | - @Override | |
| 648 | - public void onCaptureCompleted(@NonNull CameraCaptureSession session, | |
| 649 | - @NonNull CaptureRequest request, | |
| 650 | - @NonNull TotalCaptureResult result) { | |
| 651 | - unlockFocus(); | |
| 652 | - } | |
| 653 | - | |
| 654 | - @Override | |
| 655 | - public void onCaptureFailed(@NonNull CameraCaptureSession session, | |
| 656 | - @NonNull CaptureRequest request, | |
| 657 | - @NonNull CaptureFailure failure) { | |
| 658 | - super.onCaptureFailed(session, request, failure); | |
| 659 | - } | |
| 660 | - }; | |
| 661 | - | |
| 662 | - // 停止预览 | |
| 663 | - captureSession.stopRepeating(); | |
| 664 | - captureSession.capture(captureBuilder.build(), captureCallback, backgroundHandler); | |
| 665 | - state = STATE_PICTURE_TAKEN; | |
| 666 | - // unlockFocus(); | |
| 667 | - } catch (CameraAccessException e) { | |
| 668 | - if (e!=null) | |
| 669 | - e.printStackTrace(); | |
| 670 | - } | |
| 671 | - } | |
| 672 | - | |
| 673 | - private int getOrientation(int rotation) { | |
| 674 | - return (ORIENTATIONS.get(rotation) + sensorOrientation + 270) % 360; | |
| 675 | - } | |
| 676 | - | |
| 677 | - // 停止对焦 | |
| 678 | - private void unlockFocus() { | |
| 679 | - try { | |
| 680 | - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, | |
| 681 | - CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); | |
| 682 | - captureSession.capture(previewRequestBuilder.build(), captureCallback, | |
| 683 | - backgroundHandler); | |
| 684 | - state = STATE_PREVIEW; | |
| 685 | - // 预览 | |
| 686 | - captureSession.setRepeatingRequest(previewRequest, captureCallback, | |
| 687 | - backgroundHandler); | |
| 688 | - textureView.setSurfaceTextureListener(surfaceTextureListener); | |
| 689 | - } catch (CameraAccessException e) { | |
| 690 | - if (e!=null) | |
| 691 | - e.printStackTrace(); | |
| 692 | - } | |
| 693 | - } | |
| 694 | - | |
| 695 | - private void updateFlashMode(@FlashMode int flashMode, CaptureRequest.Builder builder) { | |
| 696 | - switch (flashMode) { | |
| 697 | - case FLASH_MODE_TORCH: | |
| 698 | - builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH); | |
| 699 | - break; | |
| 700 | - case FLASH_MODE_OFF: | |
| 701 | - builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF); | |
| 702 | - break; | |
| 703 | - case ICameraControl.FLASH_MODE_AUTO: | |
| 704 | - default: | |
| 705 | - builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_SINGLE); | |
| 706 | - break; | |
| 707 | - } | |
| 708 | - } | |
| 709 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/CameraActivity.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | -import android.Manifest; | |
| 7 | -import android.app.Activity; | |
| 8 | -import android.content.Intent; | |
| 9 | -import android.content.pm.PackageManager; | |
| 10 | -import android.content.res.Configuration; | |
| 11 | -import android.graphics.Bitmap; | |
| 12 | -import android.graphics.Rect; | |
| 13 | -import android.graphics.drawable.BitmapDrawable; | |
| 14 | -import android.os.Build; | |
| 15 | -import android.os.Bundle; | |
| 16 | -import android.os.Environment; | |
| 17 | -import android.os.Handler; | |
| 18 | -import android.view.Surface; | |
| 19 | -import android.view.View; | |
| 20 | -import android.widget.ImageView; | |
| 21 | -import android.widget.Toast; | |
| 22 | - | |
| 23 | -import com.cnlive.core.libs.base.util.AlertUtil; | |
| 24 | -import com.cnlive.core.ocr.idcardquality.IDcardQualityProcess; | |
| 25 | -import com.cnlive.core.ocr.ui.crop.CropView; | |
| 26 | -import com.cnlive.core.ocr.ui.crop.FrameOverlayView; | |
| 27 | -import com.cnlive.core.people_verfication.R; | |
| 28 | -import com.cnlive.media.picker.ImagePicker; | |
| 29 | -import com.cnlive.media.picker.PickerConfig; | |
| 30 | -import com.cnlive.media.picker.entity.Media; | |
| 31 | - | |
| 32 | -import java.io.File; | |
| 33 | -import java.io.FileOutputStream; | |
| 34 | -import java.io.IOException; | |
| 35 | -import java.util.ArrayList; | |
| 36 | - | |
| 37 | -import androidx.annotation.NonNull; | |
| 38 | -import androidx.core.app.ActivityCompat; | |
| 39 | - | |
| 40 | -public class CameraActivity extends Activity { | |
| 41 | - | |
| 42 | - public static final String KEY_OUTPUT_FILE_PATH = "outputFilePath"; | |
| 43 | - public static final String KEY_CONTENT_TYPE = "contentType"; | |
| 44 | - public static final String KEY_NATIVE_TOKEN = "nativeToken"; | |
| 45 | - public static final String KEY_NATIVE_ENABLE = "nativeEnable"; | |
| 46 | - | |
| 47 | - public static final String CONTENT_TYPE_GENERAL = "general"; | |
| 48 | - public static final String CONTENT_TYPE_ID_CARD_FRONT = "IDCardFront"; | |
| 49 | - public static final String CONTENT_TYPE_ID_CARD_BACK = "IDCardBack"; | |
| 50 | - public static final String CONTENT_TYPE_BANK_CARD = "bankCard"; | |
| 51 | - | |
| 52 | - private static final int REQUEST_CODE_PICK_IMAGE = 100; | |
| 53 | - private static final int PERMISSIONS_REQUEST_CAMERA = 800; | |
| 54 | - private static final int PERMISSIONS_EXTERNAL_STORAGE = 801; | |
| 55 | - | |
| 56 | - private File outputFile; | |
| 57 | - private String contentType; | |
| 58 | - private Handler handler = new Handler(); | |
| 59 | - | |
| 60 | - private OCRCameraLayout takePictureContainer; | |
| 61 | - private OCRCameraLayout cropContainer; | |
| 62 | - private OCRCameraLayout confirmResultContainer; | |
| 63 | - private ImageView lightButton; | |
| 64 | - private CameraView cameraView; | |
| 65 | - private ImageView displayImageView; | |
| 66 | - private CropView cropView; | |
| 67 | - private FrameOverlayView overlayView; | |
| 68 | - private MaskView cropMaskView; | |
| 69 | - private ImageView takePhotoBtn; | |
| 70 | - private ImageView back; | |
| 71 | - //上一个被点击过的btn的点击时间 | |
| 72 | - private long preViewClickTime = 0; | |
| 73 | - private PermissionCallback permissionCallback = new PermissionCallback() { | |
| 74 | - @Override | |
| 75 | - public boolean onRequestPermission() { | |
| 76 | - ActivityCompat.requestPermissions(CameraActivity.this, | |
| 77 | - new String[]{Manifest.permission.CAMERA, | |
| 78 | - Manifest.permission.WRITE_EXTERNAL_STORAGE, | |
| 79 | - Manifest.permission.READ_EXTERNAL_STORAGE}, | |
| 80 | - PERMISSIONS_REQUEST_CAMERA); | |
| 81 | - return false; | |
| 82 | - } | |
| 83 | - }; | |
| 84 | - | |
| 85 | - @Override | |
| 86 | - protected void onCreate(Bundle savedInstanceState) { | |
| 87 | - | |
| 88 | - super.onCreate(savedInstanceState); | |
| 89 | - setContentView(R.layout.bd_ocr_activity_camera); | |
| 90 | - | |
| 91 | - takePictureContainer = (OCRCameraLayout) findViewById(R.id.take_picture_container); | |
| 92 | - confirmResultContainer = (OCRCameraLayout) findViewById(R.id.confirm_result_container); | |
| 93 | - | |
| 94 | - cameraView = (CameraView) findViewById(R.id.camera_view); | |
| 95 | - cameraView.getCameraControl().setPermissionCallback(permissionCallback); | |
| 96 | - lightButton = (ImageView) findViewById(R.id.light_button); | |
| 97 | - lightButton.setOnClickListener(lightButtonOnClickListener); | |
| 98 | - takePhotoBtn = (ImageView) findViewById(R.id.take_photo_button); | |
| 99 | - findViewById(R.id.album_button).setOnClickListener(albumButtonOnClickListener); | |
| 100 | - takePhotoBtn.setOnClickListener(takeButtonOnClickListener); | |
| 101 | - | |
| 102 | - // confirm result; | |
| 103 | - displayImageView = (ImageView) findViewById(R.id.display_image_view); | |
| 104 | - confirmResultContainer.findViewById(R.id.confirm_button).setOnClickListener(confirmButtonOnClickListener); | |
| 105 | - confirmResultContainer.findViewById(R.id.cancel_button).setOnClickListener(confirmCancelButtonOnClickListener); | |
| 106 | - findViewById(R.id.rotate_button).setOnClickListener(rotateButtonOnClickListener); | |
| 107 | - | |
| 108 | - cropView = (CropView) findViewById(R.id.crop_view); | |
| 109 | - cropContainer = (OCRCameraLayout) findViewById(R.id.crop_container); | |
| 110 | - overlayView = (FrameOverlayView) findViewById(R.id.overlay_view); | |
| 111 | - cropContainer.findViewById(R.id.confirm_button).setOnClickListener(cropConfirmButtonListener); | |
| 112 | - cropMaskView = (MaskView) cropContainer.findViewById(R.id.crop_mask_view); | |
| 113 | - cropContainer.findViewById(R.id.cancel_button).setOnClickListener(cropCancelButtonListener); | |
| 114 | - back = findViewById(R.id.back); | |
| 115 | - back.setOnClickListener(finishListener); | |
| 116 | - setOrientation(getResources().getConfiguration()); | |
| 117 | - initParams(); | |
| 118 | - | |
| 119 | - cameraView.setAutoPictureCallback(autoTakePictureCallback); | |
| 120 | - } | |
| 121 | - | |
| 122 | - @Override | |
| 123 | - protected void onStart() { | |
| 124 | - super.onStart(); | |
| 125 | - cameraView.start(); | |
| 126 | - } | |
| 127 | - | |
| 128 | - @Override | |
| 129 | - protected void onStop() { | |
| 130 | - super.onStop(); | |
| 131 | - cameraView.stop(); | |
| 132 | - } | |
| 133 | - | |
| 134 | - private void initParams() { | |
| 135 | - String outputPath = getIntent().getStringExtra(KEY_OUTPUT_FILE_PATH); | |
| 136 | - final String token = getIntent().getStringExtra(KEY_NATIVE_TOKEN); | |
| 137 | - boolean isNativeEnable = getIntent().getBooleanExtra(KEY_NATIVE_ENABLE, true); | |
| 138 | - if (token == null) { | |
| 139 | - isNativeEnable = false; | |
| 140 | - } | |
| 141 | - | |
| 142 | - if (outputPath != null) { | |
| 143 | - outputFile = new File(outputPath); | |
| 144 | - } | |
| 145 | - | |
| 146 | - contentType = getIntent().getStringExtra(KEY_CONTENT_TYPE); | |
| 147 | - if (contentType == null) { | |
| 148 | - contentType = CONTENT_TYPE_GENERAL; | |
| 149 | - } | |
| 150 | - int maskType; | |
| 151 | - switch (contentType) { | |
| 152 | - case CONTENT_TYPE_ID_CARD_FRONT: | |
| 153 | - maskType = MaskView.MASK_TYPE_ID_CARD_FRONT; | |
| 154 | - overlayView.setVisibility(View.INVISIBLE); | |
| 155 | - if (isNativeEnable) { | |
| 156 | - takePhotoBtn.setVisibility(View.INVISIBLE); | |
| 157 | - } | |
| 158 | - break; | |
| 159 | - case CONTENT_TYPE_ID_CARD_BACK: | |
| 160 | - maskType = MaskView.MASK_TYPE_ID_CARD_BACK; | |
| 161 | - overlayView.setVisibility(View.INVISIBLE); | |
| 162 | - if (isNativeEnable) { | |
| 163 | - takePhotoBtn.setVisibility(View.INVISIBLE); | |
| 164 | - } | |
| 165 | - break; | |
| 166 | - case CONTENT_TYPE_BANK_CARD: | |
| 167 | - maskType = MaskView.MASK_TYPE_BANK_CARD; | |
| 168 | - overlayView.setVisibility(View.INVISIBLE); | |
| 169 | - break; | |
| 170 | - case CONTENT_TYPE_GENERAL: | |
| 171 | - default: | |
| 172 | - maskType = MaskView.MASK_TYPE_NONE; | |
| 173 | - cropMaskView.setVisibility(View.INVISIBLE); | |
| 174 | - break; | |
| 175 | - } | |
| 176 | - | |
| 177 | - // 身份证本地能力初始化 | |
| 178 | - if (maskType == MaskView.MASK_TYPE_ID_CARD_FRONT || maskType == MaskView.MASK_TYPE_ID_CARD_BACK) { | |
| 179 | - if (isNativeEnable) { | |
| 180 | - initNative(token); | |
| 181 | - } | |
| 182 | - } | |
| 183 | - cameraView.setEnableScan(isNativeEnable); | |
| 184 | - cameraView.setMaskType(maskType, this); | |
| 185 | - cropMaskView.setMaskType(maskType); | |
| 186 | - } | |
| 187 | - | |
| 188 | - private void initNative(final String token) { | |
| 189 | - CameraThreadPool.execute(new Runnable() { | |
| 190 | - @Override | |
| 191 | - public void run() { | |
| 192 | - // 加载本地so失败, 异常返回getloadSoException | |
| 193 | - if (IDcardQualityProcess.getLoadSoException() != null) { | |
| 194 | - cameraView.setInitNativeStatus(CameraView.NATIVE_SOLOAD_FAIL); | |
| 195 | - return; | |
| 196 | - } | |
| 197 | - // 授权状态 | |
| 198 | - int authStatus = IDcardQualityProcess.init(token); | |
| 199 | - // 加载模型状态 | |
| 200 | - int initModelStatus = IDcardQualityProcess.getInstance() | |
| 201 | - .idcardQualityInit(CameraActivity.this.getAssets(), | |
| 202 | - "models"); | |
| 203 | - if (authStatus != 0) { | |
| 204 | - cameraView.setInitNativeStatus(CameraView.NATIVE_AUTH_FAIL); | |
| 205 | - return; | |
| 206 | - } | |
| 207 | - if (initModelStatus != 0) { | |
| 208 | - cameraView.setInitNativeStatus(CameraView.NATIVE_INIT_FAIL); | |
| 209 | - return; | |
| 210 | - } | |
| 211 | - } | |
| 212 | - }); | |
| 213 | - } | |
| 214 | - | |
| 215 | - private void showTakePicture() { | |
| 216 | - cameraView.getCameraControl().resume(); | |
| 217 | - updateFlashMode(); | |
| 218 | - takePictureContainer.setVisibility(View.VISIBLE); | |
| 219 | - back.setVisibility(View.VISIBLE); | |
| 220 | - confirmResultContainer.setVisibility(View.INVISIBLE); | |
| 221 | - cropContainer.setVisibility(View.INVISIBLE); | |
| 222 | - } | |
| 223 | - | |
| 224 | - private void showCrop() { | |
| 225 | - cameraView.getCameraControl().pause(); | |
| 226 | - updateFlashMode(); | |
| 227 | - takePictureContainer.setVisibility(View.INVISIBLE); | |
| 228 | - back.setVisibility(View.INVISIBLE); | |
| 229 | - confirmResultContainer.setVisibility(View.INVISIBLE); | |
| 230 | - cropContainer.setVisibility(View.VISIBLE); | |
| 231 | - } | |
| 232 | - | |
| 233 | - private void showResultConfirm() { | |
| 234 | - cameraView.getCameraControl().pause(); | |
| 235 | - updateFlashMode(); | |
| 236 | - takePictureContainer.setVisibility(View.INVISIBLE); | |
| 237 | - back.setVisibility(View.INVISIBLE); | |
| 238 | - confirmResultContainer.setVisibility(View.VISIBLE); | |
| 239 | - cropContainer.setVisibility(View.INVISIBLE); | |
| 240 | - } | |
| 241 | - | |
| 242 | - // take photo; | |
| 243 | - private void updateFlashMode() { | |
| 244 | - int flashMode = cameraView.getCameraControl().getFlashMode(); | |
| 245 | - if (flashMode == ICameraControl.FLASH_MODE_TORCH) { | |
| 246 | - lightButton.setImageResource(R.drawable.bd_ocr_light_on); | |
| 247 | - } else { | |
| 248 | - lightButton.setImageResource(R.drawable.bd_ocr_light_off); | |
| 249 | - } | |
| 250 | - } | |
| 251 | - | |
| 252 | - private View.OnClickListener albumButtonOnClickListener = new View.OnClickListener() { | |
| 253 | - @Override | |
| 254 | - public void onClick(View v) { | |
| 255 | - long curClickTime = System.currentTimeMillis(); | |
| 256 | - if (preViewClickTime > 0 && curClickTime - preViewClickTime <= 2000 ) { | |
| 257 | - return; | |
| 258 | - } | |
| 259 | - preViewClickTime = curClickTime; | |
| 260 | - if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) | |
| 261 | - != PackageManager.PERMISSION_GRANTED) { | |
| 262 | - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { | |
| 263 | - ActivityCompat.requestPermissions(CameraActivity.this, | |
| 264 | - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, | |
| 265 | - PERMISSIONS_EXTERNAL_STORAGE); | |
| 266 | - return; | |
| 267 | - } | |
| 268 | - } | |
| 269 | - new ImagePicker | |
| 270 | - .Builder() | |
| 271 | - .setSelectGif(false) | |
| 272 | - .maxImageSize(20 * 1024 * 1024) | |
| 273 | - //最大选择图片数目,默认40张 | |
| 274 | - .maxNum(1) | |
| 275 | - //选择模式(默认PICKER_IMAGE_VIDEO) PICKER_IMAGE-->图片 PICKER_VIDEO-->视频 PICKER_IMAGE_VIDEO-->图片&视频 | |
| 276 | - .selectMode(PickerConfig.PICKER_IMAGE) | |
| 277 | - //拍照或录像存储位置 默认Environment.getExternalStorageDirectory().getPath() + File.separator + "JCamera" | |
| 278 | - .cachePath(Environment.getExternalStorageDirectory() + "/strike/file/") | |
| 279 | - //是否为发朋友圈模式(默认false) true-->图片与视频不能同时选择 | |
| 280 | - .isFriendCircle(true) | |
| 281 | - //裁剪 只有在单选模式下才可以使用 | |
| 282 | -// .doCrop(1, 1, 300, 300) | |
| 283 | - //是否开启单选模式(默认false) | |
| 284 | - .isSinglePick(true) | |
| 285 | - .builder() | |
| 286 | - .start(CameraActivity.this, PickerConfig.PICKER_IMAGE, REQUEST_CODE_PICK_IMAGE); | |
| 287 | - } | |
| 288 | - }; | |
| 289 | - | |
| 290 | - private View.OnClickListener lightButtonOnClickListener = new View.OnClickListener() { | |
| 291 | - @Override | |
| 292 | - public void onClick(View v) { | |
| 293 | - if (cameraView.getCameraControl().getFlashMode() == ICameraControl.FLASH_MODE_OFF) { | |
| 294 | - cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_TORCH); | |
| 295 | - } else { | |
| 296 | - cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_OFF); | |
| 297 | - } | |
| 298 | - updateFlashMode(); | |
| 299 | - } | |
| 300 | - }; | |
| 301 | - | |
| 302 | - private View.OnClickListener takeButtonOnClickListener = new View.OnClickListener() { | |
| 303 | - @Override | |
| 304 | - public void onClick(View v) { | |
| 305 | - if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) | |
| 306 | - != PackageManager.PERMISSION_GRANTED) { | |
| 307 | - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { | |
| 308 | - ActivityCompat.requestPermissions(CameraActivity.this, | |
| 309 | - new String[]{Manifest.permission.CAMERA, | |
| 310 | - Manifest.permission.WRITE_EXTERNAL_STORAGE, | |
| 311 | - Manifest.permission.READ_EXTERNAL_STORAGE}, | |
| 312 | - PERMISSIONS_REQUEST_CAMERA); | |
| 313 | - return; | |
| 314 | - } | |
| 315 | - } | |
| 316 | - cameraView.takePicture(outputFile, takePictureCallback); | |
| 317 | - } | |
| 318 | - }; | |
| 319 | - | |
| 320 | - private CameraView.OnTakePictureCallback autoTakePictureCallback = new CameraView.OnTakePictureCallback() { | |
| 321 | - @Override | |
| 322 | - public void onPictureTaken(final Bitmap bitmap) { | |
| 323 | - CameraThreadPool.execute(new Runnable() { | |
| 324 | - @Override | |
| 325 | - public void run() { | |
| 326 | - try { | |
| 327 | - FileOutputStream fileOutputStream = new FileOutputStream(outputFile); | |
| 328 | - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream); | |
| 329 | - bitmap.recycle(); | |
| 330 | - fileOutputStream.close(); | |
| 331 | - } catch (IOException e) { | |
| 332 | - e.printStackTrace(); | |
| 333 | - } | |
| 334 | - Intent intent = new Intent(); | |
| 335 | - intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, contentType); | |
| 336 | - setResult(Activity.RESULT_OK, intent); | |
| 337 | - finish(); | |
| 338 | - } | |
| 339 | - }); | |
| 340 | - } | |
| 341 | - }; | |
| 342 | - | |
| 343 | - private CameraView.OnTakePictureCallback takePictureCallback = new CameraView.OnTakePictureCallback() { | |
| 344 | - @Override | |
| 345 | - public void onPictureTaken(final Bitmap bitmap) { | |
| 346 | - handler.post(new Runnable() { | |
| 347 | - @Override | |
| 348 | - public void run() { | |
| 349 | - takePictureContainer.setVisibility(View.INVISIBLE); | |
| 350 | - back.setVisibility(View.INVISIBLE); | |
| 351 | - if (cropMaskView.getMaskType() == MaskView.MASK_TYPE_NONE) { | |
| 352 | - cropView.setFilePath(outputFile.getAbsolutePath()); | |
| 353 | - showCrop(); | |
| 354 | - } else if (cropMaskView.getMaskType() == MaskView.MASK_TYPE_BANK_CARD) { | |
| 355 | - cropView.setFilePath(outputFile.getAbsolutePath()); | |
| 356 | - cropMaskView.setVisibility(View.INVISIBLE); | |
| 357 | - overlayView.setVisibility(View.VISIBLE); | |
| 358 | - overlayView.setTypeWide(); | |
| 359 | - showCrop(); | |
| 360 | - } else { | |
| 361 | - displayImageView.setImageBitmap(bitmap); | |
| 362 | - showResultConfirm(); | |
| 363 | - } | |
| 364 | - } | |
| 365 | - }); | |
| 366 | - } | |
| 367 | - }; | |
| 368 | - | |
| 369 | - private View.OnClickListener cropCancelButtonListener = new View.OnClickListener() { | |
| 370 | - @Override | |
| 371 | - public void onClick(View v) { | |
| 372 | - // 释放 cropView中的bitmap; | |
| 373 | - cropView.setFilePath(null); | |
| 374 | - showTakePicture(); | |
| 375 | - } | |
| 376 | - }; | |
| 377 | - | |
| 378 | - | |
| 379 | - private View.OnClickListener finishListener = new View.OnClickListener() { | |
| 380 | - @Override | |
| 381 | - public void onClick(View v) { | |
| 382 | - finish(); | |
| 383 | - } | |
| 384 | - }; | |
| 385 | - | |
| 386 | - private View.OnClickListener cropConfirmButtonListener = new View.OnClickListener() { | |
| 387 | - @Override | |
| 388 | - public void onClick(View v) { | |
| 389 | - int maskType = cropMaskView.getMaskType(); | |
| 390 | - Rect rect; | |
| 391 | - switch (maskType) { | |
| 392 | - case MaskView.MASK_TYPE_BANK_CARD: | |
| 393 | - case MaskView.MASK_TYPE_ID_CARD_BACK: | |
| 394 | - case MaskView.MASK_TYPE_ID_CARD_FRONT: | |
| 395 | - rect = cropMaskView.getFrameRect(); | |
| 396 | - break; | |
| 397 | - case MaskView.MASK_TYPE_NONE: | |
| 398 | - default: | |
| 399 | - rect = overlayView.getFrameRect(); | |
| 400 | - break; | |
| 401 | - } | |
| 402 | - Bitmap cropped = cropView.crop(rect); | |
| 403 | - if(cropped == null){ | |
| 404 | - return; | |
| 405 | - } | |
| 406 | - displayImageView.setImageBitmap(cropped); | |
| 407 | - cropAndConfirm(); | |
| 408 | - } | |
| 409 | - }; | |
| 410 | - | |
| 411 | - private void cropAndConfirm() { | |
| 412 | - cameraView.getCameraControl().pause(); | |
| 413 | - updateFlashMode(); | |
| 414 | - doConfirmResult(); | |
| 415 | - } | |
| 416 | - | |
| 417 | - private void doConfirmResult() { | |
| 418 | - CameraThreadPool.execute(new Runnable() { | |
| 419 | - @Override | |
| 420 | - public void run() { | |
| 421 | - try { | |
| 422 | - FileOutputStream fileOutputStream = new FileOutputStream(outputFile); | |
| 423 | - Bitmap bitmap = ((BitmapDrawable) displayImageView.getDrawable()).getBitmap(); | |
| 424 | - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream); | |
| 425 | - fileOutputStream.close(); | |
| 426 | - } catch (IOException e) { | |
| 427 | - if (e!=null) | |
| 428 | - e.printStackTrace(); | |
| 429 | - } | |
| 430 | - Intent intent = new Intent(); | |
| 431 | - intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, contentType); | |
| 432 | - setResult(Activity.RESULT_OK, intent); | |
| 433 | - finish(); | |
| 434 | - } | |
| 435 | - }); | |
| 436 | - } | |
| 437 | - | |
| 438 | - private View.OnClickListener confirmButtonOnClickListener = new View.OnClickListener() { | |
| 439 | - @Override | |
| 440 | - public void onClick(View v) { | |
| 441 | - doConfirmResult(); | |
| 442 | - } | |
| 443 | - }; | |
| 444 | - | |
| 445 | - private View.OnClickListener confirmCancelButtonOnClickListener = new View.OnClickListener() { | |
| 446 | - @Override | |
| 447 | - public void onClick(View v) { | |
| 448 | - displayImageView.setImageBitmap(null); | |
| 449 | - showTakePicture(); | |
| 450 | - } | |
| 451 | - }; | |
| 452 | - | |
| 453 | - private View.OnClickListener rotateButtonOnClickListener = new View.OnClickListener() { | |
| 454 | - @Override | |
| 455 | - public void onClick(View v) { | |
| 456 | - cropView.rotate(90); | |
| 457 | - } | |
| 458 | - }; | |
| 459 | - | |
| 460 | - @Override | |
| 461 | - public void onConfigurationChanged(Configuration newConfig) { | |
| 462 | - super.onConfigurationChanged(newConfig); | |
| 463 | - setOrientation(newConfig); | |
| 464 | - } | |
| 465 | - | |
| 466 | - private void setOrientation(Configuration newConfig) { | |
| 467 | - int rotation = getWindowManager().getDefaultDisplay().getRotation(); | |
| 468 | - int orientation; | |
| 469 | - int cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT; | |
| 470 | - switch (newConfig.orientation) { | |
| 471 | - case Configuration.ORIENTATION_PORTRAIT: | |
| 472 | - cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT; | |
| 473 | - orientation = OCRCameraLayout.ORIENTATION_PORTRAIT; | |
| 474 | - break; | |
| 475 | - case Configuration.ORIENTATION_LANDSCAPE: | |
| 476 | - orientation = OCRCameraLayout.ORIENTATION_HORIZONTAL; | |
| 477 | - if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) { | |
| 478 | - cameraViewOrientation = CameraView.ORIENTATION_HORIZONTAL; | |
| 479 | - } else { | |
| 480 | - cameraViewOrientation = CameraView.ORIENTATION_INVERT; | |
| 481 | - } | |
| 482 | - break; | |
| 483 | - default: | |
| 484 | - orientation = OCRCameraLayout.ORIENTATION_PORTRAIT; | |
| 485 | - cameraView.setOrientation(CameraView.ORIENTATION_PORTRAIT); | |
| 486 | - break; | |
| 487 | - } | |
| 488 | - takePictureContainer.setOrientation(orientation); | |
| 489 | - cameraView.setOrientation(cameraViewOrientation); | |
| 490 | - cropContainer.setOrientation(orientation); | |
| 491 | - confirmResultContainer.setOrientation(orientation); | |
| 492 | - } | |
| 493 | - | |
| 494 | - @Override | |
| 495 | - protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
| 496 | - super.onActivityResult(requestCode, resultCode, data); | |
| 497 | - if (requestCode == REQUEST_CODE_PICK_IMAGE && data != null) { | |
| 498 | - ArrayList<Media> select = data.getParcelableArrayListExtra(PickerConfig.EXTRA_RESULT); | |
| 499 | - String path = select.get(0).path; | |
| 500 | - cropView.setFilePath(path); | |
| 501 | - showCrop(); | |
| 502 | - }else { | |
| 503 | - cameraView.getCameraControl().resume(); | |
| 504 | - } | |
| 505 | - } | |
| 506 | - | |
| 507 | - | |
| 508 | - | |
| 509 | - @Override | |
| 510 | - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, | |
| 511 | - @NonNull int[] grantResults) { | |
| 512 | - super.onRequestPermissionsResult(requestCode, permissions, grantResults); | |
| 513 | - switch (requestCode) { | |
| 514 | - case PERMISSIONS_REQUEST_CAMERA: { | |
| 515 | - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
| 516 | - cameraView.getCameraControl().refreshPermission(); | |
| 517 | - } else { | |
| 518 | - AlertUtil.showLongToast(getApplicationContext(), getString(R.string.camera_permission_required), Toast.LENGTH_LONG); | |
| 519 | - } | |
| 520 | - break; | |
| 521 | - } | |
| 522 | - case PERMISSIONS_EXTERNAL_STORAGE: | |
| 523 | - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
| 524 | - | |
| 525 | - } else { | |
| 526 | - AlertUtil.showLongToast(getApplicationContext(), getString(R.string.permission_required), Toast.LENGTH_LONG); | |
| 527 | - } | |
| 528 | - default: | |
| 529 | - break; | |
| 530 | - } | |
| 531 | - } | |
| 532 | - | |
| 533 | - /** | |
| 534 | - * 做一些收尾工作,把这些工作从onDestory中移到正确的位置 | |
| 535 | - * 可以以防止新的activity启动后被调用 | |
| 536 | - */ | |
| 537 | - private void doClear() { | |
| 538 | - CameraThreadPool.cancelAutoFocusTimer(); | |
| 539 | - IDcardQualityProcess.getInstance().releaseModel(); | |
| 540 | - } | |
| 541 | - | |
| 542 | - | |
| 543 | - @Override | |
| 544 | - protected void onDestroy() { | |
| 545 | - super.onDestroy(); | |
| 546 | - this.doClear(); | |
| 547 | - } | |
| 548 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/CameraThreadPool.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | -import java.util.Timer; | |
| 7 | -import java.util.TimerTask; | |
| 8 | -import java.util.concurrent.ExecutorService; | |
| 9 | -import java.util.concurrent.Executors; | |
| 10 | - | |
| 11 | -public class CameraThreadPool { | |
| 12 | - | |
| 13 | - static Timer timerFocus = null; | |
| 14 | - | |
| 15 | - /* | |
| 16 | - * 对焦频率 | |
| 17 | - */ | |
| 18 | - static final long cameraScanInterval = 2000; | |
| 19 | - | |
| 20 | - /* | |
| 21 | - * 线程池大小 | |
| 22 | - */ | |
| 23 | - private static int poolCount = Runtime.getRuntime().availableProcessors(); | |
| 24 | - | |
| 25 | - private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(poolCount); | |
| 26 | - | |
| 27 | - /** | |
| 28 | - * 给线程池添加任务 | |
| 29 | - * | |
| 30 | - * @param runnable 任务 | |
| 31 | - */ | |
| 32 | - public static void execute(Runnable runnable) { | |
| 33 | - fixedThreadPool.execute(runnable); | |
| 34 | - } | |
| 35 | - | |
| 36 | - /** | |
| 37 | - * 创建一个定时对焦的timer任务 | |
| 38 | - * | |
| 39 | - * @param runnable 对焦代码 | |
| 40 | - * @return Timer Timer对象,用来终止自动对焦 | |
| 41 | - */ | |
| 42 | - public static Timer createAutoFocusTimerTask(final Runnable runnable) { | |
| 43 | - if (timerFocus != null) { | |
| 44 | - return timerFocus; | |
| 45 | - } | |
| 46 | - timerFocus = new Timer(); | |
| 47 | - TimerTask task = new TimerTask() { | |
| 48 | - @Override | |
| 49 | - public void run() { | |
| 50 | - runnable.run(); | |
| 51 | - } | |
| 52 | - }; | |
| 53 | - timerFocus.scheduleAtFixedRate(task, 0, cameraScanInterval); | |
| 54 | - return timerFocus; | |
| 55 | - } | |
| 56 | - | |
| 57 | - /** | |
| 58 | - * 终止自动对焦任务,实际调用了cancel方法并且清空对象 | |
| 59 | - * 但是无法终止执行中的任务,需额外处理 | |
| 60 | - */ | |
| 61 | - public static void cancelAutoFocusTimer() { | |
| 62 | - if (timerFocus != null) { | |
| 63 | - timerFocus.cancel(); | |
| 64 | - timerFocus = null; | |
| 65 | - } | |
| 66 | - } | |
| 67 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/CameraView.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | -import android.content.Context; | |
| 7 | -import android.graphics.Bitmap; | |
| 8 | -import android.graphics.BitmapFactory; | |
| 9 | -import android.graphics.BitmapRegionDecoder; | |
| 10 | -import android.graphics.Color; | |
| 11 | -import android.graphics.Matrix; | |
| 12 | -import android.graphics.Rect; | |
| 13 | -import android.os.Handler; | |
| 14 | -import android.os.Looper; | |
| 15 | -import android.util.AttributeSet; | |
| 16 | -import android.util.TypedValue; | |
| 17 | -import android.view.Gravity; | |
| 18 | -import android.view.View; | |
| 19 | -import android.widget.FrameLayout; | |
| 20 | -import android.widget.ImageView; | |
| 21 | -import android.widget.LinearLayout; | |
| 22 | -import android.widget.TextView; | |
| 23 | - | |
| 24 | -import com.cnlive.core.ocr.idcardquality.IDcardQualityProcess; | |
| 25 | -import com.cnlive.core.ocr.ui.util.ImageUtil; | |
| 26 | -import com.cnlive.core.ocr.ui.util.PxUtil; | |
| 27 | -import com.cnlive.core.people_verfication.R; | |
| 28 | - | |
| 29 | -import java.io.File; | |
| 30 | -import java.io.FileOutputStream; | |
| 31 | -import java.io.IOException; | |
| 32 | - | |
| 33 | -import androidx.annotation.IntDef; | |
| 34 | - | |
| 35 | -/** | |
| 36 | - * 负责,相机的管理。同时提供,裁剪遮罩功能。 | |
| 37 | - */ | |
| 38 | -public class CameraView extends FrameLayout { | |
| 39 | - | |
| 40 | - private int maskType; | |
| 41 | - | |
| 42 | - /** | |
| 43 | - * 照相回调 | |
| 44 | - */ | |
| 45 | - interface OnTakePictureCallback { | |
| 46 | - void onPictureTaken(Bitmap bitmap); | |
| 47 | - } | |
| 48 | - | |
| 49 | - /** | |
| 50 | - * 垂直方向 {@link #setOrientation(int)} | |
| 51 | - */ | |
| 52 | - public static final int ORIENTATION_PORTRAIT = 0; | |
| 53 | - /** | |
| 54 | - * 水平方向 {@link #setOrientation(int)} | |
| 55 | - */ | |
| 56 | - public static final int ORIENTATION_HORIZONTAL = 90; | |
| 57 | - /** | |
| 58 | - * 水平翻转方向 {@link #setOrientation(int)} | |
| 59 | - */ | |
| 60 | - public static final int ORIENTATION_INVERT = 270; | |
| 61 | - | |
| 62 | - /** | |
| 63 | - * 本地模型授权,加载成功 | |
| 64 | - */ | |
| 65 | - public static final int NATIVE_AUTH_INIT_SUCCESS = 0; | |
| 66 | - | |
| 67 | - /** | |
| 68 | - * 本地模型授权,加载成功 | |
| 69 | - */ | |
| 70 | - public static final int NATIVE_SOLOAD_FAIL = 10; | |
| 71 | - | |
| 72 | - /** | |
| 73 | - * 本地模型授权,加载成功 | |
| 74 | - */ | |
| 75 | - public static final int NATIVE_AUTH_FAIL = 11; | |
| 76 | - | |
| 77 | - /** | |
| 78 | - * 本地模型授权,加载成功 | |
| 79 | - */ | |
| 80 | - public static final int NATIVE_INIT_FAIL = 12; | |
| 81 | - | |
| 82 | - | |
| 83 | - /** | |
| 84 | - * 是否已经通过本地质量控制扫描 | |
| 85 | - */ | |
| 86 | - private final int SCAN_SUCCESS = 0; | |
| 87 | - | |
| 88 | - public void setInitNativeStatus(int initNativeStatus) { | |
| 89 | - this.initNativeStatus = initNativeStatus; | |
| 90 | - } | |
| 91 | - | |
| 92 | - /** | |
| 93 | - * 本地检测初始化,模型加载标识 | |
| 94 | - */ | |
| 95 | - private int initNativeStatus = NATIVE_AUTH_INIT_SUCCESS; | |
| 96 | - | |
| 97 | - @IntDef({ORIENTATION_PORTRAIT, ORIENTATION_HORIZONTAL, ORIENTATION_INVERT}) | |
| 98 | - public @interface Orientation { | |
| 99 | - | |
| 100 | - } | |
| 101 | - | |
| 102 | - private CameraViewTakePictureCallback cameraViewTakePictureCallback = new CameraViewTakePictureCallback(); | |
| 103 | - | |
| 104 | - private ICameraControl cameraControl; | |
| 105 | - | |
| 106 | - /** | |
| 107 | - * 相机预览View | |
| 108 | - */ | |
| 109 | - private View displayView; | |
| 110 | - /** | |
| 111 | - * 身份证,银行卡,等裁剪用的遮罩 | |
| 112 | - */ | |
| 113 | - private MaskView maskView; | |
| 114 | - | |
| 115 | - /** | |
| 116 | - * 用于显示提示证 "请对齐身份证正面" 之类的背景 | |
| 117 | - */ | |
| 118 | - private ImageView hintView; | |
| 119 | - | |
| 120 | - /** | |
| 121 | - * 用于显示提示证 "请对齐身份证正面" 之类的文字 | |
| 122 | - */ | |
| 123 | - private TextView hintViewText; | |
| 124 | - | |
| 125 | - /** | |
| 126 | - * 提示文案容器 | |
| 127 | - */ | |
| 128 | - private LinearLayout hintViewTextWrapper; | |
| 129 | - | |
| 130 | - /** | |
| 131 | - * 是否是本地质量控制扫描 | |
| 132 | - */ | |
| 133 | - private boolean isEnableScan; | |
| 134 | - | |
| 135 | - public void setEnableScan(boolean enableScan) { | |
| 136 | - isEnableScan = enableScan; | |
| 137 | - } | |
| 138 | - | |
| 139 | - /** | |
| 140 | - * UI线程的handler | |
| 141 | - */ | |
| 142 | - Handler uiHandler = new Handler(Looper.getMainLooper()); | |
| 143 | - | |
| 144 | - public ICameraControl getCameraControl() { | |
| 145 | - return cameraControl; | |
| 146 | - } | |
| 147 | - | |
| 148 | - public void setOrientation(@Orientation int orientation) { | |
| 149 | - cameraControl.setDisplayOrientation(orientation); | |
| 150 | - } | |
| 151 | - | |
| 152 | - public CameraView(Context context) { | |
| 153 | - super(context); | |
| 154 | - init(); | |
| 155 | - } | |
| 156 | - | |
| 157 | - public CameraView(Context context, AttributeSet attrs) { | |
| 158 | - super(context, attrs); | |
| 159 | - init(); | |
| 160 | - } | |
| 161 | - | |
| 162 | - public CameraView(Context context, AttributeSet attrs, int defStyleAttr) { | |
| 163 | - super(context, attrs, defStyleAttr); | |
| 164 | - init(); | |
| 165 | - } | |
| 166 | - | |
| 167 | - public void start() { | |
| 168 | - cameraControl.start(); | |
| 169 | - setKeepScreenOn(true); | |
| 170 | - } | |
| 171 | - | |
| 172 | - public void stop() { | |
| 173 | - cameraControl.stop(); | |
| 174 | - setKeepScreenOn(false); | |
| 175 | - } | |
| 176 | - | |
| 177 | - public void takePicture(final File file, final OnTakePictureCallback callback) { | |
| 178 | - cameraViewTakePictureCallback.file = file; | |
| 179 | - cameraViewTakePictureCallback.callback = callback; | |
| 180 | - cameraControl.takePicture(cameraViewTakePictureCallback); | |
| 181 | - } | |
| 182 | - | |
| 183 | - private OnTakePictureCallback autoPictureCallback; | |
| 184 | - | |
| 185 | - public void setAutoPictureCallback(OnTakePictureCallback callback) { | |
| 186 | - autoPictureCallback = callback; | |
| 187 | - } | |
| 188 | - | |
| 189 | - public void setMaskType(@MaskView.MaskType int maskType, final Context ctx) { | |
| 190 | - maskView.setMaskType(maskType); | |
| 191 | - | |
| 192 | - maskView.setVisibility(VISIBLE); | |
| 193 | - hintView.setVisibility(VISIBLE); | |
| 194 | - | |
| 195 | - int hintResourceId = R.drawable.bd_ocr_hint_align_id_card; | |
| 196 | - this.maskType = maskType; | |
| 197 | - boolean isNeedSetImage = true; | |
| 198 | - switch (maskType) { | |
| 199 | - case MaskView.MASK_TYPE_ID_CARD_FRONT: | |
| 200 | - hintResourceId = R.drawable.bd_ocr_round_corner; | |
| 201 | - isNeedSetImage = false; | |
| 202 | - break; | |
| 203 | - case MaskView.MASK_TYPE_ID_CARD_BACK: | |
| 204 | - isNeedSetImage = false; | |
| 205 | - hintResourceId = R.drawable.bd_ocr_round_corner; | |
| 206 | - break; | |
| 207 | - case MaskView.MASK_TYPE_BANK_CARD: | |
| 208 | - hintResourceId = R.drawable.bd_ocr_hint_align_bank_card; | |
| 209 | - break; | |
| 210 | - case MaskView.MASK_TYPE_NONE: | |
| 211 | - default: | |
| 212 | - maskView.setVisibility(INVISIBLE); | |
| 213 | - hintView.setVisibility(INVISIBLE); | |
| 214 | - break; | |
| 215 | - } | |
| 216 | - | |
| 217 | - if (isNeedSetImage) { | |
| 218 | - hintView.setImageResource(hintResourceId); | |
| 219 | - hintViewTextWrapper.setVisibility(INVISIBLE); | |
| 220 | - } | |
| 221 | - | |
| 222 | - if (maskType == MaskView.MASK_TYPE_ID_CARD_FRONT && isEnableScan) { | |
| 223 | - cameraControl.setDetectCallback(new ICameraControl.OnDetectPictureCallback() { | |
| 224 | - @Override | |
| 225 | - public int onDetect(byte[] data, int rotation) { | |
| 226 | - return detect(data, rotation); | |
| 227 | - } | |
| 228 | - }); | |
| 229 | - } | |
| 230 | - | |
| 231 | - if (maskType == MaskView.MASK_TYPE_ID_CARD_BACK && isEnableScan) { | |
| 232 | - cameraControl.setDetectCallback(new ICameraControl.OnDetectPictureCallback() { | |
| 233 | - @Override | |
| 234 | - public int onDetect(byte[] data, int rotation) { | |
| 235 | - return detect(data, rotation); | |
| 236 | - } | |
| 237 | - }); | |
| 238 | - } | |
| 239 | - } | |
| 240 | - | |
| 241 | - private int detect(byte[] data, final int rotation) { | |
| 242 | - if (initNativeStatus != NATIVE_AUTH_INIT_SUCCESS) { | |
| 243 | - showTipMessage(initNativeStatus); | |
| 244 | - return 1; | |
| 245 | - } | |
| 246 | - // 扫描成功阻止多余的操作 | |
| 247 | - if (cameraControl.getAbortingScan().get()) { | |
| 248 | - return 0; | |
| 249 | - } | |
| 250 | - // BitmapRegionDecoder不会将整个图片加载到内存。 | |
| 251 | - BitmapRegionDecoder decoder = null; | |
| 252 | - try { | |
| 253 | - decoder = BitmapRegionDecoder.newInstance(data, 0, data.length, true); | |
| 254 | - } catch (IOException e) { | |
| 255 | - if (e!=null) | |
| 256 | - e.printStackTrace(); | |
| 257 | - } | |
| 258 | - | |
| 259 | - Rect previewFrame = cameraControl.getPreviewFrame(); | |
| 260 | - | |
| 261 | - int width = rotation % 180 == 0 ? decoder.getWidth() : decoder.getHeight(); | |
| 262 | - int height = rotation % 180 == 0 ? decoder.getHeight() : decoder.getWidth(); | |
| 263 | - | |
| 264 | - Rect frameRect = maskView.getFrameRectExtend(); | |
| 265 | - | |
| 266 | - int left = width * frameRect.left / maskView.getWidth(); | |
| 267 | - int top = height * frameRect.top / maskView.getHeight(); | |
| 268 | - int right = width * frameRect.right / maskView.getWidth(); | |
| 269 | - int bottom = height * frameRect.bottom / maskView.getHeight(); | |
| 270 | - | |
| 271 | - // 高度大于图片 | |
| 272 | - if (previewFrame.top < 0) { | |
| 273 | - // 宽度对齐。 | |
| 274 | - int adjustedPreviewHeight = previewFrame.height() * getWidth() / previewFrame.width(); | |
| 275 | - int topInFrame = ((adjustedPreviewHeight - frameRect.height()) / 2) | |
| 276 | - * getWidth() / previewFrame.width(); | |
| 277 | - int bottomInFrame = ((adjustedPreviewHeight + frameRect.height()) / 2) * getWidth() | |
| 278 | - / previewFrame.width(); | |
| 279 | - | |
| 280 | - // 等比例投射到照片当中。 | |
| 281 | - top = topInFrame * height / previewFrame.height(); | |
| 282 | - bottom = bottomInFrame * height / previewFrame.height(); | |
| 283 | - } else { | |
| 284 | - // 宽度大于图片 | |
| 285 | - if (previewFrame.left < 0) { | |
| 286 | - // 高度对齐 | |
| 287 | - int adjustedPreviewWidth = previewFrame.width() * getHeight() / previewFrame.height(); | |
| 288 | - int leftInFrame = ((adjustedPreviewWidth - maskView.getFrameRect().width()) / 2) * getHeight() | |
| 289 | - / previewFrame.height(); | |
| 290 | - int rightInFrame = ((adjustedPreviewWidth + maskView.getFrameRect().width()) / 2) * getHeight() | |
| 291 | - / previewFrame.height(); | |
| 292 | - | |
| 293 | - // 等比例投射到照片当中。 | |
| 294 | - left = leftInFrame * width / previewFrame.width(); | |
| 295 | - right = rightInFrame * width / previewFrame.width(); | |
| 296 | - } | |
| 297 | - } | |
| 298 | - | |
| 299 | - Rect region = new Rect(); | |
| 300 | - region.left = left; | |
| 301 | - region.top = top; | |
| 302 | - region.right = right; | |
| 303 | - region.bottom = bottom; | |
| 304 | - | |
| 305 | - // 90度或者270度旋转 | |
| 306 | - if (rotation % 180 == 90) { | |
| 307 | - int x = decoder.getWidth() / 2; | |
| 308 | - int y = decoder.getHeight() / 2; | |
| 309 | - | |
| 310 | - int rotatedWidth = region.height(); | |
| 311 | - int rotated = region.width(); | |
| 312 | - | |
| 313 | - // 计算,裁剪框旋转后的坐标 | |
| 314 | - region.left = x - rotatedWidth / 2; | |
| 315 | - region.top = y - rotated / 2; | |
| 316 | - region.right = x + rotatedWidth / 2; | |
| 317 | - region.bottom = y + rotated / 2; | |
| 318 | - region.sort(); | |
| 319 | - } | |
| 320 | - | |
| 321 | - BitmapFactory.Options options = new BitmapFactory.Options(); | |
| 322 | - | |
| 323 | - // 最大图片大小。 | |
| 324 | - int maxPreviewImageSize = 2560; | |
| 325 | - int size = Math.min(decoder.getWidth(), decoder.getHeight()); | |
| 326 | - size = Math.min(size, maxPreviewImageSize); | |
| 327 | - | |
| 328 | - options.inSampleSize = ImageUtil.calculateInSampleSize(options, size, size); | |
| 329 | - options.inScaled = true; | |
| 330 | - options.inDensity = Math.max(options.outWidth, options.outHeight); | |
| 331 | - options.inTargetDensity = size; | |
| 332 | - options.inPreferredConfig = Bitmap.Config.RGB_565; | |
| 333 | - | |
| 334 | - Bitmap bitmap = decoder.decodeRegion(region, options); | |
| 335 | - | |
| 336 | - if (rotation != 0) { | |
| 337 | - // 只能是裁剪完之后再旋转了。有没有别的更好的方案呢? | |
| 338 | - Matrix matrix = new Matrix(); | |
| 339 | - matrix.postRotate(rotation); | |
| 340 | - Bitmap rotatedBitmap = Bitmap.createBitmap( | |
| 341 | - bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); | |
| 342 | - if (bitmap != rotatedBitmap) { | |
| 343 | - // 有时候 createBitmap会复用对象 | |
| 344 | - bitmap.recycle(); | |
| 345 | - } | |
| 346 | - bitmap = rotatedBitmap; | |
| 347 | - } | |
| 348 | - | |
| 349 | - final int status; | |
| 350 | - | |
| 351 | - // 调用本地质量控制请求 | |
| 352 | - switch (maskType) { | |
| 353 | - case MaskView.MASK_TYPE_ID_CARD_FRONT: | |
| 354 | - status = IDcardQualityProcess.getInstance().idcardQualityDetectionImg(bitmap, true); | |
| 355 | - break; | |
| 356 | - case MaskView.MASK_TYPE_ID_CARD_BACK: | |
| 357 | - status = IDcardQualityProcess.getInstance().idcardQualityDetectionImg(bitmap, false); | |
| 358 | - break; | |
| 359 | - default: | |
| 360 | - status = 1; | |
| 361 | - } | |
| 362 | - | |
| 363 | - // 当有某个扫描处理线程调用成功后,阻止其他线程继续调用本地控制代码 | |
| 364 | - if (status == SCAN_SUCCESS) { | |
| 365 | - // 扫描成功阻止多线程同时回调 | |
| 366 | - if (!cameraControl.getAbortingScan().compareAndSet(false, true)) { | |
| 367 | - bitmap.recycle(); | |
| 368 | - return 0; | |
| 369 | - } | |
| 370 | - autoPictureCallback.onPictureTaken(bitmap); | |
| 371 | - } | |
| 372 | - | |
| 373 | - showTipMessage(status); | |
| 374 | - | |
| 375 | - return status; | |
| 376 | - } | |
| 377 | - | |
| 378 | - private void showTipMessage(final int status) { | |
| 379 | - // 提示tip文字变化 | |
| 380 | - uiHandler.post(new Runnable() { | |
| 381 | - @Override | |
| 382 | - public void run() { | |
| 383 | - if (status == 0) { | |
| 384 | - hintViewText.setVisibility(View.INVISIBLE); | |
| 385 | - } else if (!cameraControl.getAbortingScan().get()) { | |
| 386 | - hintViewText.setVisibility(View.VISIBLE); | |
| 387 | - hintViewText.setText(getScanMessage(status)); | |
| 388 | - } | |
| 389 | - } | |
| 390 | - }); | |
| 391 | - } | |
| 392 | - | |
| 393 | - private String getScanMessage(int status) { | |
| 394 | - String message; | |
| 395 | - switch (status) { | |
| 396 | - case 0: | |
| 397 | - message = ""; | |
| 398 | - break; | |
| 399 | - case 2: | |
| 400 | - message = "身份证模糊,请重新尝试"; | |
| 401 | - break; | |
| 402 | - case 3: | |
| 403 | - message = "身份证反光,请重新尝试"; | |
| 404 | - break; | |
| 405 | - case 4: | |
| 406 | - message = "请将身份证前后反转再进行识别"; | |
| 407 | - break; | |
| 408 | - case 5: | |
| 409 | - message = "请拿稳镜头和身份证"; | |
| 410 | - break; | |
| 411 | - case 6: | |
| 412 | - message = "请将镜头靠近身份证"; | |
| 413 | - break; | |
| 414 | - case 7: | |
| 415 | - message = "请将身份证完整置于取景框内"; | |
| 416 | - break; | |
| 417 | - case NATIVE_AUTH_FAIL: | |
| 418 | - message = "本地质量控制授权失败"; | |
| 419 | - break; | |
| 420 | - case NATIVE_INIT_FAIL: | |
| 421 | - message = "本地模型加载失败"; | |
| 422 | - break; | |
| 423 | - case NATIVE_SOLOAD_FAIL: | |
| 424 | - message = "本地SO库加载失败"; | |
| 425 | - break; | |
| 426 | - case 1: | |
| 427 | - default: | |
| 428 | - message = "请将身份证置于取景框内"; | |
| 429 | - } | |
| 430 | - | |
| 431 | - | |
| 432 | - return message; | |
| 433 | - } | |
| 434 | - | |
| 435 | - private void init() { | |
| 436 | -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
| 437 | -// cameraControl = new Camera2Control(getContext()); | |
| 438 | -// } else { | |
| 439 | -// | |
| 440 | -// } | |
| 441 | - cameraControl = new Camera1Control(getContext()); | |
| 442 | - | |
| 443 | - displayView = cameraControl.getDisplayView(); | |
| 444 | - addView(displayView); | |
| 445 | - | |
| 446 | - maskView = new MaskView(getContext()); | |
| 447 | - addView(maskView); | |
| 448 | - | |
| 449 | - hintView = new ImageView(getContext()); | |
| 450 | - addView(hintView); | |
| 451 | - | |
| 452 | - hintViewTextWrapper = new LinearLayout(getContext()); | |
| 453 | - hintViewTextWrapper.setOrientation(LinearLayout.VERTICAL); | |
| 454 | - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, | |
| 455 | - PxUtil.dp2px(25)); | |
| 456 | - | |
| 457 | - lp.gravity = Gravity.CENTER; | |
| 458 | - hintViewText = new TextView(getContext()); | |
| 459 | - hintViewText.setBackgroundResource(R.drawable.bd_ocr_round_corner); | |
| 460 | - hintViewText.setAlpha(0.5f); | |
| 461 | - hintViewText.setPadding(PxUtil.dp2px(10), 0, PxUtil.dp2px(10), 0); | |
| 462 | - hintViewTextWrapper.addView(hintViewText, lp); | |
| 463 | - | |
| 464 | - | |
| 465 | - hintViewText.setGravity(Gravity.CENTER); | |
| 466 | - hintViewText.setTextColor(Color.WHITE); | |
| 467 | - hintViewText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); | |
| 468 | - hintViewText.setText(getScanMessage(-1)); | |
| 469 | - | |
| 470 | - | |
| 471 | - addView(hintViewTextWrapper, lp); | |
| 472 | - } | |
| 473 | - | |
| 474 | - @Override | |
| 475 | - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | |
| 476 | - displayView.layout(left, 0, right, bottom - top); | |
| 477 | - maskView.layout(left, 0, right, bottom - top); | |
| 478 | - | |
| 479 | - int hintViewWidth = PxUtil.dp2px(250); | |
| 480 | - int hintViewHeight = PxUtil.dp2px(25); | |
| 481 | - | |
| 482 | - int hintViewLeft = (getWidth() - hintViewWidth) / 2; | |
| 483 | - int hintViewTop = maskView.getFrameRect().bottom + PxUtil.dp2px(16); | |
| 484 | - | |
| 485 | - hintViewTextWrapper.layout(hintViewLeft, hintViewTop, | |
| 486 | - hintViewLeft + hintViewWidth, hintViewTop + hintViewHeight); | |
| 487 | - | |
| 488 | - hintView.layout(hintViewLeft, hintViewTop, | |
| 489 | - hintViewLeft + hintViewWidth, hintViewTop + hintViewHeight); | |
| 490 | - } | |
| 491 | - | |
| 492 | - /** | |
| 493 | - * 拍摄后的照片。需要进行裁剪。有些手机(比如三星)不会对照片数据进行旋转,而是将旋转角度写入EXIF信息当中, | |
| 494 | - * 所以需要做旋转处理。 | |
| 495 | - * | |
| 496 | - * @param outputFile 写入照片的文件。 | |
| 497 | - * @param data 原始照片数据。 | |
| 498 | - * @param rotation 照片exif中的旋转角度。 | |
| 499 | - * @return 裁剪好的bitmap。 | |
| 500 | - */ | |
| 501 | - @SuppressWarnings("ResultOfMethodCallIgnored") | |
| 502 | - private Bitmap crop(File outputFile, byte[] data, int rotation) { | |
| 503 | - try { | |
| 504 | - // BitmapRegionDecoder不会将整个图片加载到内存。 | |
| 505 | - BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(data, 0, data.length, true); | |
| 506 | - | |
| 507 | - Rect previewFrame = cameraControl.getPreviewFrame(); | |
| 508 | - | |
| 509 | - int width = rotation % 180 == 0 ? decoder.getWidth() : decoder.getHeight(); | |
| 510 | - int height = rotation % 180 == 0 ? decoder.getHeight() : decoder.getWidth(); | |
| 511 | - | |
| 512 | - Rect frameRect = maskView.getFrameRect(); | |
| 513 | - | |
| 514 | - int left = width * frameRect.left / maskView.getWidth(); | |
| 515 | - int top = height * frameRect.top / maskView.getHeight(); | |
| 516 | - int right = width * frameRect.right / maskView.getWidth(); | |
| 517 | - int bottom = height * frameRect.bottom / maskView.getHeight(); | |
| 518 | - | |
| 519 | - // 高度大于图片 | |
| 520 | - if (previewFrame.top < 0) { | |
| 521 | - // 宽度对齐。 | |
| 522 | - int adjustedPreviewHeight = previewFrame.height() * getWidth() / previewFrame.width(); | |
| 523 | - int topInFrame = ((adjustedPreviewHeight - frameRect.height()) / 2) | |
| 524 | - * getWidth() / previewFrame.width(); | |
| 525 | - int bottomInFrame = ((adjustedPreviewHeight + frameRect.height()) / 2) * getWidth() | |
| 526 | - / previewFrame.width(); | |
| 527 | - | |
| 528 | - // 等比例投射到照片当中。 | |
| 529 | - top = topInFrame * height / previewFrame.height(); | |
| 530 | - bottom = bottomInFrame * height / previewFrame.height(); | |
| 531 | - } else { | |
| 532 | - // 宽度大于图片 | |
| 533 | - if (previewFrame.left < 0) { | |
| 534 | - // 高度对齐 | |
| 535 | - int adjustedPreviewWidth = previewFrame.width() * getHeight() / previewFrame.height(); | |
| 536 | - int leftInFrame = ((adjustedPreviewWidth - maskView.getFrameRect().width()) / 2) * getHeight() | |
| 537 | - / previewFrame.height(); | |
| 538 | - int rightInFrame = ((adjustedPreviewWidth + maskView.getFrameRect().width()) / 2) * getHeight() | |
| 539 | - / previewFrame.height(); | |
| 540 | - | |
| 541 | - // 等比例投射到照片当中。 | |
| 542 | - left = leftInFrame * width / previewFrame.width(); | |
| 543 | - right = rightInFrame * width / previewFrame.width(); | |
| 544 | - } | |
| 545 | - } | |
| 546 | - | |
| 547 | - Rect region = new Rect(); | |
| 548 | - region.left = left; | |
| 549 | - region.top = top; | |
| 550 | - region.right = right; | |
| 551 | - region.bottom = bottom; | |
| 552 | - | |
| 553 | - // 90度或者270度旋转 | |
| 554 | - if (rotation % 180 == 90) { | |
| 555 | - int x = decoder.getWidth() / 2; | |
| 556 | - int y = decoder.getHeight() / 2; | |
| 557 | - | |
| 558 | - int rotatedWidth = region.height(); | |
| 559 | - int rotated = region.width(); | |
| 560 | - | |
| 561 | - // 计算,裁剪框旋转后的坐标 | |
| 562 | - region.left = x - rotatedWidth / 2; | |
| 563 | - region.top = y - rotated / 2; | |
| 564 | - region.right = x + rotatedWidth / 2; | |
| 565 | - region.bottom = y + rotated / 2; | |
| 566 | - region.sort(); | |
| 567 | - } | |
| 568 | - | |
| 569 | - BitmapFactory.Options options = new BitmapFactory.Options(); | |
| 570 | - | |
| 571 | - // 最大图片大小。 | |
| 572 | - int maxPreviewImageSize = 2560; | |
| 573 | - int size = Math.min(decoder.getWidth(), decoder.getHeight()); | |
| 574 | - size = Math.min(size, maxPreviewImageSize); | |
| 575 | - | |
| 576 | - options.inSampleSize = ImageUtil.calculateInSampleSize(options, size, size); | |
| 577 | - options.inScaled = true; | |
| 578 | - options.inDensity = Math.max(options.outWidth, options.outHeight); | |
| 579 | - options.inTargetDensity = size; | |
| 580 | - options.inPreferredConfig = Bitmap.Config.RGB_565; | |
| 581 | - Bitmap bitmap = decoder.decodeRegion(region, options); | |
| 582 | - | |
| 583 | - if (rotation != 0) { | |
| 584 | - // 只能是裁剪完之后再旋转了。有没有别的更好的方案呢? | |
| 585 | - Matrix matrix = new Matrix(); | |
| 586 | - matrix.postRotate(rotation); | |
| 587 | - Bitmap rotatedBitmap = Bitmap.createBitmap( | |
| 588 | - bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); | |
| 589 | - if (bitmap != rotatedBitmap) { | |
| 590 | - // 有时候 createBitmap会复用对象 | |
| 591 | - bitmap.recycle(); | |
| 592 | - } | |
| 593 | - bitmap = rotatedBitmap; | |
| 594 | - } | |
| 595 | - | |
| 596 | - try { | |
| 597 | - if (!outputFile.exists()) { | |
| 598 | - outputFile.createNewFile(); | |
| 599 | - } | |
| 600 | - FileOutputStream fileOutputStream = new FileOutputStream(outputFile); | |
| 601 | - bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream); | |
| 602 | - fileOutputStream.flush(); | |
| 603 | - fileOutputStream.close(); | |
| 604 | - return bitmap; | |
| 605 | - } catch (IOException e) { | |
| 606 | - if (e!=null) | |
| 607 | - e.printStackTrace(); | |
| 608 | - } | |
| 609 | - } catch (IOException e) { | |
| 610 | - if (e!=null) | |
| 611 | - e.printStackTrace(); | |
| 612 | - } | |
| 613 | - return null; | |
| 614 | - } | |
| 615 | - | |
| 616 | - public void release() { | |
| 617 | - IDcardQualityProcess.getInstance().releaseModel(); | |
| 618 | - } | |
| 619 | - | |
| 620 | - private class CameraViewTakePictureCallback implements ICameraControl.OnTakePictureCallback { | |
| 621 | - | |
| 622 | - private File file; | |
| 623 | - private OnTakePictureCallback callback; | |
| 624 | - | |
| 625 | - @Override | |
| 626 | - public void onPictureTaken(final byte[] data) { | |
| 627 | - CameraThreadPool.execute(new Runnable() { | |
| 628 | - @Override | |
| 629 | - public void run() { | |
| 630 | - final int rotation = ImageUtil.getOrientation(data); | |
| 631 | - Bitmap bitmap = crop(file, data, rotation); | |
| 632 | - callback.onPictureTaken(bitmap); | |
| 633 | - } | |
| 634 | - }); | |
| 635 | - } | |
| 636 | - } | |
| 637 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/ICameraControl.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | -import android.graphics.Rect; | |
| 7 | -import android.view.View; | |
| 8 | - | |
| 9 | -import java.util.concurrent.atomic.AtomicBoolean; | |
| 10 | - | |
| 11 | -import androidx.annotation.IntDef; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * Android 5.0 相机的API发生很大的变化。些类屏蔽掉了 api的变化。相机的操作和功能,抽象剥离出来。 | |
| 15 | - */ | |
| 16 | -public interface ICameraControl { | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * 闪光灯关 {@link #setFlashMode(int)} | |
| 20 | - */ | |
| 21 | - int FLASH_MODE_OFF = 0; | |
| 22 | - /** | |
| 23 | - * 闪光灯开 {@link #setFlashMode(int)} | |
| 24 | - */ | |
| 25 | - int FLASH_MODE_TORCH = 1; | |
| 26 | - /** | |
| 27 | - * 闪光灯自动 {@link #setFlashMode(int)} | |
| 28 | - */ | |
| 29 | - int FLASH_MODE_AUTO = 2; | |
| 30 | - | |
| 31 | - @IntDef({FLASH_MODE_TORCH, FLASH_MODE_OFF, FLASH_MODE_AUTO}) | |
| 32 | - @interface FlashMode { | |
| 33 | - | |
| 34 | - } | |
| 35 | - | |
| 36 | - /** | |
| 37 | - * 照相回调。 | |
| 38 | - */ | |
| 39 | - interface OnTakePictureCallback { | |
| 40 | - void onPictureTaken(byte[] data); | |
| 41 | - } | |
| 42 | - | |
| 43 | - /** | |
| 44 | - * 设置本地质量控制回调,如果不设置则视为不扫描调用本地质量控制代码。 | |
| 45 | - */ | |
| 46 | - void setDetectCallback(OnDetectPictureCallback callback); | |
| 47 | - | |
| 48 | - /** | |
| 49 | - * 预览回调 | |
| 50 | - */ | |
| 51 | - interface OnDetectPictureCallback { | |
| 52 | - int onDetect(byte[] data, int rotation); | |
| 53 | - } | |
| 54 | - | |
| 55 | - /** | |
| 56 | - * 打开相机。 | |
| 57 | - */ | |
| 58 | - void start(); | |
| 59 | - | |
| 60 | - /** | |
| 61 | - * 关闭相机 | |
| 62 | - */ | |
| 63 | - void stop(); | |
| 64 | - | |
| 65 | - void pause(); | |
| 66 | - | |
| 67 | - void resume(); | |
| 68 | - | |
| 69 | - /** | |
| 70 | - * 相机对应的预览视图。 | |
| 71 | - * @return 预览视图 | |
| 72 | - */ | |
| 73 | - View getDisplayView(); | |
| 74 | - | |
| 75 | - /** | |
| 76 | - * 看到的预览可能不是照片的全部。返回预览视图的全貌。 | |
| 77 | - * @return 预览视图frame; | |
| 78 | - */ | |
| 79 | - Rect getPreviewFrame(); | |
| 80 | - | |
| 81 | - /** | |
| 82 | - * 拍照。结果在回调中获取。 | |
| 83 | - * @param callback 拍照结果回调 | |
| 84 | - */ | |
| 85 | - void takePicture(OnTakePictureCallback callback); | |
| 86 | - | |
| 87 | - /** | |
| 88 | - * 设置权限回调,当手机没有拍照权限时,可在回调中获取。 | |
| 89 | - * @param callback 权限回调 | |
| 90 | - */ | |
| 91 | - void setPermissionCallback(PermissionCallback callback); | |
| 92 | - | |
| 93 | - /** | |
| 94 | - * 设置水平方向 | |
| 95 | - * @param displayOrientation 参数值见 {@link com.cnlive.ocr.ui.camera.CameraView.Orientation} | |
| 96 | - */ | |
| 97 | - void setDisplayOrientation(@CameraView.Orientation int displayOrientation); | |
| 98 | - | |
| 99 | - /** | |
| 100 | - * 获取到拍照权限时,调用些函数以继续。 | |
| 101 | - */ | |
| 102 | - void refreshPermission(); | |
| 103 | - | |
| 104 | - /** | |
| 105 | - * 获取已经扫描成功,处理中 | |
| 106 | - */ | |
| 107 | - AtomicBoolean getAbortingScan(); | |
| 108 | - | |
| 109 | - /** | |
| 110 | - * 设置闪光灯状态。 | |
| 111 | - * @param flashMode {@link #FLASH_MODE_TORCH,#FLASH_MODE_OFF,#FLASH_MODE_AUTO} | |
| 112 | - */ | |
| 113 | - void setFlashMode(@FlashMode int flashMode); | |
| 114 | - | |
| 115 | - /** | |
| 116 | - * 获取当前闪光灯状态 | |
| 117 | - * @return 当前闪光灯状态 参见 {@link #setFlashMode(int)} | |
| 118 | - */ | |
| 119 | - @FlashMode | |
| 120 | - int getFlashMode(); | |
| 121 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/MaskView.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | -import android.content.Context; | |
| 7 | -import android.graphics.Canvas; | |
| 8 | -import android.graphics.Color; | |
| 9 | -import android.graphics.Paint; | |
| 10 | -import android.graphics.Path; | |
| 11 | -import android.graphics.PorterDuff; | |
| 12 | -import android.graphics.PorterDuffXfermode; | |
| 13 | -import android.graphics.Rect; | |
| 14 | -import android.graphics.drawable.Drawable; | |
| 15 | -import android.os.Build; | |
| 16 | -import android.util.AttributeSet; | |
| 17 | -import android.view.View; | |
| 18 | - | |
| 19 | -import com.cnlive.core.people_verfication.R; | |
| 20 | - | |
| 21 | -import java.io.File; | |
| 22 | - | |
| 23 | -import androidx.annotation.IntDef; | |
| 24 | -import androidx.annotation.RequiresApi; | |
| 25 | -import androidx.core.content.res.ResourcesCompat; | |
| 26 | - | |
| 27 | -@SuppressWarnings("unused") | |
| 28 | -public class MaskView extends View { | |
| 29 | - | |
| 30 | - public static final int MASK_TYPE_NONE = 0; | |
| 31 | - public static final int MASK_TYPE_ID_CARD_FRONT = 1; | |
| 32 | - public static final int MASK_TYPE_ID_CARD_BACK = 2; | |
| 33 | - public static final int MASK_TYPE_BANK_CARD = 11; | |
| 34 | - public static final int MASK_TYPE_AVATAR = 12; | |
| 35 | - | |
| 36 | - @IntDef({MASK_TYPE_NONE, MASK_TYPE_ID_CARD_FRONT, MASK_TYPE_ID_CARD_BACK, MASK_TYPE_BANK_CARD, MASK_TYPE_AVATAR}) | |
| 37 | - @interface MaskType { | |
| 38 | - | |
| 39 | - } | |
| 40 | - | |
| 41 | - public void setLineColor(int lineColor) { | |
| 42 | - this.lineColor = lineColor; | |
| 43 | - } | |
| 44 | - | |
| 45 | - public void setMaskColor(int maskColor) { | |
| 46 | - this.maskColor = maskColor; | |
| 47 | - } | |
| 48 | - | |
| 49 | - private int lineColor = Color.WHITE; | |
| 50 | - | |
| 51 | - private int maskType = MASK_TYPE_ID_CARD_FRONT; | |
| 52 | - | |
| 53 | - private int maskColor = Color.argb(100, 0, 0, 0); | |
| 54 | - | |
| 55 | - private Paint eraser = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 56 | - private Paint pen = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 57 | - | |
| 58 | - private Rect frame = new Rect(); | |
| 59 | - | |
| 60 | - private Drawable locatorDrawable; | |
| 61 | - | |
| 62 | - public Rect getFrameRect() { | |
| 63 | - if (maskType == MASK_TYPE_NONE) { | |
| 64 | - return new Rect(0, 0, getWidth(), getHeight()); | |
| 65 | - } else { | |
| 66 | - return new Rect(frame); | |
| 67 | - } | |
| 68 | - | |
| 69 | - } | |
| 70 | - | |
| 71 | - public Rect getFrameRectExtend() { | |
| 72 | - Rect rc = new Rect(frame); | |
| 73 | - int widthExtend = (int) ((frame.right - frame.left) * 0.02f); | |
| 74 | - int heightExtend = (int) ((frame.bottom - frame.top) * 0.02f); | |
| 75 | - rc.left -= widthExtend; | |
| 76 | - rc.right += widthExtend; | |
| 77 | - rc.top -= heightExtend; | |
| 78 | - rc.bottom += heightExtend; | |
| 79 | - return rc; | |
| 80 | - } | |
| 81 | - | |
| 82 | - public void setMaskType(@MaskType int maskType) { | |
| 83 | - this.maskType = maskType; | |
| 84 | - switch (maskType) { | |
| 85 | - case MASK_TYPE_ID_CARD_FRONT: | |
| 86 | - locatorDrawable = ResourcesCompat.getDrawable(getResources(), | |
| 87 | - R.drawable.bd_ocr_id_card_locator_front, null); | |
| 88 | - break; | |
| 89 | - case MASK_TYPE_ID_CARD_BACK: | |
| 90 | - locatorDrawable = ResourcesCompat.getDrawable(getResources(), | |
| 91 | - R.drawable.bd_ocr_id_card_locator_back, null); | |
| 92 | - break; | |
| 93 | - case MASK_TYPE_BANK_CARD: | |
| 94 | - break; | |
| 95 | - case MASK_TYPE_AVATAR: | |
| 96 | - break; | |
| 97 | - case MASK_TYPE_NONE: | |
| 98 | - default: | |
| 99 | - break; | |
| 100 | - } | |
| 101 | - invalidate(); | |
| 102 | - } | |
| 103 | - | |
| 104 | - public int getMaskType() { | |
| 105 | - return maskType; | |
| 106 | - } | |
| 107 | - | |
| 108 | - public void setOrientation(@CameraView.Orientation int orientation) { | |
| 109 | - } | |
| 110 | - | |
| 111 | - public MaskView(Context context) { | |
| 112 | - super(context); | |
| 113 | - init(); | |
| 114 | - } | |
| 115 | - | |
| 116 | - public MaskView(Context context, AttributeSet attrs) { | |
| 117 | - super(context, attrs); | |
| 118 | - init(); | |
| 119 | - } | |
| 120 | - | |
| 121 | - public MaskView(Context context, AttributeSet attrs, int defStyleAttr) { | |
| 122 | - super(context, attrs, defStyleAttr); | |
| 123 | - init(); | |
| 124 | - } | |
| 125 | - | |
| 126 | - private void init() { | |
| 127 | - locatorDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.bd_ocr_id_card_locator_front, null); | |
| 128 | - } | |
| 129 | - | |
| 130 | - @Override | |
| 131 | - protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
| 132 | - super.onSizeChanged(w, h, oldw, oldh); | |
| 133 | - if (w > 0 && h > 0) { | |
| 134 | - float ratio = h > w ? 0.9f : 0.72f; | |
| 135 | - | |
| 136 | - int width = (int) (w * ratio); | |
| 137 | - int height; | |
| 138 | - if (maskType == MASK_TYPE_AVATAR) { | |
| 139 | - height = width; | |
| 140 | - } else { | |
| 141 | - height = width * 400 / 620; | |
| 142 | - } | |
| 143 | - | |
| 144 | - int left = (w - width) / 2; | |
| 145 | - int top = (h - height) / 2; | |
| 146 | - int right = width + left; | |
| 147 | - int bottom = height + top; | |
| 148 | - | |
| 149 | - frame.left = left; | |
| 150 | - frame.top = top; | |
| 151 | - frame.right = right; | |
| 152 | - frame.bottom = bottom; | |
| 153 | - | |
| 154 | - } | |
| 155 | - } | |
| 156 | - | |
| 157 | - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) | |
| 158 | - @Override | |
| 159 | - protected void onDraw(Canvas canvas) { | |
| 160 | - super.onDraw(canvas); | |
| 161 | - | |
| 162 | - int width = frame.width(); | |
| 163 | - int height = frame.height(); | |
| 164 | - | |
| 165 | - int left = frame.left; | |
| 166 | - int top = frame.top; | |
| 167 | - int right = frame.right; | |
| 168 | - int bottom = frame.bottom; | |
| 169 | - | |
| 170 | - canvas.drawColor(maskColor); | |
| 171 | - fillRectRound(left, top, right, bottom, 30, 30, false); | |
| 172 | - canvas.drawPath(path, pen); | |
| 173 | - canvas.drawPath(path, eraser); | |
| 174 | - | |
| 175 | - if (maskType == MASK_TYPE_ID_CARD_FRONT) { | |
| 176 | - locatorDrawable.setBounds( | |
| 177 | - (int) (left + 601f / 1006 * width), | |
| 178 | - (int) (top + (110f / 632) * height), | |
| 179 | - (int) (left + (963f / 1006) * width), | |
| 180 | - (int) (top + (476f / 632) * height)); | |
| 181 | - } else if (maskType == MASK_TYPE_ID_CARD_BACK) { | |
| 182 | - locatorDrawable.setBounds( | |
| 183 | - (int) (left + 51f / 1006 * width), | |
| 184 | - (int) (top + (48f / 632) * height), | |
| 185 | - (int) (left + (250f / 1006) * width), | |
| 186 | - (int) (top + (262f / 632) * height)); | |
| 187 | - } | |
| 188 | - if (locatorDrawable != null) { | |
| 189 | - locatorDrawable.draw(canvas); | |
| 190 | - } | |
| 191 | - } | |
| 192 | - | |
| 193 | - private Path path = new Path(); | |
| 194 | - | |
| 195 | - private Path fillRectRound(float left, float top, float right, float bottom, float rx, float ry, boolean | |
| 196 | - conformToOriginalPost) { | |
| 197 | - | |
| 198 | - path.reset(); | |
| 199 | - if (rx < 0) { | |
| 200 | - rx = 0; | |
| 201 | - } | |
| 202 | - if (ry < 0) { | |
| 203 | - ry = 0; | |
| 204 | - } | |
| 205 | - float width = right - left; | |
| 206 | - float height = bottom - top; | |
| 207 | - if (rx > width / 2) { | |
| 208 | - rx = width / 2; | |
| 209 | - } | |
| 210 | - if (ry > height / 2) { | |
| 211 | - ry = height / 2; | |
| 212 | - } | |
| 213 | - float widthMinusCorners = (width - (2 * rx)); | |
| 214 | - float heightMinusCorners = (height - (2 * ry)); | |
| 215 | - | |
| 216 | - path.moveTo(right, top + ry); | |
| 217 | - path.rQuadTo(0, -ry, -rx, -ry); | |
| 218 | - path.rLineTo(-widthMinusCorners, 0); | |
| 219 | - path.rQuadTo(-rx, 0, -rx, ry); | |
| 220 | - path.rLineTo(0, heightMinusCorners); | |
| 221 | - | |
| 222 | - if (conformToOriginalPost) { | |
| 223 | - path.rLineTo(0, ry); | |
| 224 | - path.rLineTo(width, 0); | |
| 225 | - path.rLineTo(0, -ry); | |
| 226 | - } else { | |
| 227 | - path.rQuadTo(0, ry, rx, ry); | |
| 228 | - path.rLineTo(widthMinusCorners, 0); | |
| 229 | - path.rQuadTo(rx, 0, rx, -ry); | |
| 230 | - } | |
| 231 | - | |
| 232 | - path.rLineTo(0, -heightMinusCorners); | |
| 233 | - path.close(); | |
| 234 | - return path; | |
| 235 | - } | |
| 236 | - | |
| 237 | - { | |
| 238 | - // 硬件加速不支持,图层混合。 | |
| 239 | - setLayerType(View.LAYER_TYPE_SOFTWARE, null); | |
| 240 | - | |
| 241 | - pen.setColor(Color.WHITE); | |
| 242 | - pen.setStyle(Paint.Style.STROKE); | |
| 243 | - pen.setStrokeWidth(6); | |
| 244 | - | |
| 245 | - eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); | |
| 246 | - } | |
| 247 | - | |
| 248 | - private void capture(File file) { | |
| 249 | - | |
| 250 | - } | |
| 251 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/OCRCameraLayout.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | -import android.content.Context; | |
| 7 | -import android.content.res.TypedArray; | |
| 8 | -import android.graphics.Canvas; | |
| 9 | -import android.graphics.Color; | |
| 10 | -import android.graphics.Paint; | |
| 11 | -import android.graphics.Rect; | |
| 12 | -import android.util.AttributeSet; | |
| 13 | -import android.view.View; | |
| 14 | -import android.widget.FrameLayout; | |
| 15 | - | |
| 16 | -import com.cnlive.core.people_verfication.R; | |
| 17 | - | |
| 18 | - | |
| 19 | -public class OCRCameraLayout extends FrameLayout { | |
| 20 | - | |
| 21 | - public static int ORIENTATION_PORTRAIT = 0; | |
| 22 | - public static int ORIENTATION_HORIZONTAL = 1; | |
| 23 | - | |
| 24 | - private int orientation = ORIENTATION_PORTRAIT; | |
| 25 | - private View contentView; | |
| 26 | - private View centerView; | |
| 27 | - private View leftDownView; | |
| 28 | - private View rightUpView; | |
| 29 | - | |
| 30 | - private int contentViewId; | |
| 31 | - private int centerViewId; | |
| 32 | - private int leftDownViewId; | |
| 33 | - private int rightUpViewId; | |
| 34 | - | |
| 35 | - public void setOrientation(int orientation) { | |
| 36 | - if (this.orientation == orientation) { | |
| 37 | - return; | |
| 38 | - } | |
| 39 | - this.orientation = orientation; | |
| 40 | - requestLayout(); | |
| 41 | - } | |
| 42 | - | |
| 43 | - public OCRCameraLayout(Context context) { | |
| 44 | - super(context); | |
| 45 | - } | |
| 46 | - | |
| 47 | - public OCRCameraLayout(Context context, AttributeSet attrs) { | |
| 48 | - super(context, attrs); | |
| 49 | - parseAttrs(attrs); | |
| 50 | - } | |
| 51 | - | |
| 52 | - public OCRCameraLayout(Context context, AttributeSet attrs, int defStyleAttr) { | |
| 53 | - super(context, attrs, defStyleAttr); | |
| 54 | - parseAttrs(attrs); | |
| 55 | - } | |
| 56 | - | |
| 57 | - { | |
| 58 | - setWillNotDraw(false); | |
| 59 | - } | |
| 60 | - | |
| 61 | - private void parseAttrs(AttributeSet attrs) { | |
| 62 | - TypedArray a = getContext().getTheme().obtainStyledAttributes( | |
| 63 | - attrs, | |
| 64 | - R.styleable.OCRCameraLayout, | |
| 65 | - 0, 0); | |
| 66 | - try { | |
| 67 | - contentViewId = a.getResourceId(R.styleable.OCRCameraLayout_contentView, -1); | |
| 68 | - centerViewId = a.getResourceId(R.styleable.OCRCameraLayout_centerView, -1); | |
| 69 | - leftDownViewId = a.getResourceId(R.styleable.OCRCameraLayout_leftDownView, -1); | |
| 70 | - rightUpViewId = a.getResourceId(R.styleable.OCRCameraLayout_rightUpView, -1); | |
| 71 | - } finally { | |
| 72 | - a.recycle(); | |
| 73 | - } | |
| 74 | - } | |
| 75 | - | |
| 76 | - @Override | |
| 77 | - protected void onAttachedToWindow() { | |
| 78 | - super.onAttachedToWindow(); | |
| 79 | - contentView = findViewById(contentViewId); | |
| 80 | - if (centerViewId != -1) { | |
| 81 | - centerView = findViewById(centerViewId); | |
| 82 | - } | |
| 83 | - leftDownView = findViewById(leftDownViewId); | |
| 84 | - rightUpView = findViewById(rightUpViewId); | |
| 85 | - } | |
| 86 | - | |
| 87 | - private Rect backgroundRect = new Rect(); | |
| 88 | - private Paint paint = new Paint(); | |
| 89 | - | |
| 90 | - { | |
| 91 | - paint.setStyle(Paint.Style.FILL); | |
| 92 | - paint.setColor(Color.argb(83, 0, 0, 0)); | |
| 93 | - } | |
| 94 | - | |
| 95 | - @Override | |
| 96 | - protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
| 97 | - int width = getWidth(); | |
| 98 | - int height = getHeight(); | |
| 99 | - int left; | |
| 100 | - int top; | |
| 101 | - | |
| 102 | - MarginLayoutParams leftDownViewLayoutParams = (MarginLayoutParams) leftDownView.getLayoutParams(); | |
| 103 | - MarginLayoutParams rightUpViewLayoutParams = (MarginLayoutParams) rightUpView.getLayoutParams(); | |
| 104 | - if (r < b) { | |
| 105 | - int contentHeight = width * 4 / 3; | |
| 106 | - int heightLeft = height - contentHeight; | |
| 107 | - contentView.layout(l, t, r, contentHeight); | |
| 108 | - | |
| 109 | - backgroundRect.left = 0; | |
| 110 | - backgroundRect.top = contentHeight; | |
| 111 | - backgroundRect.right = width; | |
| 112 | - backgroundRect.bottom = height; | |
| 113 | - | |
| 114 | - // layout centerView; | |
| 115 | - if (centerView != null) { | |
| 116 | - left = (width - centerView.getMeasuredWidth()) / 2; | |
| 117 | - top = contentHeight + (heightLeft - centerView.getMeasuredHeight()) / 2; | |
| 118 | - centerView | |
| 119 | - .layout(left, top, left + centerView.getMeasuredWidth(), top + centerView.getMeasuredHeight()); | |
| 120 | - } | |
| 121 | - // layout leftDownView | |
| 122 | - | |
| 123 | - left = leftDownViewLayoutParams.leftMargin; | |
| 124 | - top = contentHeight + (heightLeft - leftDownView.getMeasuredHeight()) / 2; | |
| 125 | - leftDownView | |
| 126 | - .layout(left, top, left + leftDownView.getMeasuredWidth(), top + leftDownView.getMeasuredHeight()); | |
| 127 | - // layout rightUpView | |
| 128 | - left = width - rightUpView.getMeasuredWidth() - rightUpViewLayoutParams.rightMargin; | |
| 129 | - top = contentHeight + (heightLeft - rightUpView.getMeasuredHeight()) / 2; | |
| 130 | - rightUpView.layout(left, top, left + rightUpView.getMeasuredWidth(), top + rightUpView.getMeasuredHeight()); | |
| 131 | - } else { | |
| 132 | - int contentWidth = height * 4 / 3; | |
| 133 | - int widthLeft = width - contentWidth; | |
| 134 | - contentView.layout(l, t, contentWidth, height); | |
| 135 | - | |
| 136 | - backgroundRect.left = contentWidth; | |
| 137 | - backgroundRect.top = 0; | |
| 138 | - backgroundRect.right = width; | |
| 139 | - backgroundRect.bottom = height; | |
| 140 | - | |
| 141 | - // layout centerView | |
| 142 | - if (centerView != null) { | |
| 143 | - left = contentWidth + (widthLeft - centerView.getMeasuredWidth()) / 2; | |
| 144 | - top = (height - centerView.getMeasuredHeight()) / 2; | |
| 145 | - centerView | |
| 146 | - .layout(left, top, left + centerView.getMeasuredWidth(), top + centerView.getMeasuredHeight()); | |
| 147 | - } | |
| 148 | - // layout leftDownView | |
| 149 | - left = contentWidth + (widthLeft - leftDownView.getMeasuredWidth()) / 2; | |
| 150 | - top = height - leftDownView.getMeasuredHeight() - leftDownViewLayoutParams.bottomMargin; | |
| 151 | - leftDownView | |
| 152 | - .layout(left, top, left + leftDownView.getMeasuredWidth(), top + leftDownView.getMeasuredHeight()); | |
| 153 | - // layout rightUpView | |
| 154 | - left = contentWidth + (widthLeft - rightUpView.getMeasuredWidth()) / 2; | |
| 155 | - | |
| 156 | - top = rightUpViewLayoutParams.topMargin; | |
| 157 | - rightUpView.layout(left, top, left + rightUpView.getMeasuredWidth(), top + rightUpView.getMeasuredHeight()); | |
| 158 | - } | |
| 159 | - } | |
| 160 | - | |
| 161 | - @Override | |
| 162 | - protected void onDraw(Canvas canvas) { | |
| 163 | - super.onDraw(canvas); | |
| 164 | - canvas.drawRect(backgroundRect, paint); | |
| 165 | - } | |
| 166 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/OCRFrameLayout.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.camera; | |
| 5 | - | |
| 6 | - | |
| 7 | -import android.content.Context; | |
| 8 | -import android.util.AttributeSet; | |
| 9 | -import android.view.View; | |
| 10 | -import android.view.ViewGroup; | |
| 11 | - | |
| 12 | -public class OCRFrameLayout extends ViewGroup { | |
| 13 | - | |
| 14 | - public OCRFrameLayout(Context context) { | |
| 15 | - super(context); | |
| 16 | - } | |
| 17 | - | |
| 18 | - public OCRFrameLayout(Context context, AttributeSet attrs) { | |
| 19 | - super(context, attrs); | |
| 20 | - parseAttrs(attrs); | |
| 21 | - } | |
| 22 | - | |
| 23 | - public OCRFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { | |
| 24 | - super(context, attrs, defStyleAttr); | |
| 25 | - parseAttrs(attrs); | |
| 26 | - } | |
| 27 | - | |
| 28 | - private void parseAttrs(AttributeSet attrs) { | |
| 29 | - } | |
| 30 | - | |
| 31 | - @Override | |
| 32 | - protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
| 33 | - int childCount = getChildCount(); | |
| 34 | - for (int i = 0; i < childCount; i++) { | |
| 35 | - View view = getChildAt(i); | |
| 36 | - view.layout(l, t, r, b); | |
| 37 | - } | |
| 38 | - } | |
| 39 | - | |
| 40 | - @Override | |
| 41 | - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
| 42 | - super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
| 43 | - int width; | |
| 44 | - int height; | |
| 45 | - int childCount = getChildCount(); | |
| 46 | - | |
| 47 | - width = MeasureSpec.getSize(widthMeasureSpec); | |
| 48 | - height = MeasureSpec.getSize(heightMeasureSpec); | |
| 49 | - for (int i = 0; i < childCount; i++) { | |
| 50 | - View view = getChildAt(i); | |
| 51 | - measureChild(view, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec | |
| 52 | - (height, MeasureSpec.EXACTLY)); | |
| 53 | - } | |
| 54 | - setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(height, heightMeasureSpec)); | |
| 55 | - } | |
| 56 | -} |
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/PermissionCallback.java deleted
100644 → 0
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/crop/CropView.java deleted
100644 → 0
| 1 | -/* | |
| 2 | - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. | |
| 3 | - */ | |
| 4 | -package com.cnlive.core.ocr.ui.crop; | |
| 5 | - | |
| 6 | -import android.content.Context; | |
| 7 | -import android.graphics.Bitmap; | |
| 8 | -import android.graphics.BitmapFactory; | |
| 9 | -import android.graphics.Canvas; | |
| 10 | -import android.graphics.Matrix; | |
| 11 | -import android.graphics.Point; | |
| 12 | -import android.graphics.Rect; | |
| 13 | -import android.media.ExifInterface; | |
| 14 | -import android.util.AttributeSet; | |
| 15 | -import android.view.GestureDetector; | |
| 16 | -import android.view.MotionEvent; | |
| 17 | -import android.view.ScaleGestureDetector; | |
| 18 | -import android.view.View; | |
| 19 | -import android.view.WindowManager; | |
| 20 | - | |
| 21 | -import com.cnlive.core.libs.base.util.AlertUtil; | |
| 22 | -import com.cnlive.core.ocr.ui.util.ImageUtil; | |
| 23 | - | |
| 24 | -import java.io.IOException; | |
| 25 | - | |
| 26 | -public class CropView extends View { | |
| 27 | - | |
| 28 | - public CropView(Context context) { | |
| 29 | - super(context); | |
| 30 | - init(); | |
| 31 | - } | |
| 32 | - | |
| 33 | - public CropView(Context context, AttributeSet attrs) { | |
| 34 | - super(context, attrs); | |
| 35 | - init(); | |
| 36 | - } | |
| 37 | - | |
| 38 | - public CropView(Context context, AttributeSet attrs, int defStyleAttr) { | |
| 39 | - super(context, attrs, defStyleAttr); | |
| 40 | - init(); | |
| 41 | - } | |
| 42 | - | |
| 43 | - public void setFilePath(String path) { | |
| 44 | - | |
| 45 | - if (this.bitmap != null && !this.bitmap.isRecycled()) { | |
| 46 | - this.bitmap.recycle(); | |
| 47 | - } | |
| 48 | - | |
| 49 | - if (path == null) { | |
| 50 | - return; | |
| 51 | - } | |
| 52 | - | |
| 53 | - BitmapFactory.Options options = new BitmapFactory.Options(); | |
| 54 | - options.inJustDecodeBounds = true; | |
| 55 | - Bitmap original = BitmapFactory.decodeFile(path, options); | |
| 56 | - | |
| 57 | - try { | |
| 58 | - ExifInterface exif = new ExifInterface(path); | |
| 59 | - int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); | |
| 60 | - Matrix matrix = new Matrix(); | |
| 61 | - int rotationInDegrees = ImageUtil.exifToDegrees(rotation); | |
| 62 | - if (rotation != 0f) { | |
| 63 | - matrix.preRotate(rotationInDegrees); | |
| 64 | - } | |
| 65 | - | |
| 66 | - // 图片太大会导致内存泄露,所以在显示前对图片进行裁剪。 | |
| 67 | - int maxPreviewImageSize = 2560; | |
| 68 | - | |
| 69 | - int min = Math.min(options.outWidth, options.outHeight); | |
| 70 | - min = Math.min(min, maxPreviewImageSize); | |
| 71 | - | |
| 72 | - WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); | |
| 73 | - Point screenSize = new Point(); | |
| 74 | - windowManager.getDefaultDisplay().getSize(screenSize); | |
| 75 | - min = Math.min(min, screenSize.x * 2 / 3); | |
| 76 | - | |
| 77 | - options.inSampleSize = ImageUtil.calculateInSampleSize(options, min, min); | |
| 78 | - options.inScaled = true; | |
| 79 | - options.inDensity = options.outWidth; | |
| 80 | - options.inTargetDensity = min * options.inSampleSize; | |
| 81 | - options.inPreferredConfig = Bitmap.Config.RGB_565; | |
| 82 | - | |
| 83 | - options.inJustDecodeBounds = false; | |
| 84 | - this.bitmap = BitmapFactory.decodeFile(path, options); | |
| 85 | - } catch (IOException e) { | |
| 86 | - e.printStackTrace(); | |
| 87 | - this.bitmap = original; | |
| 88 | - } catch (NullPointerException e) { | |
| 89 | - e.printStackTrace(); | |
| 90 | - } | |
| 91 | - setBitmap(this.bitmap); | |
| 92 | - } | |
| 93 | - | |
| 94 | - private void setBitmap(Bitmap bitmap) { | |
| 95 | - this.bitmap = bitmap; | |
| 96 | - matrix.reset(); | |
| 97 | - centerImage(getWidth(), getHeight()); | |
| 98 | - rotation = 0; | |
| 99 | - invalidate(); | |
| 100 | - } | |
| 101 | - | |
| 102 | - @Override | |
| 103 | - protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
| 104 | - super.onSizeChanged(w, h, oldw, oldh); | |
| 105 | - centerImage(w, h); | |
| 106 | - invalidate(); | |
| 107 | - } | |
| 108 | - | |
| 109 | - public Bitmap crop(Rect frame) { | |
| 110 | - float scale = getScale(); | |
| 111 | - | |
| 112 | - float[] src = new float[] {frame.left, frame.top}; | |
| 113 | - float[] desc = new float[] {0, 0}; | |
| 114 | - | |
| 115 | - Matrix invertedMatrix = new Matrix(); | |
| 116 | - this.matrix.invert(invertedMatrix); | |
| 117 | - invertedMatrix.mapPoints(desc, src); | |
| 118 | - | |
| 119 | - Matrix matrix = new Matrix(); | |
| 120 | - | |
| 121 | - int width = (int) (frame.width() / scale); | |
| 122 | - int height = (int) (frame.height() / scale); | |
| 123 | - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); | |
| 124 | - Canvas canvas = new Canvas(bitmap); | |
| 125 | - | |
| 126 | - Bitmap originalBitmap = this.bitmap; | |
| 127 | - if(originalBitmap == null){ | |
| 128 | - AlertUtil.showDeftToast(getContext(),"该照片已失效,请重新选择"); | |
| 129 | - return null; | |
| 130 | - } | |
| 131 | - matrix.postTranslate(-desc[0], -desc[1]); | |
| 132 | - canvas.drawBitmap(originalBitmap, matrix, null); | |
| 133 | - return bitmap; | |
| 134 | - } | |
| 135 | - | |
| 136 | - public void setMinimumScale(float setMinimumScale) { | |
| 137 | - this.setMinimumScale = setMinimumScale; | |
| 138 | - } | |
| 139 | - | |
| 140 | - public void setMaximumScale(float maximumScale) { | |
| 141 | - this.maximumScale = maximumScale; | |
| 142 | - } | |
| 143 | - | |
| 144 | - private float setMinimumScale = 0.2f; | |
| 145 | - private float maximumScale = 4.0f; | |
| 146 | - | |
| 147 | - private float[] matrixArray = new float[9]; | |
| 148 | - private Matrix matrix = new Matrix(); | |
| 149 | - private Bitmap bitmap; | |
| 150 | - | |
| 151 | - private GestureDetector gestureDetector; | |
| 152 | - | |
| 153 | - private ScaleGestureDetector scaleGestureDetector; | |
| 154 | - private ScaleGestureDetector.OnScaleGestureListener onScaleGestureListener = | |
| 155 | - new ScaleGestureDetector.OnScaleGestureListener() { | |
| 156 | - @Override | |
| 157 | - public boolean onScale(ScaleGestureDetector detector) { | |
| 158 | - scale(detector); | |
| 159 | - return true; | |
| 160 | - } | |
| 161 | - | |
| 162 | - @Override | |
| 163 | - public boolean onScaleBegin(ScaleGestureDetector detector) { | |
| 164 | - return true; | |
| 165 | - } | |
| 166 | - | |
| 167 | - @Override | |
| 168 | - public void onScaleEnd(ScaleGestureDetector detector) { | |
| 169 | - float scale = detector.getScaleFactor(); | |
| 170 | - matrix.postScale(scale, scale); | |
| 171 | - invalidate(); | |
| 172 | - } | |
| 173 | - }; | |
| 174 | - | |
| 175 | - private void init() { | |
| 176 | - scaleGestureDetector = new ScaleGestureDetector(getContext(), onScaleGestureListener); | |
| 177 | - gestureDetector = new GestureDetector(getContext(), new GestureDetector.OnGestureListener() { | |
| 178 | - @Override | |
| 179 | - public boolean onDown(MotionEvent e) { | |
| 180 | - return true; | |
| 181 | - } | |
| 182 | - | |
| 183 | - @Override | |
| 184 | - public void onShowPress(MotionEvent e) { | |
| 185 | - } | |
| 186 | - | |
| 187 | - @Override | |
| 188 | - public boolean onSingleTapUp(MotionEvent e) { | |
| 189 | - return false; | |
| 190 | - } | |
| 191 | - | |
| 192 | - @Override | |
| 193 | - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { | |
| 194 | - translate(distanceX, distanceY); | |
| 195 | - return true; | |
| 196 | - } | |
| 197 | - | |
| 198 | - @Override | |
| 199 | - public void onLongPress(MotionEvent e) { | |
| 200 | - } | |
| 201 | - | |
| 202 | - @Override | |
| 203 | - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { | |
| 204 | - return false; | |
| 205 | - } | |
| 206 | - }); | |
| 207 | - } | |
| 208 | - | |
| 209 | - int rotation = 0; | |
| 210 | - | |
| 211 | - public void rotate(int degrees) { | |
| 212 | - Matrix matrix = new Matrix(); | |
| 213 | - | |
| 214 | - if(bitmap == null) return; | |
| 215 | - int dx = this.bitmap.getWidth() / 2; | |
| 216 | - int dy = this.bitmap.getHeight() / 2; | |
| 217 | - | |
| 218 | - matrix.postTranslate(-dx, -dy); | |
| 219 | - matrix.postRotate(degrees); | |
| 220 | - matrix.postTranslate(dy, dx); | |
| 221 | - Bitmap scaledBitmap = this.bitmap; | |
| 222 | - Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap.getHeight(), scaledBitmap.getWidth(), | |
| 223 | - Bitmap.Config.RGB_565); | |
| 224 | - Canvas canvas = new Canvas(rotatedBitmap); | |
| 225 | - canvas.drawBitmap(this.bitmap, matrix, null); | |
| 226 | - this.bitmap.recycle(); | |
| 227 | - this.bitmap = rotatedBitmap; | |
| 228 | - centerImage(getWidth(), getHeight()); | |
| 229 | - invalidate(); | |
| 230 | - } | |
| 231 | - | |
| 232 | - private void translate(float distanceX, float distanceY) { | |
| 233 | - matrix.getValues(matrixArray); | |
| 234 | - float left = matrixArray[Matrix.MTRANS_X]; | |
| 235 | - float top = matrixArray[Matrix.MTRANS_Y]; | |
| 236 | - | |
| 237 | - Rect bound = getRestrictedBound(); | |
| 238 | - if (bound != null) { | |
| 239 | - float scale = getScale(); | |
| 240 | - float right = left + (int) (bitmap.getWidth() / scale); | |
| 241 | - float bottom = top + (int) (bitmap.getHeight() / scale); | |
| 242 | - | |
| 243 | - if (left - distanceX > bound.left) { | |
| 244 | - distanceX = left - bound.left; | |
| 245 | - } | |
| 246 | - if (top - distanceY > bound.top) { | |
| 247 | - distanceY = top - bound.top; | |
| 248 | - } | |
| 249 | - | |
| 250 | - if (distanceX > 0) { | |
| 251 | - if (right - distanceX < bound.right) { | |
| 252 | - distanceX = right - bound.right; | |
| 253 | - } | |
| 254 | - } | |
| 255 | - if (distanceY > 0) { | |
| 256 | - if (bottom - distanceY < bound.bottom) { | |
| 257 | - distanceY = bottom - bound.bottom; | |
| 258 | - } | |
| 259 | - } | |
| 260 | - } | |
| 261 | - matrix.postTranslate(-distanceX, -distanceY); | |
| 262 | - invalidate(); | |
| 263 | - } | |
| 264 | - | |
| 265 | - private void scale(ScaleGestureDetector detector) { | |
| 266 | - float scale = detector.getScaleFactor(); | |
| 267 | - float currentScale = getScale(); | |
| 268 | - if (currentScale * scale < setMinimumScale) { | |
| 269 | - scale = setMinimumScale / currentScale; | |
| 270 | - } | |
| 271 | - if (currentScale * scale > maximumScale) { | |
| 272 | - scale = maximumScale / currentScale; | |
| 273 | - } | |
| 274 | - matrix.postScale(scale, scale, detector.getFocusX(), detector.getFocusY()); | |
| 275 | - invalidate(); | |
| 276 | - } | |
| 277 | - | |
| 278 | - private void centerImage(int width, int height) { | |
| 279 | - if (width <= 0 || height <= 0 || bitmap == null) { | |
| 280 | - return; | |
| 281 | - } | |
| 282 | - float widthRatio = 1.0f * height / this.bitmap.getHeight(); | |
| 283 | - float heightRatio = 1.0f * width / this.bitmap.getWidth(); | |
| 284 | - | |
| 285 | - float ratio = Math.min(widthRatio, heightRatio); | |
| 286 | - | |
| 287 | - float dx = (width - this.bitmap.getWidth()) / 2; | |
| 288 | - float dy = (height - this.bitmap.getHeight()) / 2; | |
| 289 | - matrix.setTranslate(0, 0); | |
| 290 | - matrix.setScale(ratio, ratio, bitmap.getWidth() / 2, bitmap.getHeight() / 2); | |
| 291 | - matrix.postTranslate(dx, dy); | |
| 292 | - invalidate(); | |
| 293 | - } | |
| 294 | - | |
| 295 | - private float getScale() { | |
| 296 | - matrix.getValues(matrixArray); | |
| 297 | - float scale = matrixArray[Matrix.MSCALE_X]; | |
| 298 | - if (Math.abs(scale) <= 0.1) { | |
| 299 | - scale = matrixArray[Matrix.MSKEW_X]; | |
| 300 | - } | |
| 301 | - return Math.abs(scale); | |
| 302 | - } | |
| 303 | - | |
| 304 | - @Override | |
| 305 | - protected void onDraw(Canvas canvas) { | |
| 306 | - super.onDraw(canvas); | |
| 307 | - if (bitmap != null) { | |
| 308 | - canvas.drawBitmap(bitmap, matrix, null); | |
| 309 | - } | |
| 310 | - } | |
| 311 | - | |
| 312 | - @Override | |
| 313 | - public boolean onTouchEvent(MotionEvent event) { | |
| 314 | - boolean result = scaleGestureDetector.onTouchEvent(event); | |
| 315 | - result = gestureDetector.onTouchEvent(event) || result; | |
| 316 | - return result || super.onTouchEvent(event); | |
| 317 | - } | |
| 318 | - | |
| 319 | - private Rect restrictBound; | |
| 320 | - | |
| 321 | - private Rect getRestrictedBound() { | |
| 322 | - return restrictBound; | |
| 323 | - } | |
| 324 | - | |
| 325 | - public void setRestrictBound(Rect rect) { | |
| 326 | - this.restrictBound = rect; | |
| 327 | - } | |
| 328 | -} |