import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.entity.LocalMedia;
import net.qihoo.corp.iqha.base.ui.activity.IQHABaseActivity;
import net.qihoo.corp.iqha.base.utils.DensityUtils;
import net.qihoo.corp.iqha.base.utils.ToastUtil;
import net.qihoo.corp.iqha.base.utils.logger.Logger;
import net.qihoo.corp.iqha.base.widgets.MDiaglog;
import net.qihoo.corp.iqha.base.widgets.adapter.BaseQuickAdapter;
import net.qihoo.corp.module.base.R;
import net.qihoo.corp.module.base.adapter.TackPhotosAdapter;
import net.qihoo.corp.module.base.config.RoutePath;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.RuntimePermissions;
/**
* author CaiNing
* email oslanka@163.com
* created 2019/10/16 10:30
* version v 1.0
*/
@RuntimePermissions
public class TakeMultiPhotoActivity extends IQHABaseActivity implements SurfaceHolder.Callback {
private Camera mCamera;
private Camera.Parameters mParams;
private SurfaceHolder mSurfaceHolder;
private SurfaceHolder mySurfaceHolder;
private Camera.Size preSize;
private SurfaceView mSurfaceView;
private RelativeLayout layouHolder;
private ImageView oralView;
private int rawX;
private int rawY;
private ImageView ivTackPhoto;
private TextView tvCancel;
private ImageView changeCamera;
private boolean catchOnePhoto;
private int maxPhotos =9;
private Listphotos =new ArrayList<>();
private TextView tvOk;
private RecyclerView recyclerView;
private TackPhotosAdapter tackPhotosAdapter;
private LinearLayout layoutHeader;
@Override
public boolean getTitleBarVisible() {
setImmersionBar(true);
return false;
}
@Override
protected int setLayoutId() {
return R.layout.activity_tack_multi_photo;
}
@SuppressLint("ClickableViewAccessibility")
@Override
protected void initListener() {
initView();
int px40 =DensityUtils.dp2px(this, 40);
layouHolder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCamera !=null)
mCamera.autoFocus(null);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)oralView.getLayoutParams();
layoutParams.setMargins(rawX -px40, rawY -px40, 0, 0);
oralView.setLayoutParams(layoutParams);
oralView.setVisibility(View.VISIBLE);
oralView.postDelayed(new Runnable() {
@Override
public void run() {
if (oralView !=null)
oralView.setVisibility(View.GONE);
}
}, 500);
}
});
layouHolder.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
rawX = (int)event.getRawX();
rawY = (int)event.getRawY();
Logger.i("info---->touch--->" +event.getX() +"--->" +event.getY() +"--->" +rawX +"--->" +rawY);
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
break;
}
return false;
});
ivTackPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
tvCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setResult(RESULT_CANCELED);
finish();
}
});
changeCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isBack = !isBack;
changeCamera();
}
});
tvOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Listresult =new ArrayList<>();
for (int i =0; i
LocalMedia localMedia =new LocalMedia();
String path =photos.get(i);
localMedia.setPath(path);
localMedia.setCompressPath(path);
result.add(localMedia);
}
Intent intent =new Intent();
intent.putExtra(PictureConfig.EXTRA_RESULT_SELECTION,(Serializable)result);
setResult(RESULT_OK,intent);
finish();
}
});
}
public void takePicture() {//对外暴露的方法,连续拍照时调用
if (mCamera !=null)
mCamera.takePicture(null, null, jpeg);
showLoading();
}
@SuppressLint("StaticFieldLeak")
public class SavePictureTask extends AsyncTask {
@SuppressLint("SimpleDateFormat")
@Override
protected Bitmap doInBackground(byte[]...params) {
byte[]data =params[0]; //回调的数据
Bitmap bitmap =BitmapFactory.decodeByteArray(data, 0, data.length);
String path =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) +File.separator +"Test";
File file =new File(path);
if (!file.exists()) {//文件不存在就创建
file.mkdir();
}
String picPath =file +File.separator +System.currentTimeMillis() +".jpg";
File pic =new File(picPath);
try {
FileOutputStream mFos =new FileOutputStream(pic);
//压缩
Matrix matrix =new Matrix();
//旋转90,拍完照的图片保存之后会自动旋转90度,在这里把图片给转回去去
matrix.postRotate(90);
// 创建新的图片
Bitmap resizedBitmap =Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 85, mFos);
mFos.close();
if (photos.size() <=maxPhotos) {
photos.add(0,picPath);
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
hideLoading();
super.onPostExecute(bitmap);
// ToastUtil.showToastShort("拍照成功了");
layoutHeader.setVisibility(View.VISIBLE);
tackPhotosAdapter.notifyItemInserted(0);
recyclerView.scrollToPosition(0);
}
}
private void changeCamera() {
initCamera();
try {
mCamera.setPreviewDisplay(mySurfaceHolder);
}catch (IOException ioe) {
ioe.printStackTrace();
}
mCamera.startPreview();
mCamera.autoFocus(null);
}
private void initView() {
layouHolder = findViewById(R.id.layout_holder);
oralView = findViewById(R.id.view_oral);
ivTackPhoto = findViewById(R.id.iv_tack_photo);
tvCancel = findViewById(R.id.tv_cancel);
changeCamera = findViewById(R.id.change_camera);
recyclerView = findViewById(R.id.recycler_view);
layoutHeader = findViewById(R.id.layout_header);
layoutHeader.setVisibility(View.GONE);
tvOk = findViewById(R.id.tv_ok);
tackPhotosAdapter =new TackPhotosAdapter(this, photos);
tackPhotosAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
String path =photos.get(position);
ARouter.getInstance().build(RoutePath.PATH_IMAGE_ACTIVITY)
.withString("filePath",path)
.withBoolean("isLocalImage",true)
.withTransition(R.anim.slide_in_right, R.anim.slide_out_left)
.navigation(TakeMultiPhotoActivity.this);
}
});
tackPhotosAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
}
});
recyclerView.setAdapter(tackPhotosAdapter);
final LinearLayoutManager layoutManager =new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
initSurface();
}
@Override
public void initData() {
}
private void initSurface() {
mSurfaceView = findViewById(R.id.sf_view);
mSurfaceHolder =mSurfaceView.getHolder();
//mSurfaceHolder.setFixedSize(SRC_FRAME_WIDTH, SRC_FRAME_HEIGHT);
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
getCameraPosition();
}
private boolean isBack =true;
private void openCamera(SurfaceHolder holder) {
initCamera();
setCameraAndOpen(holder);
}
private void setCameraAndOpen(SurfaceHolder holder) {
mParams.setPreviewSize(preSize.width, preSize.height);
mCamera.setParameters(mParams);
try {
mCamera.setPreviewDisplay(holder);
}catch (IOException ioe) {
ioe.printStackTrace();
}
mCamera.startPreview();
mCamera.autoFocus(null);
}
private void initCamera() {
int mCameraId;//.CAMERA_FACING_FRONT;
// int cameraNum = Camera.getNumberOfCameras();
// if (cameraNum > 1)
// mCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
releaseCamera(); // release Camera, if not release camera before call camera, it will be locked
if (isBack) {
mCameraId =iBackCameraIndex;
}else {
mCameraId =iFontCameraIndex;
}
mCamera =Camera.open(mCameraId);
mParams =mCamera.getParameters();
mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
setCameraDisplayOrientation(this, 0, mCamera);
preSize =getCloselyPreSize(true, (int) getScreenWidth(), (int) getScreenHeight(), mParams.getSupportedPreviewSizes());
Logger.i("----------->size" +preSize.height +"--" +preSize.width);
float screenWidth = getScreenWidth();
int localHeight;
if (preSize.height
localHeight = (int) (screenWidth *preSize.width /preSize.height);
else localHeight = (int) (screenWidth *preSize.height /preSize.width);
ViewGroup.LayoutParams layoutParams =mSurfaceView.getLayoutParams();
layoutParams.height =localHeight;
mSurfaceView.setLayoutParams(layoutParams);
}
private Camera.PictureCallback jpeg = (data, camera) -> {
if (photos.size() <=maxPhotos) {
new SavePictureTask().execute(data); //异步保存照片
mCamera.startPreview();
mCamera.autoFocus(null);
}else {
// ToastUtil.showToastShort("最多一次拍摄"+maxPhotos+"张照片");
MDiaglog.newInstance(TakeMultiPhotoActivity.this).setMMessage("最多一次拍摄" +maxPhotos +"张照片").setMPositiveButton("确定").show();
}
};
private int iFontCameraIndex =0, iBackCameraIndex =0;
protected void getCameraPosition() {
Camera.CameraInfo cameraInfo =new Camera.CameraInfo();
int iCameraCnt =Camera.getNumberOfCameras();
for (int i =0; i
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_FRONT) {
iFontCameraIndex = i;
}else if (cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_BACK) {
iBackCameraIndex = i;
}
}
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
private void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {
Camera.CameraInfo info =new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int rotation =activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees =0;
switch (rotation) {
case Surface.ROTATION_0:
degrees =0;
break;
case Surface.ROTATION_90:
degrees =90;
break;
case Surface.ROTATION_180:
degrees =180;
break;
case Surface.ROTATION_270:
degrees =270;
break;
}
int displayDegree;
if (info.facing ==Camera.CameraInfo.CAMERA_FACING_FRONT) {
displayDegree = (info.orientation + degrees) %360;
displayDegree = (360 - displayDegree) %360; // compensate the mirror
}else {
displayDegree = (info.orientation - degrees +360) %360;
}
camera.setDisplayOrientation(displayDegree);
}
private synchronized void releaseCamera() {
if (mCamera !=null) {
try {
mCamera.setPreviewCallback(null);
}catch (Exception e) {
e.printStackTrace();
}
try {
mCamera.stopPreview();
}catch (Exception e) {
e.printStackTrace();
}
try {
mCamera.release();
}catch (Exception e) {
e.printStackTrace();
}
mCamera =null;
}
}
public static void open(Activity activity, int requlstCode) {
Intent mIntent =new Intent(activity, TakeMultiPhotoActivity.class);
// mIntent.setExtrasClassLoader(Action.class.getClassLoader());
activity.startActivityForResult(mIntent, requlstCode);
}
@NeedsPermission(Manifest.permission.CAMERA)
void getCamera() {
if (this.mySurfaceHolder !=null) {
openCamera(mySurfaceHolder);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[]permissions, @NonNull int[]grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
TakeMultiPhotoActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
public static Camera.Size getCloselyPreSize(boolean isPortrait, int surfaceWidth, int surfaceHeight, ListpreSizeList) {
// surfaceWidth = 1080;
// surfaceHeight = 1080;
int reqTmpWidth;
int reqTmpHeight;
// 当屏幕为垂直的时候需要把宽高值进行调换,保证宽大于高
if (isPortrait) {
reqTmpWidth =surfaceHeight;
reqTmpHeight =surfaceWidth;
}else {
reqTmpWidth =surfaceWidth;
reqTmpHeight =surfaceHeight;
}
//先查找preview中是否存在与surfaceview相同宽高的尺寸
for (Camera.Size size :preSizeList) {
if ((size.width ==reqTmpWidth) && (size.height ==reqTmpHeight)) {
return size;
}
}
for (Camera.Size size :preSizeList) {
if ((size.width ==1920) && (size.height ==1080)) {
return size;
}
}
// TODO: 2019/9/25 找一个比例最接近,并且最小的
// 得到与传入的宽高比最接近的size
float reqRatio = ((float)reqTmpWidth) /reqTmpHeight;
float curRatio, deltaRatio;
float deltaRatioMin =Float.MAX_VALUE;
Camera.Size retSize =null;
for (Camera.Size size :preSizeList) {
curRatio = ((float)size.width) /size.height;
deltaRatio =Math.abs(reqRatio -curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin =deltaRatio;
retSize =size;
}
}
return retSize;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
this.mySurfaceHolder =holder;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==PackageManager.PERMISSION_GRANTED) {
openCamera(holder); // open camera\
}else {
TakeMultiPhotoActivityPermissionsDispatcher.getCameraWithPermissionCheck(this);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}