diff --git a/app/build.gradle b/app/build.gradle index 01c4773..c9112ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,4 +93,7 @@ implementation 'com.esri.arcgisruntime:arcgis-android:100.10.0' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' + //视频压缩 + implementation 'com.iceteck.silicompressorr:silicompressor:2.2.4' + implementation 'com.googlecode.mp4parser:isoparser:1.1.22' } diff --git a/app/build.gradle b/app/build.gradle index 01c4773..c9112ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,4 +93,7 @@ implementation 'com.esri.arcgisruntime:arcgis-android:100.10.0' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' + //视频压缩 + implementation 'com.iceteck.silicompressorr:silicompressor:2.2.4' + implementation 'com.googlecode.mp4parser:isoparser:1.1.22' } diff --git a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java index 0d3ff9c..d53b46e 100644 --- a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java @@ -4,6 +4,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; +import android.location.Location; import android.os.Handler; import android.os.Message; import android.view.MotionEvent; @@ -17,7 +18,9 @@ import com.casic.dcms.bean.GridFeatureBean; import com.casic.dcms.bean.UnitFeatureBean; import com.casic.dcms.utils.Constant; +import com.casic.dcms.utils.LocationHelper; import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.callback.ILocationListener; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.Feature; import com.esri.arcgisruntime.data.FeatureQueryResult; @@ -306,7 +309,14 @@ mapView.setViewpointScaleAsync(mapView.getMapScale() * 2); break; case R.id.removeToLocalView: - mapView.setViewpointCenterAsync(new Point(116.59788667263976, 28.24519968024058)); + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + if (location != null) { + mapView.setViewpointCenterAsync(new Point(location.getLongitude(), location.getLatitude())); + } + } + }); break; default: break; diff --git a/app/build.gradle b/app/build.gradle index 01c4773..c9112ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,4 +93,7 @@ implementation 'com.esri.arcgisruntime:arcgis-android:100.10.0' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' + //视频压缩 + implementation 'com.iceteck.silicompressorr:silicompressor:2.2.4' + implementation 'com.googlecode.mp4parser:isoparser:1.1.22' } diff --git a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java index 0d3ff9c..d53b46e 100644 --- a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java @@ -4,6 +4,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; +import android.location.Location; import android.os.Handler; import android.os.Message; import android.view.MotionEvent; @@ -17,7 +18,9 @@ import com.casic.dcms.bean.GridFeatureBean; import com.casic.dcms.bean.UnitFeatureBean; import com.casic.dcms.utils.Constant; +import com.casic.dcms.utils.LocationHelper; import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.callback.ILocationListener; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.Feature; import com.esri.arcgisruntime.data.FeatureQueryResult; @@ -306,7 +309,14 @@ mapView.setViewpointScaleAsync(mapView.getMapScale() * 2); break; case R.id.removeToLocalView: - mapView.setViewpointCenterAsync(new Point(116.59788667263976, 28.24519968024058)); + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + if (location != null) { + mapView.setViewpointCenterAsync(new Point(location.getLongitude(), location.getLatitude())); + } + } + }); break; default: break; diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java index 59da384..368eeb2 100644 --- a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -7,19 +7,23 @@ import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaRecorder; +import android.os.Handler; +import android.os.Message; import android.text.TextUtils; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.casic.dcms.R; import com.casic.dcms.adapter.ImageRecycleViewAdapter; import com.casic.dcms.base.BaseActivity; @@ -44,9 +48,11 @@ import com.casic.dcms.utils.ItemDecorationSpace; import com.casic.dcms.utils.SaveKeyValues; import com.casic.dcms.utils.StatusBarColorUtil; +import com.casic.dcms.utils.StringHelper; import com.casic.dcms.utils.ToastHelper; import com.google.gson.Gson; import com.gyf.immersionbar.ImmersionBar; +import com.iceteck.silicompressorr.SiliCompressor; import com.luck.picture.lib.PictureSelector; import com.luck.picture.lib.config.PictureConfig; import com.luck.picture.lib.config.PictureMimeType; @@ -63,6 +69,7 @@ import butterknife.BindView; import butterknife.OnClick; +import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer; import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard; public class CaseUploadActivity extends BaseActivity implements View.OnClickListener, View.OnTouchListener, @@ -93,12 +100,14 @@ TextView playAudioView; @BindView(R.id.voiceView) ImageView voiceView; + @BindView(R.id.addVideoView) + ImageView addVideoView; + @BindView(R.id.videoPlayerView) + JCVideoPlayerStandard videoPlayerView; @BindView(R.id.addImageView) ImageView addImageView; @BindView(R.id.selectedResultView) RecyclerView selectedResultView; - @BindView(R.id.videoPlayerView) - JCVideoPlayerStandard videoPlayerView; @BindView(R.id.submitButton) QMUIRoundButton submitButton; @@ -109,10 +118,12 @@ private CaseSubmitPresenterImpl caseSubmitPresenter; private List largeClassBeans; private List smallClassBeans; - private QMUITipDialog submitDialog; + private QMUITipDialog submitDialog, qmuiTipDialog; private Gson gson; private UploadImagePresenterImpl uploadImagePresenter; - private List mediaList = new ArrayList<>();//服务器返回的拍照或者视频数据集 + private List imageList = new ArrayList<>();//服务器返回的拍照数据集 + private List realPaths = new ArrayList<>();//真是图片路径 + private List mediaList = new ArrayList<>();//服务器返回的数据集 private String eorc; private String typeCode; private String typeDetailCode; @@ -121,6 +132,7 @@ private MediaPlayer mediaPlayer; private String gridId; private UploadVideoPresenterImpl uploadVideoPresenter; + private String audioUrl, videoUrl; @Override public int initLayoutView() { @@ -152,6 +164,10 @@ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) .setTipWord("提交中,请稍后") .create(); + qmuiTipDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("视频压缩中,请稍后") + .create(); uploadImagePresenter = new UploadImagePresenterImpl(this); uploadAudioPresenter = new UploadAudioPresenterImpl(this); uploadVideoPresenter = new UploadVideoPresenterImpl(this); @@ -188,7 +204,7 @@ submitButton.setChangeAlphaWhenPress(true); } - @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addVideoView, R.id.addImageView, R.id.submitButton}) @Override public void onClick(View v) { switch (v.getId()) { @@ -268,6 +284,14 @@ intent.putExtra("type", type); startActivityForResult(intent, Constant.REQUEST_MAP_CODE); break; + case R.id.addVideoView: + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .recordVideoSecond(15) + .forResult(PictureConfig.PREVIEW_VIDEO_CODE); + break; case R.id.addImageView: new QMUIDialog.MenuDialogBuilder(this) .addItem("相册中选取", new DialogInterface.OnClickListener() { @@ -286,14 +310,6 @@ takePicture(); } }) - .addItem("相机拍视频", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - //拍视频 - takeVideo(); - } - }) .create().show(); break; case R.id.submitButton: @@ -326,18 +342,6 @@ .forResult(PictureConfig.REQUEST_CAMERA); } - private void takeVideo() { - PictureSelector.create(this) - .openCamera(PictureMimeType.ofVideo()) - .imageEngine(GlideLoadEngine.createGlideEngine()) - .maxSelectNum(1) - .isCompress(true) - .compressQuality(80) - .compressSavePath(FileUtils.getVideoCompressPath()) - .videoMaxSecond(15) - .forResult(PictureConfig.PREVIEW_VIDEO_CODE); - } - @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -357,7 +361,29 @@ case PictureConfig.PREVIEW_VIDEO_CODE: LocalMedia media = PictureSelector.obtainMultipleResult(data).get(0); //"realPath":"/storage/emulated/0/Movies/VID_20210426_17552226.mp4" - uploadVideoPresenter.onReadyRetrofitRequest(new File(media.getRealPath())); + //需要手动压缩视频 + String mediaRealPath = media.getRealPath(); + + qmuiTipDialog.show(); + new Thread(new Runnable() { + @Override + public void run() { + try { + /** + * 视频压缩 + * 第一个参数:视频源文件路径 + * 第二个参数:压缩后视频保存的路径 + */ + String comPressPath = SiliCompressor.with(context).compressVideo(mediaRealPath, FileUtils.getVideoCompressPath()); + Message message = handler.obtainMessage(); + message.what = 20210427; + message.obj = comPressPath; + handler.sendMessage(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); break; case Constant.REQUEST_MAP_CODE: if (data == null) { @@ -379,6 +405,23 @@ } } + @SuppressLint("HandlerLeak") + private Handler handler = new Handler() { + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + if (msg.what == 20210427) { + qmuiTipDialog.hide(); + String comPressPath = (String) msg.obj; + if (!TextUtils.isEmpty(comPressPath)) { + uploadVideoPresenter.onReadyRetrofitRequest(new File(comPressPath)); + } else { + ToastHelper.showToast("案卷视频上传失败", ToastHelper.ERROR); + } + } + } + }; + private void showBigImage(String path) { Intent intent = new Intent(this, BigPictureActivity.class); intent.putExtra("path", path); @@ -392,27 +435,8 @@ case MotionEvent.ACTION_DOWN: //按下动画 voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); - /** - * 录音 - * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 - * */ - String caseDetail = caseDetailEditView.getText().toString().trim(); - if (TextUtils.isEmpty(caseDetail)) { - //可以录音 - startRecordedVoice(); - } else { - //提醒用户是否确认要切换录音 - new QMUIDialog.MessageDialogBuilder(this) - .setTitle("提示") - .setMessage("输入框内是否有文字,是否确认切换?") - .setCanceledOnTouchOutside(false) - .addAction("取消", (dialog, index) -> dialog.dismiss()) - .addAction("确认", (dialog, index) -> { - dialog.dismiss(); - caseDetailEditView.setText(""); - //切换录音 - startRecordedVoice(); - }).create().show(); + if (mediaRecorder != null) { + mediaRecorder.start(); } break; case MotionEvent.ACTION_UP: @@ -425,15 +449,6 @@ return true; } - /** - * 录音,保存文件 - */ - private void startRecordedVoice() { - if (mediaRecorder != null) { - mediaRecorder.start(); - } - } - private void releaseMediaRecorder() { if (mediaRecorder != null) { mediaRecorder.reset(); @@ -492,16 +507,14 @@ public void obtainUploadAudioResult(UploadResultBean resultBean) { // Log.d(TAG, "obtainUploadResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; + audioUrl = resultBean.getData(); /** * http://111.198.10.15:11409/static/2021-04/8fb86dae39ad4f949e934e25465d7382.m4a * */ - caseDetailEditView.setVisibility(View.GONE); playAudioView.setVisibility(View.VISIBLE); try { mediaPlayer = new MediaPlayer(); - mediaPlayer.setDataSource(url); + mediaPlayer.setDataSource(StringHelper.appendCompleteURL(audioUrl)); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepare(); } catch (IOException e) { @@ -516,9 +529,6 @@ } } }); - } else { - caseDetailEditView.setVisibility(View.VISIBLE); - playAudioView.setVisibility(View.GONE); } } @@ -531,28 +541,28 @@ * http://111.198.10.15:11409/static/2021-04/000bcf78345f4c1c86484efa3f9d68a2.jpeg */ //2021-04\\000bcf78345f4c1c86484efa3f9d68a2.jpeg - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; - mediaList.add(url); - if (mediaList.size() == 2) { + String url = resultBean.getData(); + imageList.add(url); + realPaths.add(StringHelper.appendCompleteURL(url)); + if (realPaths.size() == 2) { addImageView.setVisibility(View.GONE); } - imageAdapter.setMediaList(mediaList); + imageAdapter.setMediaList(realPaths); //九宫格点击事件 imageAdapter.setOnItemClickListener(new ImageRecycleViewAdapter.OnItemClickListener() { @Override public void onClick(int position) { //查看大图 - showBigImage(mediaList.get(position)); + showBigImage(realPaths.get(position)); } }); //删除按钮点击事件 imageAdapter.setOnDeleteClickListener(new ImageRecycleViewAdapter.OnDeleteItemClickListener() { @Override public void onClick(int position) { - mediaList.remove(position); - imageAdapter.setMediaList(mediaList); - if (mediaList.size() != 2) { + realPaths.remove(position); + imageAdapter.setMediaList(realPaths); + if (realPaths.size() != 2) { addImageView.setVisibility(View.VISIBLE); } } @@ -562,8 +572,19 @@ @Override public void obtainUploadVideoResult(UploadResultBean resultBean) { +// Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); + //2021-04\\9d89df21173043cfb4188e68613e3e0e.mp4 + addVideoView.setVisibility(View.GONE); + videoPlayerView.setVisibility(View.VISIBLE); + videoUrl = resultBean.getData(); + videoPlayerView.setUp(StringHelper.appendCompleteURL(videoUrl), JCVideoPlayerStandard.SCREEN_LAYOUT_NORMAL); + videoPlayerView.topContainer.setVisibility(View.INVISIBLE); + //设置第一帧为封面 + Glide.with(context) + .setDefaultRequestOptions(new RequestOptions().frame(4000000)) + .load(videoUrl) + .into(videoPlayerView.thumbImageView); } } @@ -582,9 +603,17 @@ if (TextUtils.isEmpty(description)) { ToastHelper.showToast("案卷情况还未填写", ToastHelper.WARING); } - if (mediaList.size() != 2) { + if (!TextUtils.isEmpty(audioUrl)) { + mediaList.add(audioUrl); + } + if (!TextUtils.isEmpty(videoUrl)) { + mediaList.add(videoUrl); + } + if (imageList.size() != 2) { ToastHelper.showToast("必须选择两张图片", ToastHelper.WARING); return; + } else { + mediaList.addAll(imageList); } caseSubmitPresenter.onReadyRetrofitRequest("0", "0", longitude, latitude, "1", "1", eorc, typeCode, typeDetailCode, @@ -630,4 +659,18 @@ uploadAudioPresenter.disposeRetrofitRequest(); } } + + @Override + public void onBackPressed() { + if (JCVideoPlayer.backPress()) { + return; + } + super.onBackPressed(); + } + + @Override + protected void onPause() { + super.onPause(); + JCVideoPlayer.releaseAllVideos(); + } } diff --git a/app/build.gradle b/app/build.gradle index 01c4773..c9112ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,4 +93,7 @@ implementation 'com.esri.arcgisruntime:arcgis-android:100.10.0' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' + //视频压缩 + implementation 'com.iceteck.silicompressorr:silicompressor:2.2.4' + implementation 'com.googlecode.mp4parser:isoparser:1.1.22' } diff --git a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java index 0d3ff9c..d53b46e 100644 --- a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java @@ -4,6 +4,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; +import android.location.Location; import android.os.Handler; import android.os.Message; import android.view.MotionEvent; @@ -17,7 +18,9 @@ import com.casic.dcms.bean.GridFeatureBean; import com.casic.dcms.bean.UnitFeatureBean; import com.casic.dcms.utils.Constant; +import com.casic.dcms.utils.LocationHelper; import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.callback.ILocationListener; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.Feature; import com.esri.arcgisruntime.data.FeatureQueryResult; @@ -306,7 +309,14 @@ mapView.setViewpointScaleAsync(mapView.getMapScale() * 2); break; case R.id.removeToLocalView: - mapView.setViewpointCenterAsync(new Point(116.59788667263976, 28.24519968024058)); + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + if (location != null) { + mapView.setViewpointCenterAsync(new Point(location.getLongitude(), location.getLatitude())); + } + } + }); break; default: break; diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java index 59da384..368eeb2 100644 --- a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -7,19 +7,23 @@ import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaRecorder; +import android.os.Handler; +import android.os.Message; import android.text.TextUtils; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.casic.dcms.R; import com.casic.dcms.adapter.ImageRecycleViewAdapter; import com.casic.dcms.base.BaseActivity; @@ -44,9 +48,11 @@ import com.casic.dcms.utils.ItemDecorationSpace; import com.casic.dcms.utils.SaveKeyValues; import com.casic.dcms.utils.StatusBarColorUtil; +import com.casic.dcms.utils.StringHelper; import com.casic.dcms.utils.ToastHelper; import com.google.gson.Gson; import com.gyf.immersionbar.ImmersionBar; +import com.iceteck.silicompressorr.SiliCompressor; import com.luck.picture.lib.PictureSelector; import com.luck.picture.lib.config.PictureConfig; import com.luck.picture.lib.config.PictureMimeType; @@ -63,6 +69,7 @@ import butterknife.BindView; import butterknife.OnClick; +import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer; import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard; public class CaseUploadActivity extends BaseActivity implements View.OnClickListener, View.OnTouchListener, @@ -93,12 +100,14 @@ TextView playAudioView; @BindView(R.id.voiceView) ImageView voiceView; + @BindView(R.id.addVideoView) + ImageView addVideoView; + @BindView(R.id.videoPlayerView) + JCVideoPlayerStandard videoPlayerView; @BindView(R.id.addImageView) ImageView addImageView; @BindView(R.id.selectedResultView) RecyclerView selectedResultView; - @BindView(R.id.videoPlayerView) - JCVideoPlayerStandard videoPlayerView; @BindView(R.id.submitButton) QMUIRoundButton submitButton; @@ -109,10 +118,12 @@ private CaseSubmitPresenterImpl caseSubmitPresenter; private List largeClassBeans; private List smallClassBeans; - private QMUITipDialog submitDialog; + private QMUITipDialog submitDialog, qmuiTipDialog; private Gson gson; private UploadImagePresenterImpl uploadImagePresenter; - private List mediaList = new ArrayList<>();//服务器返回的拍照或者视频数据集 + private List imageList = new ArrayList<>();//服务器返回的拍照数据集 + private List realPaths = new ArrayList<>();//真是图片路径 + private List mediaList = new ArrayList<>();//服务器返回的数据集 private String eorc; private String typeCode; private String typeDetailCode; @@ -121,6 +132,7 @@ private MediaPlayer mediaPlayer; private String gridId; private UploadVideoPresenterImpl uploadVideoPresenter; + private String audioUrl, videoUrl; @Override public int initLayoutView() { @@ -152,6 +164,10 @@ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) .setTipWord("提交中,请稍后") .create(); + qmuiTipDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("视频压缩中,请稍后") + .create(); uploadImagePresenter = new UploadImagePresenterImpl(this); uploadAudioPresenter = new UploadAudioPresenterImpl(this); uploadVideoPresenter = new UploadVideoPresenterImpl(this); @@ -188,7 +204,7 @@ submitButton.setChangeAlphaWhenPress(true); } - @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addVideoView, R.id.addImageView, R.id.submitButton}) @Override public void onClick(View v) { switch (v.getId()) { @@ -268,6 +284,14 @@ intent.putExtra("type", type); startActivityForResult(intent, Constant.REQUEST_MAP_CODE); break; + case R.id.addVideoView: + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .recordVideoSecond(15) + .forResult(PictureConfig.PREVIEW_VIDEO_CODE); + break; case R.id.addImageView: new QMUIDialog.MenuDialogBuilder(this) .addItem("相册中选取", new DialogInterface.OnClickListener() { @@ -286,14 +310,6 @@ takePicture(); } }) - .addItem("相机拍视频", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - //拍视频 - takeVideo(); - } - }) .create().show(); break; case R.id.submitButton: @@ -326,18 +342,6 @@ .forResult(PictureConfig.REQUEST_CAMERA); } - private void takeVideo() { - PictureSelector.create(this) - .openCamera(PictureMimeType.ofVideo()) - .imageEngine(GlideLoadEngine.createGlideEngine()) - .maxSelectNum(1) - .isCompress(true) - .compressQuality(80) - .compressSavePath(FileUtils.getVideoCompressPath()) - .videoMaxSecond(15) - .forResult(PictureConfig.PREVIEW_VIDEO_CODE); - } - @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -357,7 +361,29 @@ case PictureConfig.PREVIEW_VIDEO_CODE: LocalMedia media = PictureSelector.obtainMultipleResult(data).get(0); //"realPath":"/storage/emulated/0/Movies/VID_20210426_17552226.mp4" - uploadVideoPresenter.onReadyRetrofitRequest(new File(media.getRealPath())); + //需要手动压缩视频 + String mediaRealPath = media.getRealPath(); + + qmuiTipDialog.show(); + new Thread(new Runnable() { + @Override + public void run() { + try { + /** + * 视频压缩 + * 第一个参数:视频源文件路径 + * 第二个参数:压缩后视频保存的路径 + */ + String comPressPath = SiliCompressor.with(context).compressVideo(mediaRealPath, FileUtils.getVideoCompressPath()); + Message message = handler.obtainMessage(); + message.what = 20210427; + message.obj = comPressPath; + handler.sendMessage(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); break; case Constant.REQUEST_MAP_CODE: if (data == null) { @@ -379,6 +405,23 @@ } } + @SuppressLint("HandlerLeak") + private Handler handler = new Handler() { + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + if (msg.what == 20210427) { + qmuiTipDialog.hide(); + String comPressPath = (String) msg.obj; + if (!TextUtils.isEmpty(comPressPath)) { + uploadVideoPresenter.onReadyRetrofitRequest(new File(comPressPath)); + } else { + ToastHelper.showToast("案卷视频上传失败", ToastHelper.ERROR); + } + } + } + }; + private void showBigImage(String path) { Intent intent = new Intent(this, BigPictureActivity.class); intent.putExtra("path", path); @@ -392,27 +435,8 @@ case MotionEvent.ACTION_DOWN: //按下动画 voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); - /** - * 录音 - * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 - * */ - String caseDetail = caseDetailEditView.getText().toString().trim(); - if (TextUtils.isEmpty(caseDetail)) { - //可以录音 - startRecordedVoice(); - } else { - //提醒用户是否确认要切换录音 - new QMUIDialog.MessageDialogBuilder(this) - .setTitle("提示") - .setMessage("输入框内是否有文字,是否确认切换?") - .setCanceledOnTouchOutside(false) - .addAction("取消", (dialog, index) -> dialog.dismiss()) - .addAction("确认", (dialog, index) -> { - dialog.dismiss(); - caseDetailEditView.setText(""); - //切换录音 - startRecordedVoice(); - }).create().show(); + if (mediaRecorder != null) { + mediaRecorder.start(); } break; case MotionEvent.ACTION_UP: @@ -425,15 +449,6 @@ return true; } - /** - * 录音,保存文件 - */ - private void startRecordedVoice() { - if (mediaRecorder != null) { - mediaRecorder.start(); - } - } - private void releaseMediaRecorder() { if (mediaRecorder != null) { mediaRecorder.reset(); @@ -492,16 +507,14 @@ public void obtainUploadAudioResult(UploadResultBean resultBean) { // Log.d(TAG, "obtainUploadResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; + audioUrl = resultBean.getData(); /** * http://111.198.10.15:11409/static/2021-04/8fb86dae39ad4f949e934e25465d7382.m4a * */ - caseDetailEditView.setVisibility(View.GONE); playAudioView.setVisibility(View.VISIBLE); try { mediaPlayer = new MediaPlayer(); - mediaPlayer.setDataSource(url); + mediaPlayer.setDataSource(StringHelper.appendCompleteURL(audioUrl)); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepare(); } catch (IOException e) { @@ -516,9 +529,6 @@ } } }); - } else { - caseDetailEditView.setVisibility(View.VISIBLE); - playAudioView.setVisibility(View.GONE); } } @@ -531,28 +541,28 @@ * http://111.198.10.15:11409/static/2021-04/000bcf78345f4c1c86484efa3f9d68a2.jpeg */ //2021-04\\000bcf78345f4c1c86484efa3f9d68a2.jpeg - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; - mediaList.add(url); - if (mediaList.size() == 2) { + String url = resultBean.getData(); + imageList.add(url); + realPaths.add(StringHelper.appendCompleteURL(url)); + if (realPaths.size() == 2) { addImageView.setVisibility(View.GONE); } - imageAdapter.setMediaList(mediaList); + imageAdapter.setMediaList(realPaths); //九宫格点击事件 imageAdapter.setOnItemClickListener(new ImageRecycleViewAdapter.OnItemClickListener() { @Override public void onClick(int position) { //查看大图 - showBigImage(mediaList.get(position)); + showBigImage(realPaths.get(position)); } }); //删除按钮点击事件 imageAdapter.setOnDeleteClickListener(new ImageRecycleViewAdapter.OnDeleteItemClickListener() { @Override public void onClick(int position) { - mediaList.remove(position); - imageAdapter.setMediaList(mediaList); - if (mediaList.size() != 2) { + realPaths.remove(position); + imageAdapter.setMediaList(realPaths); + if (realPaths.size() != 2) { addImageView.setVisibility(View.VISIBLE); } } @@ -562,8 +572,19 @@ @Override public void obtainUploadVideoResult(UploadResultBean resultBean) { +// Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); + //2021-04\\9d89df21173043cfb4188e68613e3e0e.mp4 + addVideoView.setVisibility(View.GONE); + videoPlayerView.setVisibility(View.VISIBLE); + videoUrl = resultBean.getData(); + videoPlayerView.setUp(StringHelper.appendCompleteURL(videoUrl), JCVideoPlayerStandard.SCREEN_LAYOUT_NORMAL); + videoPlayerView.topContainer.setVisibility(View.INVISIBLE); + //设置第一帧为封面 + Glide.with(context) + .setDefaultRequestOptions(new RequestOptions().frame(4000000)) + .load(videoUrl) + .into(videoPlayerView.thumbImageView); } } @@ -582,9 +603,17 @@ if (TextUtils.isEmpty(description)) { ToastHelper.showToast("案卷情况还未填写", ToastHelper.WARING); } - if (mediaList.size() != 2) { + if (!TextUtils.isEmpty(audioUrl)) { + mediaList.add(audioUrl); + } + if (!TextUtils.isEmpty(videoUrl)) { + mediaList.add(videoUrl); + } + if (imageList.size() != 2) { ToastHelper.showToast("必须选择两张图片", ToastHelper.WARING); return; + } else { + mediaList.addAll(imageList); } caseSubmitPresenter.onReadyRetrofitRequest("0", "0", longitude, latitude, "1", "1", eorc, typeCode, typeDetailCode, @@ -630,4 +659,18 @@ uploadAudioPresenter.disposeRetrofitRequest(); } } + + @Override + public void onBackPressed() { + if (JCVideoPlayer.backPress()) { + return; + } + super.onBackPressed(); + } + + @Override + protected void onPause() { + super.onPause(); + JCVideoPlayer.releaseAllVideos(); + } } diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java index 994de29..37db458 100644 --- a/app/src/main/java/com/casic/dcms/utils/FileUtils.java +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -27,7 +27,7 @@ } public static String getImageCompressPath() { - File dir = new File(Environment.getExternalStorageDirectory(), "CompressFile"); + File dir = new File(Environment.getExternalStorageDirectory(), "CompressImageFile"); if (!dir.exists()) { dir.mkdir(); } @@ -35,10 +35,10 @@ } public static String getVideoCompressPath() { - File dir = new File(Environment.getExternalStorageDirectory(), "VideoFile"); - if (!dir.exists()) { - dir.mkdir(); - } - return dir.toString(); +// File dir = new File(Environment.getExternalStorageDirectory(), "CompressVideoFile"); +// if (!dir.exists()) { +// dir.mkdir(); +// } + return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath(); } } diff --git a/app/build.gradle b/app/build.gradle index 01c4773..c9112ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,4 +93,7 @@ implementation 'com.esri.arcgisruntime:arcgis-android:100.10.0' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' + //视频压缩 + implementation 'com.iceteck.silicompressorr:silicompressor:2.2.4' + implementation 'com.googlecode.mp4parser:isoparser:1.1.22' } diff --git a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java index 0d3ff9c..d53b46e 100644 --- a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java @@ -4,6 +4,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; +import android.location.Location; import android.os.Handler; import android.os.Message; import android.view.MotionEvent; @@ -17,7 +18,9 @@ import com.casic.dcms.bean.GridFeatureBean; import com.casic.dcms.bean.UnitFeatureBean; import com.casic.dcms.utils.Constant; +import com.casic.dcms.utils.LocationHelper; import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.callback.ILocationListener; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.Feature; import com.esri.arcgisruntime.data.FeatureQueryResult; @@ -306,7 +309,14 @@ mapView.setViewpointScaleAsync(mapView.getMapScale() * 2); break; case R.id.removeToLocalView: - mapView.setViewpointCenterAsync(new Point(116.59788667263976, 28.24519968024058)); + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + if (location != null) { + mapView.setViewpointCenterAsync(new Point(location.getLongitude(), location.getLatitude())); + } + } + }); break; default: break; diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java index 59da384..368eeb2 100644 --- a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -7,19 +7,23 @@ import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaRecorder; +import android.os.Handler; +import android.os.Message; import android.text.TextUtils; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.casic.dcms.R; import com.casic.dcms.adapter.ImageRecycleViewAdapter; import com.casic.dcms.base.BaseActivity; @@ -44,9 +48,11 @@ import com.casic.dcms.utils.ItemDecorationSpace; import com.casic.dcms.utils.SaveKeyValues; import com.casic.dcms.utils.StatusBarColorUtil; +import com.casic.dcms.utils.StringHelper; import com.casic.dcms.utils.ToastHelper; import com.google.gson.Gson; import com.gyf.immersionbar.ImmersionBar; +import com.iceteck.silicompressorr.SiliCompressor; import com.luck.picture.lib.PictureSelector; import com.luck.picture.lib.config.PictureConfig; import com.luck.picture.lib.config.PictureMimeType; @@ -63,6 +69,7 @@ import butterknife.BindView; import butterknife.OnClick; +import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer; import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard; public class CaseUploadActivity extends BaseActivity implements View.OnClickListener, View.OnTouchListener, @@ -93,12 +100,14 @@ TextView playAudioView; @BindView(R.id.voiceView) ImageView voiceView; + @BindView(R.id.addVideoView) + ImageView addVideoView; + @BindView(R.id.videoPlayerView) + JCVideoPlayerStandard videoPlayerView; @BindView(R.id.addImageView) ImageView addImageView; @BindView(R.id.selectedResultView) RecyclerView selectedResultView; - @BindView(R.id.videoPlayerView) - JCVideoPlayerStandard videoPlayerView; @BindView(R.id.submitButton) QMUIRoundButton submitButton; @@ -109,10 +118,12 @@ private CaseSubmitPresenterImpl caseSubmitPresenter; private List largeClassBeans; private List smallClassBeans; - private QMUITipDialog submitDialog; + private QMUITipDialog submitDialog, qmuiTipDialog; private Gson gson; private UploadImagePresenterImpl uploadImagePresenter; - private List mediaList = new ArrayList<>();//服务器返回的拍照或者视频数据集 + private List imageList = new ArrayList<>();//服务器返回的拍照数据集 + private List realPaths = new ArrayList<>();//真是图片路径 + private List mediaList = new ArrayList<>();//服务器返回的数据集 private String eorc; private String typeCode; private String typeDetailCode; @@ -121,6 +132,7 @@ private MediaPlayer mediaPlayer; private String gridId; private UploadVideoPresenterImpl uploadVideoPresenter; + private String audioUrl, videoUrl; @Override public int initLayoutView() { @@ -152,6 +164,10 @@ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) .setTipWord("提交中,请稍后") .create(); + qmuiTipDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("视频压缩中,请稍后") + .create(); uploadImagePresenter = new UploadImagePresenterImpl(this); uploadAudioPresenter = new UploadAudioPresenterImpl(this); uploadVideoPresenter = new UploadVideoPresenterImpl(this); @@ -188,7 +204,7 @@ submitButton.setChangeAlphaWhenPress(true); } - @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addVideoView, R.id.addImageView, R.id.submitButton}) @Override public void onClick(View v) { switch (v.getId()) { @@ -268,6 +284,14 @@ intent.putExtra("type", type); startActivityForResult(intent, Constant.REQUEST_MAP_CODE); break; + case R.id.addVideoView: + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .recordVideoSecond(15) + .forResult(PictureConfig.PREVIEW_VIDEO_CODE); + break; case R.id.addImageView: new QMUIDialog.MenuDialogBuilder(this) .addItem("相册中选取", new DialogInterface.OnClickListener() { @@ -286,14 +310,6 @@ takePicture(); } }) - .addItem("相机拍视频", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - //拍视频 - takeVideo(); - } - }) .create().show(); break; case R.id.submitButton: @@ -326,18 +342,6 @@ .forResult(PictureConfig.REQUEST_CAMERA); } - private void takeVideo() { - PictureSelector.create(this) - .openCamera(PictureMimeType.ofVideo()) - .imageEngine(GlideLoadEngine.createGlideEngine()) - .maxSelectNum(1) - .isCompress(true) - .compressQuality(80) - .compressSavePath(FileUtils.getVideoCompressPath()) - .videoMaxSecond(15) - .forResult(PictureConfig.PREVIEW_VIDEO_CODE); - } - @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -357,7 +361,29 @@ case PictureConfig.PREVIEW_VIDEO_CODE: LocalMedia media = PictureSelector.obtainMultipleResult(data).get(0); //"realPath":"/storage/emulated/0/Movies/VID_20210426_17552226.mp4" - uploadVideoPresenter.onReadyRetrofitRequest(new File(media.getRealPath())); + //需要手动压缩视频 + String mediaRealPath = media.getRealPath(); + + qmuiTipDialog.show(); + new Thread(new Runnable() { + @Override + public void run() { + try { + /** + * 视频压缩 + * 第一个参数:视频源文件路径 + * 第二个参数:压缩后视频保存的路径 + */ + String comPressPath = SiliCompressor.with(context).compressVideo(mediaRealPath, FileUtils.getVideoCompressPath()); + Message message = handler.obtainMessage(); + message.what = 20210427; + message.obj = comPressPath; + handler.sendMessage(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); break; case Constant.REQUEST_MAP_CODE: if (data == null) { @@ -379,6 +405,23 @@ } } + @SuppressLint("HandlerLeak") + private Handler handler = new Handler() { + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + if (msg.what == 20210427) { + qmuiTipDialog.hide(); + String comPressPath = (String) msg.obj; + if (!TextUtils.isEmpty(comPressPath)) { + uploadVideoPresenter.onReadyRetrofitRequest(new File(comPressPath)); + } else { + ToastHelper.showToast("案卷视频上传失败", ToastHelper.ERROR); + } + } + } + }; + private void showBigImage(String path) { Intent intent = new Intent(this, BigPictureActivity.class); intent.putExtra("path", path); @@ -392,27 +435,8 @@ case MotionEvent.ACTION_DOWN: //按下动画 voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); - /** - * 录音 - * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 - * */ - String caseDetail = caseDetailEditView.getText().toString().trim(); - if (TextUtils.isEmpty(caseDetail)) { - //可以录音 - startRecordedVoice(); - } else { - //提醒用户是否确认要切换录音 - new QMUIDialog.MessageDialogBuilder(this) - .setTitle("提示") - .setMessage("输入框内是否有文字,是否确认切换?") - .setCanceledOnTouchOutside(false) - .addAction("取消", (dialog, index) -> dialog.dismiss()) - .addAction("确认", (dialog, index) -> { - dialog.dismiss(); - caseDetailEditView.setText(""); - //切换录音 - startRecordedVoice(); - }).create().show(); + if (mediaRecorder != null) { + mediaRecorder.start(); } break; case MotionEvent.ACTION_UP: @@ -425,15 +449,6 @@ return true; } - /** - * 录音,保存文件 - */ - private void startRecordedVoice() { - if (mediaRecorder != null) { - mediaRecorder.start(); - } - } - private void releaseMediaRecorder() { if (mediaRecorder != null) { mediaRecorder.reset(); @@ -492,16 +507,14 @@ public void obtainUploadAudioResult(UploadResultBean resultBean) { // Log.d(TAG, "obtainUploadResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; + audioUrl = resultBean.getData(); /** * http://111.198.10.15:11409/static/2021-04/8fb86dae39ad4f949e934e25465d7382.m4a * */ - caseDetailEditView.setVisibility(View.GONE); playAudioView.setVisibility(View.VISIBLE); try { mediaPlayer = new MediaPlayer(); - mediaPlayer.setDataSource(url); + mediaPlayer.setDataSource(StringHelper.appendCompleteURL(audioUrl)); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepare(); } catch (IOException e) { @@ -516,9 +529,6 @@ } } }); - } else { - caseDetailEditView.setVisibility(View.VISIBLE); - playAudioView.setVisibility(View.GONE); } } @@ -531,28 +541,28 @@ * http://111.198.10.15:11409/static/2021-04/000bcf78345f4c1c86484efa3f9d68a2.jpeg */ //2021-04\\000bcf78345f4c1c86484efa3f9d68a2.jpeg - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; - mediaList.add(url); - if (mediaList.size() == 2) { + String url = resultBean.getData(); + imageList.add(url); + realPaths.add(StringHelper.appendCompleteURL(url)); + if (realPaths.size() == 2) { addImageView.setVisibility(View.GONE); } - imageAdapter.setMediaList(mediaList); + imageAdapter.setMediaList(realPaths); //九宫格点击事件 imageAdapter.setOnItemClickListener(new ImageRecycleViewAdapter.OnItemClickListener() { @Override public void onClick(int position) { //查看大图 - showBigImage(mediaList.get(position)); + showBigImage(realPaths.get(position)); } }); //删除按钮点击事件 imageAdapter.setOnDeleteClickListener(new ImageRecycleViewAdapter.OnDeleteItemClickListener() { @Override public void onClick(int position) { - mediaList.remove(position); - imageAdapter.setMediaList(mediaList); - if (mediaList.size() != 2) { + realPaths.remove(position); + imageAdapter.setMediaList(realPaths); + if (realPaths.size() != 2) { addImageView.setVisibility(View.VISIBLE); } } @@ -562,8 +572,19 @@ @Override public void obtainUploadVideoResult(UploadResultBean resultBean) { +// Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); + //2021-04\\9d89df21173043cfb4188e68613e3e0e.mp4 + addVideoView.setVisibility(View.GONE); + videoPlayerView.setVisibility(View.VISIBLE); + videoUrl = resultBean.getData(); + videoPlayerView.setUp(StringHelper.appendCompleteURL(videoUrl), JCVideoPlayerStandard.SCREEN_LAYOUT_NORMAL); + videoPlayerView.topContainer.setVisibility(View.INVISIBLE); + //设置第一帧为封面 + Glide.with(context) + .setDefaultRequestOptions(new RequestOptions().frame(4000000)) + .load(videoUrl) + .into(videoPlayerView.thumbImageView); } } @@ -582,9 +603,17 @@ if (TextUtils.isEmpty(description)) { ToastHelper.showToast("案卷情况还未填写", ToastHelper.WARING); } - if (mediaList.size() != 2) { + if (!TextUtils.isEmpty(audioUrl)) { + mediaList.add(audioUrl); + } + if (!TextUtils.isEmpty(videoUrl)) { + mediaList.add(videoUrl); + } + if (imageList.size() != 2) { ToastHelper.showToast("必须选择两张图片", ToastHelper.WARING); return; + } else { + mediaList.addAll(imageList); } caseSubmitPresenter.onReadyRetrofitRequest("0", "0", longitude, latitude, "1", "1", eorc, typeCode, typeDetailCode, @@ -630,4 +659,18 @@ uploadAudioPresenter.disposeRetrofitRequest(); } } + + @Override + public void onBackPressed() { + if (JCVideoPlayer.backPress()) { + return; + } + super.onBackPressed(); + } + + @Override + protected void onPause() { + super.onPause(); + JCVideoPlayer.releaseAllVideos(); + } } diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java index 994de29..37db458 100644 --- a/app/src/main/java/com/casic/dcms/utils/FileUtils.java +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -27,7 +27,7 @@ } public static String getImageCompressPath() { - File dir = new File(Environment.getExternalStorageDirectory(), "CompressFile"); + File dir = new File(Environment.getExternalStorageDirectory(), "CompressImageFile"); if (!dir.exists()) { dir.mkdir(); } @@ -35,10 +35,10 @@ } public static String getVideoCompressPath() { - File dir = new File(Environment.getExternalStorageDirectory(), "VideoFile"); - if (!dir.exists()) { - dir.mkdir(); - } - return dir.toString(); +// File dir = new File(Environment.getExternalStorageDirectory(), "CompressVideoFile"); +// if (!dir.exists()) { +// dir.mkdir(); +// } + return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath(); } } diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java index d371eb7..4bbfadb 100644 --- a/app/src/main/java/com/casic/dcms/utils/StringHelper.java +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -1,5 +1,7 @@ package com.casic.dcms.utils; +import android.text.TextUtils; + public class StringHelper { public static void saveUserName(String name) { @@ -46,4 +48,13 @@ } return isDigit && isLetter; } + + public static String appendCompleteURL(String url) { + if (TextUtils.isEmpty(url)) { + ToastHelper.showToast("上传路径不对", ToastHelper.ERROR); + return ""; + } + String data = url.replace("\\", "/"); + return SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; + } } diff --git a/app/build.gradle b/app/build.gradle index 01c4773..c9112ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,4 +93,7 @@ implementation 'com.esri.arcgisruntime:arcgis-android:100.10.0' //上拉加载下拉刷新 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' + //视频压缩 + implementation 'com.iceteck.silicompressorr:silicompressor:2.2.4' + implementation 'com.googlecode.mp4parser:isoparser:1.1.22' } diff --git a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java index 0d3ff9c..d53b46e 100644 --- a/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/ArcGISMapActivity.java @@ -4,6 +4,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; +import android.location.Location; import android.os.Handler; import android.os.Message; import android.view.MotionEvent; @@ -17,7 +18,9 @@ import com.casic.dcms.bean.GridFeatureBean; import com.casic.dcms.bean.UnitFeatureBean; import com.casic.dcms.utils.Constant; +import com.casic.dcms.utils.LocationHelper; import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.callback.ILocationListener; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.Feature; import com.esri.arcgisruntime.data.FeatureQueryResult; @@ -306,7 +309,14 @@ mapView.setViewpointScaleAsync(mapView.getMapScale() * 2); break; case R.id.removeToLocalView: - mapView.setViewpointCenterAsync(new Point(116.59788667263976, 28.24519968024058)); + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + if (location != null) { + mapView.setViewpointCenterAsync(new Point(location.getLongitude(), location.getLatitude())); + } + } + }); break; default: break; diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java index 59da384..368eeb2 100644 --- a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -7,19 +7,23 @@ import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaRecorder; +import android.os.Handler; +import android.os.Message; import android.text.TextUtils; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; import com.casic.dcms.R; import com.casic.dcms.adapter.ImageRecycleViewAdapter; import com.casic.dcms.base.BaseActivity; @@ -44,9 +48,11 @@ import com.casic.dcms.utils.ItemDecorationSpace; import com.casic.dcms.utils.SaveKeyValues; import com.casic.dcms.utils.StatusBarColorUtil; +import com.casic.dcms.utils.StringHelper; import com.casic.dcms.utils.ToastHelper; import com.google.gson.Gson; import com.gyf.immersionbar.ImmersionBar; +import com.iceteck.silicompressorr.SiliCompressor; import com.luck.picture.lib.PictureSelector; import com.luck.picture.lib.config.PictureConfig; import com.luck.picture.lib.config.PictureMimeType; @@ -63,6 +69,7 @@ import butterknife.BindView; import butterknife.OnClick; +import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer; import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard; public class CaseUploadActivity extends BaseActivity implements View.OnClickListener, View.OnTouchListener, @@ -93,12 +100,14 @@ TextView playAudioView; @BindView(R.id.voiceView) ImageView voiceView; + @BindView(R.id.addVideoView) + ImageView addVideoView; + @BindView(R.id.videoPlayerView) + JCVideoPlayerStandard videoPlayerView; @BindView(R.id.addImageView) ImageView addImageView; @BindView(R.id.selectedResultView) RecyclerView selectedResultView; - @BindView(R.id.videoPlayerView) - JCVideoPlayerStandard videoPlayerView; @BindView(R.id.submitButton) QMUIRoundButton submitButton; @@ -109,10 +118,12 @@ private CaseSubmitPresenterImpl caseSubmitPresenter; private List largeClassBeans; private List smallClassBeans; - private QMUITipDialog submitDialog; + private QMUITipDialog submitDialog, qmuiTipDialog; private Gson gson; private UploadImagePresenterImpl uploadImagePresenter; - private List mediaList = new ArrayList<>();//服务器返回的拍照或者视频数据集 + private List imageList = new ArrayList<>();//服务器返回的拍照数据集 + private List realPaths = new ArrayList<>();//真是图片路径 + private List mediaList = new ArrayList<>();//服务器返回的数据集 private String eorc; private String typeCode; private String typeDetailCode; @@ -121,6 +132,7 @@ private MediaPlayer mediaPlayer; private String gridId; private UploadVideoPresenterImpl uploadVideoPresenter; + private String audioUrl, videoUrl; @Override public int initLayoutView() { @@ -152,6 +164,10 @@ .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) .setTipWord("提交中,请稍后") .create(); + qmuiTipDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("视频压缩中,请稍后") + .create(); uploadImagePresenter = new UploadImagePresenterImpl(this); uploadAudioPresenter = new UploadAudioPresenterImpl(this); uploadVideoPresenter = new UploadVideoPresenterImpl(this); @@ -188,7 +204,7 @@ submitButton.setChangeAlphaWhenPress(true); } - @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @OnClick({R.id.caseClassLayout, R.id.caseLargeClassLayout, R.id.caseSmallClassLayout, R.id.locationMapView, R.id.addVideoView, R.id.addImageView, R.id.submitButton}) @Override public void onClick(View v) { switch (v.getId()) { @@ -268,6 +284,14 @@ intent.putExtra("type", type); startActivityForResult(intent, Constant.REQUEST_MAP_CODE); break; + case R.id.addVideoView: + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .recordVideoSecond(15) + .forResult(PictureConfig.PREVIEW_VIDEO_CODE); + break; case R.id.addImageView: new QMUIDialog.MenuDialogBuilder(this) .addItem("相册中选取", new DialogInterface.OnClickListener() { @@ -286,14 +310,6 @@ takePicture(); } }) - .addItem("相机拍视频", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - //拍视频 - takeVideo(); - } - }) .create().show(); break; case R.id.submitButton: @@ -326,18 +342,6 @@ .forResult(PictureConfig.REQUEST_CAMERA); } - private void takeVideo() { - PictureSelector.create(this) - .openCamera(PictureMimeType.ofVideo()) - .imageEngine(GlideLoadEngine.createGlideEngine()) - .maxSelectNum(1) - .isCompress(true) - .compressQuality(80) - .compressSavePath(FileUtils.getVideoCompressPath()) - .videoMaxSecond(15) - .forResult(PictureConfig.PREVIEW_VIDEO_CODE); - } - @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -357,7 +361,29 @@ case PictureConfig.PREVIEW_VIDEO_CODE: LocalMedia media = PictureSelector.obtainMultipleResult(data).get(0); //"realPath":"/storage/emulated/0/Movies/VID_20210426_17552226.mp4" - uploadVideoPresenter.onReadyRetrofitRequest(new File(media.getRealPath())); + //需要手动压缩视频 + String mediaRealPath = media.getRealPath(); + + qmuiTipDialog.show(); + new Thread(new Runnable() { + @Override + public void run() { + try { + /** + * 视频压缩 + * 第一个参数:视频源文件路径 + * 第二个参数:压缩后视频保存的路径 + */ + String comPressPath = SiliCompressor.with(context).compressVideo(mediaRealPath, FileUtils.getVideoCompressPath()); + Message message = handler.obtainMessage(); + message.what = 20210427; + message.obj = comPressPath; + handler.sendMessage(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); break; case Constant.REQUEST_MAP_CODE: if (data == null) { @@ -379,6 +405,23 @@ } } + @SuppressLint("HandlerLeak") + private Handler handler = new Handler() { + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + if (msg.what == 20210427) { + qmuiTipDialog.hide(); + String comPressPath = (String) msg.obj; + if (!TextUtils.isEmpty(comPressPath)) { + uploadVideoPresenter.onReadyRetrofitRequest(new File(comPressPath)); + } else { + ToastHelper.showToast("案卷视频上传失败", ToastHelper.ERROR); + } + } + } + }; + private void showBigImage(String path) { Intent intent = new Intent(this, BigPictureActivity.class); intent.putExtra("path", path); @@ -392,27 +435,8 @@ case MotionEvent.ACTION_DOWN: //按下动画 voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); - /** - * 录音 - * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 - * */ - String caseDetail = caseDetailEditView.getText().toString().trim(); - if (TextUtils.isEmpty(caseDetail)) { - //可以录音 - startRecordedVoice(); - } else { - //提醒用户是否确认要切换录音 - new QMUIDialog.MessageDialogBuilder(this) - .setTitle("提示") - .setMessage("输入框内是否有文字,是否确认切换?") - .setCanceledOnTouchOutside(false) - .addAction("取消", (dialog, index) -> dialog.dismiss()) - .addAction("确认", (dialog, index) -> { - dialog.dismiss(); - caseDetailEditView.setText(""); - //切换录音 - startRecordedVoice(); - }).create().show(); + if (mediaRecorder != null) { + mediaRecorder.start(); } break; case MotionEvent.ACTION_UP: @@ -425,15 +449,6 @@ return true; } - /** - * 录音,保存文件 - */ - private void startRecordedVoice() { - if (mediaRecorder != null) { - mediaRecorder.start(); - } - } - private void releaseMediaRecorder() { if (mediaRecorder != null) { mediaRecorder.reset(); @@ -492,16 +507,14 @@ public void obtainUploadAudioResult(UploadResultBean resultBean) { // Log.d(TAG, "obtainUploadResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; + audioUrl = resultBean.getData(); /** * http://111.198.10.15:11409/static/2021-04/8fb86dae39ad4f949e934e25465d7382.m4a * */ - caseDetailEditView.setVisibility(View.GONE); playAudioView.setVisibility(View.VISIBLE); try { mediaPlayer = new MediaPlayer(); - mediaPlayer.setDataSource(url); + mediaPlayer.setDataSource(StringHelper.appendCompleteURL(audioUrl)); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepare(); } catch (IOException e) { @@ -516,9 +529,6 @@ } } }); - } else { - caseDetailEditView.setVisibility(View.VISIBLE); - playAudioView.setVisibility(View.GONE); } } @@ -531,28 +541,28 @@ * http://111.198.10.15:11409/static/2021-04/000bcf78345f4c1c86484efa3f9d68a2.jpeg */ //2021-04\\000bcf78345f4c1c86484efa3f9d68a2.jpeg - String data = resultBean.getData().replace("\\", "/"); - String url = SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; - mediaList.add(url); - if (mediaList.size() == 2) { + String url = resultBean.getData(); + imageList.add(url); + realPaths.add(StringHelper.appendCompleteURL(url)); + if (realPaths.size() == 2) { addImageView.setVisibility(View.GONE); } - imageAdapter.setMediaList(mediaList); + imageAdapter.setMediaList(realPaths); //九宫格点击事件 imageAdapter.setOnItemClickListener(new ImageRecycleViewAdapter.OnItemClickListener() { @Override public void onClick(int position) { //查看大图 - showBigImage(mediaList.get(position)); + showBigImage(realPaths.get(position)); } }); //删除按钮点击事件 imageAdapter.setOnDeleteClickListener(new ImageRecycleViewAdapter.OnDeleteItemClickListener() { @Override public void onClick(int position) { - mediaList.remove(position); - imageAdapter.setMediaList(mediaList); - if (mediaList.size() != 2) { + realPaths.remove(position); + imageAdapter.setMediaList(realPaths); + if (realPaths.size() != 2) { addImageView.setVisibility(View.VISIBLE); } } @@ -562,8 +572,19 @@ @Override public void obtainUploadVideoResult(UploadResultBean resultBean) { +// Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); if (resultBean.isSuccess()) { - Log.d(TAG, "obtainUploadVideoResult: " + gson.toJson(resultBean)); + //2021-04\\9d89df21173043cfb4188e68613e3e0e.mp4 + addVideoView.setVisibility(View.GONE); + videoPlayerView.setVisibility(View.VISIBLE); + videoUrl = resultBean.getData(); + videoPlayerView.setUp(StringHelper.appendCompleteURL(videoUrl), JCVideoPlayerStandard.SCREEN_LAYOUT_NORMAL); + videoPlayerView.topContainer.setVisibility(View.INVISIBLE); + //设置第一帧为封面 + Glide.with(context) + .setDefaultRequestOptions(new RequestOptions().frame(4000000)) + .load(videoUrl) + .into(videoPlayerView.thumbImageView); } } @@ -582,9 +603,17 @@ if (TextUtils.isEmpty(description)) { ToastHelper.showToast("案卷情况还未填写", ToastHelper.WARING); } - if (mediaList.size() != 2) { + if (!TextUtils.isEmpty(audioUrl)) { + mediaList.add(audioUrl); + } + if (!TextUtils.isEmpty(videoUrl)) { + mediaList.add(videoUrl); + } + if (imageList.size() != 2) { ToastHelper.showToast("必须选择两张图片", ToastHelper.WARING); return; + } else { + mediaList.addAll(imageList); } caseSubmitPresenter.onReadyRetrofitRequest("0", "0", longitude, latitude, "1", "1", eorc, typeCode, typeDetailCode, @@ -630,4 +659,18 @@ uploadAudioPresenter.disposeRetrofitRequest(); } } + + @Override + public void onBackPressed() { + if (JCVideoPlayer.backPress()) { + return; + } + super.onBackPressed(); + } + + @Override + protected void onPause() { + super.onPause(); + JCVideoPlayer.releaseAllVideos(); + } } diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java index 994de29..37db458 100644 --- a/app/src/main/java/com/casic/dcms/utils/FileUtils.java +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -27,7 +27,7 @@ } public static String getImageCompressPath() { - File dir = new File(Environment.getExternalStorageDirectory(), "CompressFile"); + File dir = new File(Environment.getExternalStorageDirectory(), "CompressImageFile"); if (!dir.exists()) { dir.mkdir(); } @@ -35,10 +35,10 @@ } public static String getVideoCompressPath() { - File dir = new File(Environment.getExternalStorageDirectory(), "VideoFile"); - if (!dir.exists()) { - dir.mkdir(); - } - return dir.toString(); +// File dir = new File(Environment.getExternalStorageDirectory(), "CompressVideoFile"); +// if (!dir.exists()) { +// dir.mkdir(); +// } + return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath(); } } diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java index d371eb7..4bbfadb 100644 --- a/app/src/main/java/com/casic/dcms/utils/StringHelper.java +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -1,5 +1,7 @@ package com.casic.dcms.utils; +import android.text.TextUtils; + public class StringHelper { public static void saveUserName(String name) { @@ -46,4 +48,13 @@ } return isDigit && isLetter; } + + public static String appendCompleteURL(String url) { + if (TextUtils.isEmpty(url)) { + ToastHelper.showToast("上传路径不对", ToastHelper.ERROR); + return ""; + } + String data = url.replace("\\", "/"); + return SaveKeyValues.getValue(Constant.IP_KEY, "http://111.198.10.15:11409") + "/static/" + data; + } } diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml index dde439c..1df0d8c 100644 --- a/app/src/main/res/layout/activity_case_upload.xml +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -265,7 +265,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:drawableEnd="@mipmap/point" android:text="案卷录音" android:textSize="@dimen/textFontSize" /> @@ -300,8 +299,7 @@ + android:layout_height="120dp" + android:visibility="gone" /> + + + + + + + + + + + +