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() {//對(duì)外暴露的方法荠列,連續(xù)拍照時(shí)調(diào)用
? ? ? ? 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];? //回調(diào)的數(shù)據(jù)
? ? ? ? ? ? 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()) {//文件不存在就創(chuàng)建
? ? ? ? ? ? ? ? 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();
? ? ? ? ? ? ? ? //旋轉(zhuǎn)90,拍完照的圖片保存之后會(huì)自動(dòng)旋轉(zhuǎn)90度,在這里把圖片給轉(zhuǎn)回去去
? ? ? ? ? ? ? ? matrix.postRotate(90);
? ? ? ? ? ? ? ? // 創(chuàng)建新的圖片
? ? ? ? ? ? ? ? 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;
? ? ? ? // 當(dāng)屏幕為垂直的時(shí)候需要把寬高值進(jìn)行調(diào)換,保證寬大于高
? ? ? ? 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? 找一個(gè)比例最接近畔裕,并且最小的
? ? ? ? // 得到與傳入的寬高比最接近的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) {
}
}