认证身份证的正反面,我现在只是做了一个demo。基本效果如下:

1,先看清单文件,这需要配置权限,以及CameraActivity的一些属性:

 ...<uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.FLASHLIGHT" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-featureandroid:name="android.hardware.camera"android:required="true" /><uses-featureandroid:name="android.hardware.camera.autofocus"android:required="true" />...

2,MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private ImageView iv_front;private ImageView iv_back;private ImageView iv_show_front;private ImageView iv_show_back;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);iv_front = (ImageView) findViewById(R.id.iv_show_z);iv_back = (ImageView) findViewById(R.id.iv_show_f);iv_show_back = (ImageView) findViewById(R.id.iv_back_img);iv_show_front = (ImageView) findViewById(R.id.iv_front_img);iv_show_back.setOnClickListener(this);iv_show_front.setOnClickListener(this);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode != RESULT_OK) {return;}if (requestCode == CameraActivity.REQUEST_CODE) {//获取文件路径,显示图片if (data != null) {String path = data.getStringExtra("result_front");String path_b = data.getStringExtra("result_back");if (!TextUtils.isEmpty(path)) {iv_front.setImageBitmap(BitmapFactory.decodeFile(path));}if (!TextUtils.isEmpty(path_b)) {iv_back.setImageBitmap(BitmapFactory.decodeFile(path_b));}}}}/*** 拍摄证件照片** @param type 拍摄证件类型*/private void takePhoto(int type) {if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);}if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 0x12);return;}CameraActivity.navToCamera(this, type);}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.iv_front_img :takePhoto(CameraActivity.TYPE_ID_CARD_FRONT);break;case R.id.iv_back_img :takePhoto(CameraActivity.TYPE_ID_CARD_BACK);break;}}
}

3,activity_main.xml布局文件,这里使用的约束布局 ConstraintLayout 。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"tools:layout_editor_absoluteY="25dp"><android.support.constraint.Guidelineandroid:id="@+id/guideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.5" /><ImageViewandroid:id="@+id/iv_show_z"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginEnd="8dp"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:layout_marginTop="67dp"app:layout_constraintEnd_toStartOf="@+id/guideline"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:srcCompat="@drawable/ic_front" /><ImageViewandroid:id="@+id/iv_show_f"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginBottom="66dp"android:layout_marginTop="69dp"app:layout_constraintBottom_toTopOf="@+id/button"app:layout_constraintEnd_toEndOf="@+id/iv_show_z"app:layout_constraintHorizontal_bias="1.0"app:layout_constraintStart_toStartOf="@+id/iv_show_z"app:layout_constraintTop_toBottomOf="@+id/iv_front_img"app:srcCompat="@drawable/ic_back" /><ImageViewandroid:id="@+id/iv_front_img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:layout_marginStart="8dp"android:layout_marginTop="8dp"app:layout_constraintBottom_toBottomOf="@+id/iv_show_z"app:layout_constraintStart_toEndOf="@+id/iv_show_z"app:layout_constraintTop_toTopOf="@+id/iv_show_z"app:srcCompat="@drawable/icon_img_front" /><ImageViewandroid:id="@+id/iv_back_img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:layout_marginStart="8dp"android:layout_marginTop="8dp"app:layout_constraintBottom_toBottomOf="@+id/iv_show_f"app:layout_constraintStart_toEndOf="@+id/iv_show_f"app:layout_constraintTop_toTopOf="@+id/iv_show_f"app:srcCompat="@drawable/icon_img_back" /><Buttonandroid:id="@+id/button"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginBottom="52dp"android:layout_marginEnd="8dp"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:background="@android:color/holo_red_light"android:textColor="#ffffff"android:textSize="18sp"android:text="认证"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent" /></android.support.constraint.ConstraintLayout>

4,点击上传身份证正面(反面),跳转到相应界面 CameraActivity:

public class CameraActivity extends Activity implements View.OnClickListener {/*** 身份证正面*/public final static int TYPE_ID_CARD_FRONT = 1;/*** 身份证反面*/public final static int TYPE_ID_CARD_BACK = 2;public final static int REQUEST_CODE = 0X13;private CustomCameraPreview customCameraPreview;private View containerView;private ImageView cropView;private View optionView;private int type;/*** 跳转到拍照页面*/public static void navToCamera(Context context, int type) {Intent intent = new Intent(context, CameraActivity.class);intent.putExtra("type", type);((Activity) context).startActivityForResult(intent, REQUEST_CODE);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);type = getIntent().getIntExtra("type", 0);setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);setContentView(R.layout.activity_camera);customCameraPreview = (CustomCameraPreview) findViewById(R.id.camera_surface);containerView = findViewById(R.id.camera_crop_container);cropView = (ImageView) findViewById(R.id.camera_crop);optionView = findViewById(R.id.camera_option);//获取屏幕最小边,设置为cameraPreview较窄的一边float screenMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);//根据screenMinSize,计算出cameraPreview的较宽的一边,长宽比为标准的16:9float maxSize = screenMinSize / 9.0f * 16.0f;RelativeLayout.LayoutParams layoutParams;layoutParams = new RelativeLayout.LayoutParams((int) maxSize, (int) screenMinSize);layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);customCameraPreview.setLayoutParams(layoutParams);float height = (int) (screenMinSize * 0.75);float width = (int) (height * 75.0f / 47.0f);LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams((int) width, ViewGroup.LayoutParams.MATCH_PARENT);LinearLayout.LayoutParams cropParams = new LinearLayout.LayoutParams((int) width, (int) height);containerView.setLayoutParams(containerParams);cropView.setLayoutParams(cropParams);switch (type) {case TYPE_ID_CARD_FRONT:cropView.setImageResource(R.mipmap.camera_front);break;case TYPE_ID_CARD_BACK:cropView.setImageResource(R.mipmap.camera_back);break;}customCameraPreview.setOnClickListener(this);findViewById(R.id.camera_close).setOnClickListener(this);findViewById(R.id.camera_take).setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.camera_surface:customCameraPreview.focus();break;case R.id.camera_close:finish();break;case R.id.camera_take:takePhoto();}}private void takePhoto() {optionView.setVisibility(View.GONE);customCameraPreview.setEnabled(false);customCameraPreview.takePhoto(new Camera.PictureCallback() {public void onPictureTaken(final byte[] data, final Camera camera) {//子线程处理图片,防止ANRnew Thread(new Runnable() {@Overridepublic void run() {Bitmap bitmap = null;if (data != null) {bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);camera.stopPreview();}if (bitmap != null) {//计算裁剪位置float left = ((float) containerView.getLeft() - (float) customCameraPreview.getLeft()) / (float) customCameraPreview.getWidth();float top = (float) cropView.getTop() / (float) customCameraPreview.getHeight();float right = (float) containerView.getRight() / (float) customCameraPreview.getWidth();float bottom = (float) cropView.getBottom() / (float) customCameraPreview.getHeight();//裁剪及保存到文件Bitmap resBitmap = Bitmap.createBitmap(bitmap,(int) (left * (float) bitmap.getWidth()),(int) (top * (float) bitmap.getHeight()),(int) ((right - left) * (float) bitmap.getWidth()),(int) ((bottom - top) * (float) bitmap.getHeight()));FileUtil.saveBitmap(resBitmap,type);if (!bitmap.isRecycled()) {bitmap.recycle();}if (!resBitmap.isRecycled()) {resBitmap.recycle();}//拍照完成,返回对应图片路径Intent intent = new Intent();intent.putExtra("result_front", FileUtil.getImgPath());intent.putExtra("result_back", FileUtil.getImgPath2());setResult(RESULT_OK, intent);finish();}return;}}).start();}});}@Overridepublic void onPointerCaptureChanged(boolean hasCapture) {}
}

5,相应的布局文件,还有需要放在layout-land文件夹下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000"><com.gyq.constraintlayouttest.camera.CustomCameraPreviewandroid:id="@+id/camera_surface"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"><LinearLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:orientation="horizontal"><Viewandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="@color/preview_mock" /><LinearLayoutandroid:id="@+id/camera_crop_container"android:layout_width="0dp"android:layout_height="0dp"android:orientation="vertical"><Viewandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="@color/preview_mock" /><ImageViewandroid:id="@+id/camera_crop"android:layout_width="0dp"android:layout_height="0dp"android:scaleType="fitXY" /><TextViewandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="@color/preview_mock"android:gravity="center"android:text="@string/touch_to_focus"android:textColor="#afff"android:textSize="16dp" /></LinearLayout></LinearLayout><FrameLayoutandroid:layout_width="136dp"android:layout_height="match_parent"android:background="@color/preview_mock"><LinearLayoutandroid:id="@+id/camera_option"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><ImageViewandroid:id="@+id/camera_take"android:layout_width="72dp"android:layout_height="72dp"android:layout_margin="32dp"android:src="@mipmap/camera_take" /><ImageViewandroid:id="@+id/camera_close"android:layout_width="40dp"android:layout_height="40dp"android:src="@mipmap/camera_close" /></LinearLayout></FrameLayout></LinearLayout>
</RelativeLayout>

,6,自定义CustomCameraPreview.java


public class CustomCameraPreview extends SurfaceView implements SurfaceHolder.Callback {private static String TAG = CustomCameraPreview.class.getName();private Camera mCamera;public CustomCameraPreview(Context context) {super(context);init();}public CustomCameraPreview(Context context, AttributeSet attrs) {super(context, attrs);init();}public CustomCameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {SurfaceHolder surfaceHolder = getHolder();surfaceHolder.addCallback(this);surfaceHolder.setKeepScreenOn(true);surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}public void surfaceCreated(SurfaceHolder holder) {mCamera = CamParaUtil.openCamera();if (mCamera != null) {startPreview(holder);}}public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {mCamera.stopPreview();startPreview(holder);}public void surfaceDestroyed(SurfaceHolder holder) {//回收释放资源release();}/*** 预览相机*/private void startPreview( SurfaceHolder holder) {try {mCamera.setPreviewDisplay(holder);Camera.Parameters parameters = mCamera.getParameters();if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {//竖屏拍照时,需要设置旋转90度,否者看到的相机预览方向和界面方向不相同mCamera.setDisplayOrientation(90);parameters.setRotation(90);} else {mCamera.setDisplayOrientation(0);parameters.setRotation(0);}Camera.Size bestSize = CamParaUtil.getBestSize(parameters.getSupportedPreviewSizes());if (bestSize != null) {parameters.setPreviewSize(bestSize.width, bestSize.height);parameters.setPictureSize(bestSize.width, bestSize.height);} else {parameters.setPreviewSize(1920, 1080);parameters.setPictureSize(1920, 1080);}mCamera.setParameters(parameters);mCamera.startPreview();focus();} catch (Exception e) {try {Camera.Parameters parameters = mCamera.getParameters();if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {mCamera.setDisplayOrientation(90);parameters.setRotation(90);} else {mCamera.setDisplayOrientation(0);parameters.setRotation(0);}mCamera.setParameters(parameters);mCamera.startPreview();focus();} catch (Exception e1) {e.printStackTrace();mCamera = null;}}}/*** 释放资源*/private void release() {if (mCamera != null) {mCamera.stopPreview();mCamera.release();mCamera = null;}}/*** 对焦,在CameraActivity中触摸对焦*/public void focus() {if (mCamera != null) {mCamera.autoFocus(null);}}/*** 拍摄照片** @param pictureCallback 在pictureCallback处理拍照回调*/public void takePhoto(Camera.PictureCallback pictureCallback) {if (mCamera != null) {mCamera.takePicture(null, null, pictureCallback);}}
}

相应的工具类及图片等可以查看 传送门

Android 项目必备(十七)-->实现身份证认证功能相关推荐

  1. Android 项目必备(三十七)-->使用友盟集成 QQ、微信、微博等第三方分享与登录

    文章目录 效果图 实战 最近项目需要加入第三方分享和登录功能,之前其他项目的第三方分享和登录一直都使用ShareSDK实现的.为了统一使用友盟的全家桶,所以三方分享和登录也就选择了友盟. 效果图 实战 ...

  2. Android 项目必备(二十七)-->加密和解密

    概况 在对称加密算法中,双方使用的密钥相同,要求解密方事先必须知道加密密钥.这类加密算法技术较为成熟,加密效率高. 在非对称加密算法中,收发双方使用不同的密钥,发方使用公开密钥对消息进行加密,收发使用 ...

  3. Android项目必备技术

    1.一个APP只需要一个Activity //片段fragmentimplementation 'me.yokeyword:fragmentation:1.3.6'implementation 'me ...

  4. Android 项目必备(三十八)-->APP 消息推送

    文章目录 前言 推送的实现方式 1. C2DM 2. 轮询 3. SMS信令推送 4. MQTT协议 5. XMPP协议 6. 使用第三方平台 Android 中 MQTT 的使用 1. 集成 2. ...

  5. 基于eclipse的android项目实战—博学谷(新功能四)签到

    在前面博学谷项目的基础上进行改善和增加新功能 源码资源下载:https://download.csdn.net/download/hyh17808770899/19844673 博学谷的第四个新功能: ...

  6. 基于eclipse的android项目实战—博学谷(新功能五)更换头像

    在前面博学谷项目的基础上进行改善和增加新功能 源码资源下载:https://download.csdn.net/download/hyh17808770899/19844673 博学谷的第五个新功能: ...

  7. 基于eclipse的android项目实战—博学谷(新功能二)欢迎界面倒计时

    在前面博学谷项目的基础上进行改善和增加新功能 源码资源下载:https://download.csdn.net/download/hyh17808770899/19844673 博学谷的第二个新功能: ...

  8. Android 项目必备(十六)--> 手机号 验证码 密码

    文章目录 手机号 验证码 密码 在我们的项目中,获取验证码.手机号验证以及密码输入是很常见的小功能. 手机号 1. 布局文件 <EditTextandroid:id="@+id/et_ ...

  9. Android 项目必备(三十一)-->一个优秀的 APP 从建项目开始

    文章目录 1. 项目结构 (MVP) 2. 配置主题 3. 依赖库与 SDK 4. 配置 Gradle 5. 制定开发规范 6. 其它 1. 项目结构 (MVP) 如果项目比较小 如果项目比较大 2. ...

  10. Android 项目必备(八)--> APP 的开发流程

    文章目录 一.正常的互联网开发 App 的流程 二.快速搭建项目 三.定开发规范 四.选用开发库 五.第三方服务集成 六.云测 一.正常的互联网开发 App 的流程 产品规划,定产品方向 需求调研,产 ...

最新文章

  1. Python网络爬虫之scrapy爬虫的基本使用
  2. fftw与matlab中的fft对比,基于FFTW的FFT和IFFT
  3. print python excel分隔_合并/拆分 Excel?Python、VBA轻松自动化
  4. 锁的用处及脏读、不可重复读和幻觉读的概念
  5. java中的case1怎么说_Java 中的 CAS 简述及原理解析
  6. JPA教程:实体映射-第3部分
  7. 11g下如何查询trace文件名
  8. 云场景实践研究第27期:袋鼠云
  9. java基础输入_java基础之标准输入
  10. 小程序加载更多-数据的拼接
  11. php数组实例,PHP数组实例总结及说明
  12. 内容管理领域举足轻重的100家公司
  13. linux之VMware安装Centos7
  14. python当中df的用法_Pydf替代“df”命令检查不同颜色的磁盘使用情况
  15. 电脑IP地址查看及修改
  16. qt实现涂鸦板_Qt涂鸦板程序图文详细教程
  17. 40K成功入职:六年开发终获小米Offer(附面经+面试题+答案详解)
  18. 印象笔记导出比较好看的html,这些超实用印象笔记模板,让你高效率记笔记
  19. xxx is not in the sudoers file. This incident will be reported.解決方法
  20. 苹果CMS怎么更换模板详细教程

热门文章

  1. 最新电销语音机器人完整版源码+含安装教程
  2. 猿创征文 | 常见的五款BI报表介绍
  3. Android网络通讯之Retrofit
  4. xcb_query_extension_reply_t的解释
  5. Three.js修改模型中心点
  6. 如果你现在没有目标,或许很迷茫
  7. 帆软软件FineReport考试题库FCRA题库
  8. JScriptJQuery学习
  9. 【C/C++】共用体(union)
  10. 简单的异步任务工具——rq 的使用教程