From e7cf41ab71009d2fc48d1c4321fe3b2ea5080c26 Mon Sep 17 00:00:00 2001 From: xuhuixiang Date: Fri, 14 Apr 2023 17:42:06 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8E=AB=E5=90=8D=E5=85=B6=E5=A6=99=E7=9A=84?= =?UTF-8?q?=E4=B8=9C=E8=A5=BF=E5=8F=88=E5=A2=9E=E5=8A=A0=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 9 +- .../java/com/dskj/daikuan/api/ApiService.java | 6 +- .../daikuan/ui/activity/LoginActivity.java | 11 +- .../daikuan/ui/activity/ShenQingActivity.java | 628 ++++++++++++++- app/src/main/res/layout/activity_login.xml | 40 +- app/src/main/res/layout/activity_shenqing.xml | 761 ++++++++++-------- app/src/main/res/mipmap-xxhdpi/luzhi_img.png | Bin 0 -> 18413 bytes app/src/main/res/mipmap-xxhdpi/luzhi_img1.png | Bin 0 -> 14133 bytes .../main/res/mipmap-xxhdpi/wancheng_img.png | Bin 0 -> 17647 bytes app/src/main/res/mipmap-xxxhdpi/logo_2.png | Bin 73296 -> 121106 bytes .../main/res/mipmap-xxxhdpi/player_btn.png | Bin 0 -> 8582 bytes app/src/main/res/xml/file_paths.xml | 22 +- app/src/main/res/xml/file_paths_csj.xml | 9 - app/src/main/res/xml/gdt_file_path.xml | 10 - 15 files changed, 1103 insertions(+), 397 deletions(-) create mode 100644 app/src/main/res/mipmap-xxhdpi/luzhi_img.png create mode 100644 app/src/main/res/mipmap-xxhdpi/luzhi_img1.png create mode 100644 app/src/main/res/mipmap-xxhdpi/wancheng_img.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/player_btn.png delete mode 100644 app/src/main/res/xml/file_paths_csj.xml delete mode 100644 app/src/main/res/xml/gdt_file_path.xml diff --git a/app/build.gradle b/app/build.gradle index f12cd30..8ccf0b6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.dskj.daikuan" minSdkVersion 23 targetSdkVersion 30 - versionCode 116 - versionName "1.1.6" + versionCode 119 + versionName "1.1.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // configurations.all { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ba00b5a..458c4bf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,7 +12,9 @@ - + + + @@ -58,18 +61,22 @@ diff --git a/app/src/main/java/com/dskj/daikuan/api/ApiService.java b/app/src/main/java/com/dskj/daikuan/api/ApiService.java index c1c7a4c..856cfa0 100644 --- a/app/src/main/java/com/dskj/daikuan/api/ApiService.java +++ b/app/src/main/java/com/dskj/daikuan/api/ApiService.java @@ -79,7 +79,9 @@ public interface ApiService { /**身份证*/ @POST("api/Upload/picture") Observable>> picture(@Body MultipartBody file); - + /**身份证*/ + @POST("api/Upload/video") + Observable>> video(@Body MultipartBody file); /**提交*/ @FormUrlEncoded @@ -87,6 +89,6 @@ public interface ApiService { Observable> apply(@Field("full_name") String full_name, @Field("ic_code") String ic_code, @Field("phone") String phone, @Field("occupation") String occupation, @Field("address") String address, @Field("bank_name") String bank_name, @Field("bank_code") String bank_code, @Field("salary") float salary, @Field("amount") float amount, - @Field("id_front") String id_front, @Field("id_back") String id_back); + @Field("id_front") String id_front, @Field("id_back") String id_back, @Field("video") String video); } diff --git a/app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java b/app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java index f55b6a9..f2831a0 100644 --- a/app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java +++ b/app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java @@ -1,6 +1,7 @@ package com.dskj.daikuan.ui.activity; import android.content.Intent; +import android.text.Html; import android.text.TextUtils; import android.view.View; @@ -37,6 +38,7 @@ public class LoginActivity extends BaseActivity{ ToastUtils.showShort(dataBinding.loginBt,bean.errorMessage); @@ -53,13 +55,14 @@ public class LoginActivity extends BaseActivity { SweetAlertDialog pDialog = new SweetAlertDialog(this, SweetAlertDialog.WARNING_TYPE); @@ -144,7 +173,13 @@ public class ShenQingActivity extends BaseActivity rxPermissions.requestEach(Manifest.permission.READ_CONTACTS) + // rxPermissions.requestEach(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) + // .subscribe(permission -> { + // if (permission.granted) { + // toStep2(); + // } + // }); + dataBinding.loginBt.setOnClickListener(view -> rxPermissions.requestEach(Manifest.permission.READ_CONTACTS,Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) .subscribe(permission -> { if (permission.granted) { readContacts(); @@ -156,7 +191,7 @@ public class ShenQingActivity extends BaseActivity { if (permission.granted) { } @@ -170,8 +205,69 @@ public class ShenQingActivity extends BaseActivity { if(isSucc) { // setResult(RESULT_OK); + completeRecording(false, -1000); + dataBinding.step1Ry.setVisibility(View.VISIBLE); + dataBinding.step2Ry.setVisibility(View.GONE); qingkong(); - Intent intent = new Intent(ShenQingActivity.this,XiangQingActivity.class); - intent.putExtra("id",id); - startActivity(intent); + + new Handler().postDelayed(() -> { + Intent intent = new Intent(ShenQingActivity.this,XiangQingActivity.class); + intent.putExtra("id",id); + startActivity(intent); + }, 500); } pDialog.cancel(); @@ -248,10 +350,13 @@ public class ShenQingActivity extends BaseActivity { + LogUtils.i("1111111111111"); + if (!isRecording) { + LogUtils.i("222222222222"); + startRecording(); + } else { + LogUtils.i("333333333333333333"); + + completeRecording(false, -1); + } + }); + dataBinding.wanchengIv.setVisibility(View.GONE); + dataBinding.chongxinTv.setVisibility(View.GONE); + dataBinding.luzhiIv.setVisibility(View.VISIBLE); + + dataBinding.playerIv.setVisibility(View.GONE); + dataBinding.videoView.setVisibility(View.GONE); + + dataBinding.chongxinTv.setOnClickListener(view -> { + dataBinding.wanchengIv.setVisibility(View.GONE); + dataBinding.chongxinTv.setVisibility(View.GONE); + dataBinding.luzhiIv.setVisibility(View.VISIBLE); + initSuf(); + dataBinding.playerIv.setVisibility(View.GONE); + dataBinding.videoView.setVisibility(View.GONE); + + if (!isRecording) { + LogUtils.i("222222222222"); + startRecording(); + } else { + LogUtils.i("333333333333333333"); + + completeRecording(false, -1); + } + }); + } + + private void initSuf() { + + // 配置SurfaceHolder + mSurfaceHolder = dataBinding.commonShortVideoRecordAcRecordSurfaceView.getHolder(); + // 设置Surface不需要维护自己的缓冲区 + mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + // 设置分辨率 + mSurfaceHolder.setFixedSize(320, 280); + // 设置该组件不会让屏幕自动关闭 + mSurfaceHolder.setKeepScreenOn(true); + // 回调接口 + mSurfaceHolder.addCallback(mSurfaceCallBack); + } + + + private SurfaceHolder.Callback mSurfaceCallBack = new SurfaceHolder.Callback() { + @Override + public void surfaceCreated(SurfaceHolder surfaceHolder) { + initCamera(); + } + + @Override + public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { + if (mSurfaceHolder.getSurface() == null) { + return; + } + } + + @Override + public void surfaceDestroyed(SurfaceHolder surfaceHolder) { + releaseCamera(); + } + }; + + /** + * 释放摄像头资源 + * + * @date 2016-2-5 + */ + private void releaseCamera() { + if (mCamera != null) { + mCamera.setPreviewCallback(null); + mCamera.stopPreview(); + mCamera.release(); + mCamera = null; + } + } + /** + * 初始化摄像头 + * + * @throws IOException + */ + private void initCamera() { + + try { + if (mCamera != null) { + releaseCamera(); + } + + mCamera = Camera.open(findFrontFacingCamera()); + if (mCamera == null) { + Toast.makeText(this, "未能获取到相机!", Toast.LENGTH_SHORT).show(); + return; + } + + //将相机与SurfaceHolder绑定 + mCamera.setPreviewDisplay(mSurfaceHolder); + //配置CameraParams + configCameraParams(); + //启动相机预览 + mCamera.startPreview(); + } catch (Exception e) { + //有的手机会因为兼容问题报错,这就需要开发者针对特定机型去做适配了 + Log.w(TAG, "【视频录制】Error initCamera: " + e.getMessage(), e); + } + } + + private int findFrontFacingCamera() { + int cameraId = -1; + // Search for the front facing camera + int numberOfCameras = Camera.getNumberOfCameras(); + for (int i = 0; i < numberOfCameras; i++) { + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(i, info); +// int rotation = (info.orientation - 180 + 360) % 360; +// mediaRecorder.setOrientationHint(rotation); + if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + cameraId = i; + break; + } + } + return cameraId; + } + /** + * 设置摄像头为竖屏 + * + * @date 2015-3-16 + */ + private void configCameraParams() { + Camera.Parameters params = mCamera.getParameters(); + //设置相机的横竖屏(竖屏需要旋转90°) + if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { + params.set("orientation", "portrait"); + mCamera.setDisplayOrientation(90); + } else { + params.set("orientation", "landscape"); + mCamera.setDisplayOrientation(0); + } + + //设置对焦模式 +// params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + List focusModes = params.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { + params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + } + + // 以下方法只在android level 14及以上版本才有的,代码里要加判断哦!!! + // http://www.android-doc.com/reference/android/hardware/Camera.Parameters.html#setRecordingHint(boolean) + if(Build.VERSION.SDK_INT >= 14) { + //缩短Recording启动时间 + params.setRecordingHint(true); + //影像稳定能力 + configVideoStabilization(params); + } + + mCamera.setParameters(params); + } + + @TargetApi(15) + private void configVideoStabilization(Camera.Parameters params) { + //影像稳定能力 + if (params.isVideoStabilizationSupported()) + params.setVideoStabilization(true); + } + + /** 录制事件监听器 */ + private MediaRecorder.OnInfoListener mMediaRecorderOnInfoListener = (mediaRecorder, what, extra) -> { + // 到达了最大录制时长 + if(what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { +// Log.v(TAG, "【视频录制】到达了最大录制时长("+ Const.SHORT_VIDEO_RECORD_MAX_TIME+"ms)"); + // 完成录制 + completeRecording(true,10 * 1000); + } + }; + /** + * 开始录制视频 + */ + private boolean startRecord() { + + try { + // 开始录制时不需要再调用一次这个方法了,因为本界面显示时在surfaceview初始化完成它就被调用 + // 过了,再次调用的话,一是没有必要,二是这会导致更多的耗时和界面的瞬间闪烁,影响用户体验 + initCamera(); + + //录制视频前必须先解锁Camera + mCamera.unlock(); + configMediaRecorder(); + + //开始录制 + mediaRecorder.prepare(); + mediaRecorder.start(); + } catch (Exception e) { + Log.w(TAG, e); + return false; + } + return true; + } + + + private MediaRecorder.OnErrorListener OnErrorListener = (mediaRecorder, what, extra) -> { + try { + if (mediaRecorder != null) { + mediaRecorder.reset(); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); + } + }; + /** + * 配置MediaRecorder() + */ + + private void configMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.reset(); + mediaRecorder.setCamera(mCamera); + mediaRecorder.setOnErrorListener(OnErrorListener); + + mediaRecorder.setOnInfoListener(this.mMediaRecorderOnInfoListener); + // 设置最大录制时长 + mediaRecorder.setMaxDuration(20*1000); + + //使用SurfaceView预览 + mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); + + //1.设置采集声音 + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + //设置采集图像 + mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + //2.设置视频,音频的输出格式 mp4 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); + //3.设置音频的编码格式 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + //设置图像的编码格式 + mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); + + + //设置立体声 +// mediaRecorder.setAudioChannels(2); + //设置最大录制的大小 单位,字节 +// mediaRecorder.setMaxFileSize(1024 * 1024); + + //视录制录制质量(当前默认录制480P的视频,当前的各项参数可以确保录制出的视频跟微信的画质、文件大小等持平) + CamcorderProfile mProfile = null; + try{ + mProfile= CamcorderProfile.get(CamcorderProfile.QUALITY_720P); + } catch(Exception e) { + Log.w(TAG, "【视频录制】此手机不支持QUALITY_480P录制,为保兼容性将使用最低质量进行录制。", e); + mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW); + } + + Log.i(TAG, "【视频录制】预定义录制参数中,mProfile.videoFrameWidth=" + +mProfile.videoFrameWidth+", mProfile.videoFrameHeight="+mProfile.videoFrameHeight); + + mediaRecorder.setAudioEncodingBitRate(44100); + if (mProfile.videoBitRate > 2 * 1024 * 1024) + mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024); + else + mediaRecorder.setVideoEncodingBitRate(1024 * 1024); + mediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); + + //设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度 + mediaRecorder.setOrientationHint(270); + //设置录像的分辨率 + mediaRecorder.setVideoSize(mProfile.videoFrameWidth,mProfile.videoFrameHeight);//352, 288); + + //设置录像视频输出地址 + mediaRecorder.setOutputFile(currentVideoFilePath); + } + + private String getTempVideoName() { + return "shortvideo_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4"; + } + /** + * 录制开始 + */ + public void startRecording() { + // 视频文件保存路径,configMediaRecorder方法中会设置 + currentVideoFilePath = this.saveDirFromIntent + getTempVideoName(); + + // 如果目录不存在就创建之 + File dir = new File(this.saveDirFromIntent); + if(!dir.exists()) + dir.mkdirs(); + +// //开始录制视频 + if (!startRecord()) { + LogUtils.i("333333333333333444444444444"); + + return; + } + LogUtils.i("4444444444444444"); + + this.isRecording = true; + // 开始录制时间 + this.startRecordingTimestamp = System.currentTimeMillis(); + + refreshControlUI(); + } + + /** + * 录制完成。 + */ + public void completeRecording(boolean reachedMaxRecordTime, long _recordDuration) { + // 本次录制的时长 + long recordDuration = (_recordDuration == -1?System.currentTimeMillis() - this.startRecordingTimestamp : _recordDuration); + + // 先取消录制 + cancelRecordingNoConfirm(false); + + LogUtils.i( "【视频录制】视频录制完成(时长:"+recordDuration+"ms),保存路径是:" + this.currentVideoFilePath); + if(_recordDuration!=-1000) { + dataBinding.luzhiIv.setVisibility(View.GONE); + dataBinding.wanchengIv.setVisibility(View.VISIBLE); + dataBinding.chongxinTv.setVisibility(View.VISIBLE); + dataBinding.playerIv.setVisibility(View.VISIBLE); + + } + // 再调置回调数据 + Intent intent = new Intent(); + intent.putExtra("path", this.currentVideoFilePath); + intent.putExtra("duration", recordDuration); + intent.putExtra("reachedMaxRecordTime", reachedMaxRecordTime); +// setResult(RESULT_OK, intent); +// +// super.finish(); + + + dataBinding.playerIv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dataBinding.videoView.setVisibility(View.VISIBLE); + dataBinding.videoView.setVideoPath(ShenQingActivity.this.currentVideoFilePath); + dataBinding.videoView.start(); + dataBinding.playerIv.setVisibility(View.GONE); + + + } + }); + + + + + } + + /** + * 取消录制。 + */ + public void cancelRecordingNoConfirm(boolean deleteFile) { + if(this.isRecording) { + Log.d(TAG, "【视频录制】当前正在录制中,cancelRecording时需先停止录制相关逻辑。。。"); + + try{ + //停止视频录制 + stopRecord(); + + // 重置 + this.startRecordingTimestamp = 0; + + //先给Camera加锁后再释放相机 + mCamera.lock(); + releaseCamera(); + + this.isRecording = false; + + refreshControlUI(); + + // 如果需要删除录制完成的文件 + if(deleteFile && this.currentVideoFilePath != null) + { + deleteFile(this.currentVideoFilePath); + } + } catch (Exception e) { + Log.w(TAG, "【视频录制】cancelRecording时发生异常,原因:"+e.getMessage(), e); + } + } else { + Log.d(TAG, "【视频录制】当前未在录制中,cancelRecording时直接通出当前界面即可。"); + } + } + + @Override + public void onBackPressed() { + if(dataBinding.step2Ry.getVisibility() ==View.VISIBLE){ + completeRecording(false, -1000); + dataBinding.step1Ry.setVisibility(View.VISIBLE); + dataBinding.step2Ry.setVisibility(View.GONE); + }else{ + super.onBackPressed(); + + } + } + + /** + * 停止录制视频 + */ + private void stopRecord() { + // 设置后不会崩 + mediaRecorder.setOnErrorListener(null); + mediaRecorder.setPreviewDisplay(null); + //停止录制 + mediaRecorder.stop(); + mediaRecorder.reset(); + //释放资源 + mediaRecorder.release(); + mediaRecorder = null; + } + + /** + * 点击中间按钮,执行的UI更新操作 + */ + private void refreshControlUI() { + if (this.isRecording) { + //录像时间计时 +// mRecordTime.setBase(SystemClock.elapsedRealtime()); +// mRecordTime.start(); + + // 设置按钮此状态下的图标 + dataBinding.luzhiIv.setImageResource(R.mipmap.luzhi_img1); + //1s后才能按停止录制按钮 +// dataBinding.luzhiIv.setEnabled(false); + + // 显示录制动画 +// mRecordingAnim.setImageResource(R.drawable.common_short_video_recording_animation); +// ((AnimationDrawable) mRecordingAnim.getDrawable()).start(); + +// new Handler().postDelayed(() -> +// dataBinding.luzhiIv.setEnabled(true), 1000); + } else { +// mRecordTime.stop(); + dataBinding.luzhiIv.setImageResource(R.mipmap.luzhi_img); + +// mRecordingAnim.setImageResource(R.drawable.common_short_video_recordvideo_start_amination_normal); + } } private void toApply() { Api.getInstance().apply(dataBinding.fullnameEt.getText().toString(), dataBinding.icEt.getText().toString(), dataBinding.phoneNumberEt.getText().toString(), dataBinding.occupationEt.getText().toString(), dataBinding.addressEt.getText().toString(), dataBinding.beneficiaryBankEt.getText().toString(), dataBinding.beneficiaryAccountNoEt.getText().toString(), Float.parseFloat(dataBinding.salaryEt.getText().toString().trim()), - Float.parseFloat(dataBinding.loanAmountEt.getText().toString().trim()), id_front, id_back) + Float.parseFloat(dataBinding.loanAmountEt.getText().toString().trim()), id_front, id_back,videoPath) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver>() { @@ -507,13 +1069,13 @@ public class ShenQingActivity extends BaseActivity types = getPic(100 - files.size()); - LogUtils.i("获取到的文件地址2:" + GsonUtils.beanToJSONString(types)); +// LogUtils.i("获取到的文件地址2:" + GsonUtils.beanToJSONString(types)); if (types != null && types.size() > 0) { files.addAll(types); } } - LogUtils.i("获取到的文件地址3:" + GsonUtils.beanToJSONString(files)); +// LogUtils.i("获取到的文件地址3:" + GsonUtils.beanToJSONString(files)); toUpIDCard(); // toApply(); } @@ -568,7 +1130,7 @@ public class ShenQingActivity extends BaseActivity>>() { + + @Override + public void onSuccess(Result> feedbackResp) { + if (feedbackResp.data != null && feedbackResp.data.size() > 0) { + videoPath = feedbackResp.data.get(0); + + toApply(); + } + } + + @Override + public void onError(int code, String msg) { +// ToastUtils.showShort(dataBinding.loginBt, msg); + changePush(false, msg); + } + }); + } + + + } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 8225315..e342459 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -88,18 +88,6 @@ android:textSize="16sp" android:visibility="gone" /> -