package cn.flightfeather.thirdappmodule.util.photo; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.provider.MediaStore; import android.support.v4.app.Fragment; import android.support.v4.content.FileProvider; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.PopupWindow; import android.widget.Toast; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.ping.greendao.gen.MediafileDao; import java.io.File; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import cn.flightfeather.thirdappmodule.CommonApplication; import cn.flightfeather.thirdappmodule.activity.PhotoViewerActivity; import cn.flightfeather.thirdappmodule.bean.entity.Mediafile; import cn.flightfeather.thirdappmodule.httpservice.UploadService; import cn.flightfeather.thirdappmodule.module.common.CameraActivity; import cn.flightfeather.thirdappmodule.task.CompressPhotoTask; import cn.flightfeather.thirdappmodule.task.DownloadAndSetImageTask; import cn.flightfeather.thirdappmodule.task.SetImageTask; import cn.flightfeather.thirdappmodule.util.DialogUtil2; import cn.flightfeather.thirdappmodule.util.file.FileUtil; import kotlin.Unit; import kotlin.jvm.functions.Function1; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class PhotoUtil { private int photoUploaded =0; private final int photoTotal; private final MediafileDao mediafileDao; private CommonApplication application; private OnUpLoadListener onUpLoadListener; public PhotoUtil(int photoTotal, CommonApplication application, OnUpLoadListener onUpLoadListener) { this.photoTotal = photoTotal; this.application = application; this.mediafileDao = application.getDaoSession().getMediafileDao(); this.onUpLoadListener = onUpLoadListener; } /** * 绑定ImageView和图片,本地加载或联网加载显示(针对固定数量的ImageView) * @param mediaFiles * @param imageViews * @param activity * @return 实际加载的图片个数 */ public static int loadImage(List mediaFiles, List imageViews, Activity activity){ if (mediaFiles!=null){ int count = Math.min(mediaFiles.size(), imageViews.size()); for (int i = 0; i < count; i++) { Mediafile mediaFileTmp = mediaFiles.get(i); File file = FileUtil.getFileFromMediaFile(mediaFileTmp); if (file.exists()) { SetImageTask task1 = new SetImageTask(file, imageViews.get(i), (Activity) activity); task1.execute(); } else { DownloadAndSetImageTask task = new DownloadAndSetImageTask(mediaFileTmp, imageViews.get(i), activity); task.execute(); } } return count; } return 0; } /** * 获取查看图片的点击事件 * @param activity * @param files * @param position * @param mediafiles * @param type 参数为{@link PhotoViewerActivity#PROBLEM_PHOTO} 和{@link PhotoViewerActivity#CHANGE_PHOTO } * @param editable 是否可编辑 * @return */ public static View.OnClickListener OnPhotoViewClickListener(final Activity activity, final List files, final int position, final List mediafiles, final int type, final boolean editable){ View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(activity, PhotoViewerActivity.class); intent.putExtra("position",position); intent.putExtra("deletable",editable); intent.putExtra(PhotoViewerActivity.PARA_MEDIAS, (Serializable) mediafiles); intent.putExtra(PhotoViewerActivity.PARA_FILES, (Serializable) files); intent.putExtra("type",type); activity.startActivityForResult(intent,type); } }; return listener; } /** * 拍照功能 * 启动的activity会返回一个{@link Uri}, 标签为{@link MediaStore#EXTRA_OUTPUT} * @param activity * @param requestCode * @param dirPath */ public static void takePhoto(Activity activity, int requestCode, File dirPath) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //判断要跳转的目的地是否为空 if (intent.resolveActivity(activity.getPackageManager()) != null) { if (dirPath!=null){ //安卓7.0适配 Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { uri = FileProvider.getUriForFile(activity, "cn.flightfeather.thirdapp.fileProvider", dirPath); } else { uri = Uri.fromFile(dirPath); } intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); activity.startActivityForResult(intent, requestCode); }else { Toast.makeText(activity, "拍照启动错误", Toast.LENGTH_SHORT).show(); } } } /** * 从相册中选择图片 * @param activity * @param requestCode * @param num 图片数 */ public static void pickPhoto(Activity activity, int requestCode, int num) { View view = ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0); List textList = new ArrayList<>(); textList.add("相册"); textList.add("拍照"); List> function1List = new ArrayList<>(); function1List.add(popupWindow -> { ImagePicker2.getInstance() .setTitle("选择图片")//设置标题 .showCamera(false)//设置是否显示拍照按钮 .showImage(true)//设置是否展示图片 .showVideo(false)//设置是否展示视频 .setMaxCount(num)//设置最大选择图片数目(默认为1,单选) .setSingleType(true)//设置图片视频不能同时选择 // .setImagePaths(mImagePaths)//设置历史选择记录 .setImageLoader(new GlideLoader())//设置自定义图片加载器 .start(activity, requestCode); popupWindow.dismiss(); return null; }); function1List.add(popupWindow -> { Intent intent = new Intent(activity, CameraActivity.class); intent.putExtra("maxPic", num); activity.startActivityForResult(intent, requestCode); popupWindow.dismiss(); return null; }); DialogUtil2.INSTANCE.showBottomDialog(activity, view, textList, function1List, popupWindow -> null); } public static void pickPhoto2(Activity activity, int requestCode, int num) { ImagePicker2.getInstance() .setTitle("选择图片")//设置标题 .showCamera(true)//设置是否显示拍照按钮 .showImage(true)//设置是否展示图片 .showVideo(false)//设置是否展示视频 .setMaxCount(num)//设置最大选择图片数目(默认为1,单选) .setSingleType(true)//设置图片视频不能同时选择 // .setImagePaths(mImagePaths)//设置历史选择记录 .setImageLoader(new GlideLoader())//设置自定义图片加载器 .start(activity, requestCode); } public static void pickPhoto(Fragment fragment, int requestCode, int num) { ImagePicker2.getInstance() .setTitle("选择图片")//设置标题 .showCamera(true)//设置是否显示拍照按钮 .showImage(true)//设置是否展示图片 .showVideo(false)//设置是否展示视频 .setMaxCount(num)//设置最大选择图片数目(默认为1,单选) .setSingleType(true)//设置图片视频不能同时选择 // .setImagePaths(mImagePaths)//设置历史选择记录 .setImageLoader(new GlideLoader())//设置自定义图片加载器 .start(fragment, requestCode); } /** * 上传图片 * @param mediafileList 图片信息列表 */ public void upLoadPhoto(final List mediafileList) { CompressPhotoTask task = new CompressPhotoTask(mediafileList, new OnCompressListener() { @Override public void onCompressed(List files) { photoUploaded = 0; uploadSinglePhoto(files, mediafileList); } }); task.execute(); } private void uploadSinglePhoto(final List files, final List mediafileList){ if (files.size()==0) { onUpLoadListener.onSuccess(); return; } //当前上传的文件 File file = files.get(photoUploaded); List photoList = new ArrayList<>(); //准备图片部分 // 创建 RequestBody,用于封装构建RequestBody RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); // MultipartBody.Part 和后端约定好Key,这里的partName是用image MultipartBody.Part body = MultipartBody.Part.createFormData("Photos", file.getName(), requestFile); photoList.add(body); List mediafiles = new ArrayList<>(); final Mediafile mediaFile = mediafileList.get(photoUploaded); mediaFile.setRemark("已上传"); mediafiles.add(mediaFile); //准备mediafile的json Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") .create(); String a =gson.toJson(mediafiles); final RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), a); MultipartBody.Part part = MultipartBody.Part.createFormData("mediafileVoList", null, requestBody); photoList.add(part); Call uploadPhotos =application.getRetrofit().create(UploadService.class).uploadPhotos(photoList); uploadPhotos.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if (response.body()!=null){ mediafileDao.update(mediaFile); photoUploaded++; if (photoUploaded call, Throwable t) { if (onUpLoadListener != null) { onUpLoadListener.onFail(); } } }); } //清理缓存 private void clearTemp(List outputFileList){ if (outputFileList!=null&&outputFileList.size()>0){ for (File file:outputFileList){ if (file.exists()){ file.delete(); } } } } /** * 根据要求的宽高,计算图片缩放倍数 * @param options * @param reqWidth * @param reqHeight * @return */ public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // 源图片的高度和宽度 final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // 计算出实际宽高和目标宽高的比率 final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高 // 一定都会大于等于目标的宽和高。 inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } public static Bitmap decodeSampledBitmapFromResource(String filePath, int reqWidth, int reqHeight) { // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小 final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); // 调用上面定义的方法计算inSampleSize值 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 使用获取到的inSampleSize值再次解析图片 options.inJustDecodeBounds = false; options.inPreferredConfig = Bitmap.Config.RGB_565; options.inPurgeable = true; return BitmapFactory.decodeFile(filePath, options); } }