images) {
- for(TImage image : images) {
- if(TImage.FromType.CAMERA == fromType) {
+ for (TImage image : images) {
+ if (TImage.FromType.CAMERA == fromType) {
TFileUtils.delete(image.getOriginalPath());
image.setOriginalPath("");
}
@@ -450,7 +479,7 @@ private void handleTakeCallBack(final TResult result, String... message) {
if (message.length > 0) {
listener.takeFail(result, message[0]);
} else if (multipleCrop != null && multipleCrop.hasFailed) {
- listener.takeFail(result, contextWrap.getActivity().getResources().getString(R.string.msg_crop_failed));
+ listener.takeFail(result, contextWrap.getActivity().getResources().getString(org.devio.takephoto.R.string.msg_crop_failed));
} else if (compressConfig != null) {
boolean hasFailed = false;
for (TImage image : result.getImages()) {
@@ -460,7 +489,7 @@ private void handleTakeCallBack(final TResult result, String... message) {
}
}
if (hasFailed) {
- listener.takeFail(result, contextWrap.getActivity().getString(R.string.msg_compress_failed));
+ listener.takeFail(result, contextWrap.getActivity().getString(org.devio.takephoto.R.string.msg_compress_failed));
} else {
listener.takeSuccess(result);
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressConfig.java b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressConfig.java
similarity index 79%
rename from takephoto_library/src/main/java/com/jph/takephoto/compress/CompressConfig.java
rename to takephoto_library/src/main/java/org/devio/takephoto/compress/CompressConfig.java
index 2c386da8..3c29c3d6 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressConfig.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressConfig.java
@@ -1,7 +1,7 @@
-package com.jph.takephoto.compress;
+package org.devio.takephoto.compress;
-import com.jph.takephoto.model.LubanOptions;
+import org.devio.takephoto.model.LubanOptions;
import java.io.Serializable;
@@ -15,20 +15,20 @@ public class CompressConfig implements Serializable {
/**
* 长或宽不超过的最大像素,单位px
*/
- private int maxPixel=1200;
+ private int maxPixel = 1200;
/**
* 压缩到的最大大小,单位B
*/
- private int maxSize=100*1024;
+ private int maxSize = 100 * 1024;
/**
* 是否启用像素压缩
*/
- private boolean enablePixelCompress=true;
+ private boolean enablePixelCompress = true;
/**
* 是否启用质量压缩
*/
- private boolean enableQualityCompress=true;
+ private boolean enableQualityCompress = true;
/**
* 是否保留原文件
@@ -39,15 +39,20 @@ public class CompressConfig implements Serializable {
* Luban压缩配置
*/
private LubanOptions lubanOptions;
- public static CompressConfig ofDefaultConfig(){
+
+ public static CompressConfig ofDefaultConfig() {
return new CompressConfig();
}
- public static CompressConfig ofLuban(LubanOptions options){
+
+ public static CompressConfig ofLuban(LubanOptions options) {
return new CompressConfig(options);
}
- private CompressConfig(){}
- private CompressConfig(LubanOptions options){
- this.lubanOptions=options;
+
+ private CompressConfig() {
+ }
+
+ private CompressConfig(LubanOptions options) {
+ this.lubanOptions = options;
}
public LubanOptions getLubanOptions() {
@@ -57,13 +62,16 @@ public LubanOptions getLubanOptions() {
public int getMaxPixel() {
return maxPixel;
}
+
public CompressConfig setMaxPixel(int maxPixel) {
this.maxPixel = maxPixel;
return this;
}
+
public int getMaxSize() {
return maxSize;
}
+
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
@@ -87,35 +95,44 @@ public void enableQualityCompress(boolean enableQualityCompress) {
public boolean isEnableReserveRaw() {
return enableReserveRaw;
}
+
public void enableReserveRaw(boolean enableReserveRaw) {
this.enableReserveRaw = enableReserveRaw;
}
- public static class Builder{
+
+ public static class Builder {
private CompressConfig config;
+
public Builder() {
- config=new CompressConfig();
+ config = new CompressConfig();
}
+
public Builder setMaxSize(int maxSize) {
- config.setMaxSize( maxSize);
+ config.setMaxSize(maxSize);
return this;
}
+
public Builder setMaxPixel(int maxPixel) {
config.setMaxPixel(maxPixel);
return this;
}
+
public Builder enablePixelCompress(boolean enablePixelCompress) {
config.enablePixelCompress(enablePixelCompress);
return this;
}
+
public Builder enableQualityCompress(boolean enableQualityCompress) {
config.enableQualityCompress(enableQualityCompress);
return this;
}
+
public Builder enableReserveRaw(boolean enableReserveRaw) {
config.enableReserveRaw(enableReserveRaw);
return this;
}
- public CompressConfig create(){
+
+ public CompressConfig create() {
return config;
}
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImage.java b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImage.java
similarity index 61%
rename from takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImage.java
rename to takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImage.java
index b48ce191..ef3d32f4 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImage.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImage.java
@@ -1,11 +1,12 @@
-package com.jph.takephoto.compress;
+package org.devio.takephoto.compress;
+
+import org.devio.takephoto.model.TImage;
-import com.jph.takephoto.model.TImage;
import java.util.ArrayList;
/**
* 压缩照片2.0
- *
+ *
* Author JPH
* Date 2015-08-26 下午1:44:26
*/
@@ -18,15 +19,17 @@ public interface CompressImage {
interface CompressListener {
/**
* 压缩成功
+ *
* @param images 已经压缩图片
*/
- void onCompressSuccess(ArrayList images);
+ void onCompressSuccess(ArrayList images);
/**
* 压缩失败
+ *
* @param images 压缩失败的图片
- * @param msg 失败的原因
+ * @param msg 失败的原因
*/
- void onCompressFailed(ArrayList images,String msg);
+ void onCompressFailed(ArrayList images, String msg);
}
}
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImageImpl.java b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImageImpl.java
new file mode 100644
index 00000000..85b9f767
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImageImpl.java
@@ -0,0 +1,105 @@
+package org.devio.takephoto.compress;
+
+import android.content.Context;
+import android.text.TextUtils;
+
+import org.devio.takephoto.model.TImage;
+
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * 压缩照片
+ *
+ * Date: 2016/9/21 0007 20:10
+ * Version:3.0.0
+ * 技术博文:http://www.devio.org
+ * GitHub:https://github.com/crazycodeboy
+ * Email:crazycodeboy@gmail.com
+ */
+public class CompressImageImpl implements CompressImage {
+ private CompressImageUtil compressImageUtil;
+ private ArrayList images;
+ private CompressImage.CompressListener listener;
+
+ public static CompressImage of(Context context, CompressConfig config, ArrayList images,
+ CompressImage.CompressListener listener) {
+ if (config.getLubanOptions() != null) {
+ return new CompressWithLuBan(context, config, images, listener);
+ } else {
+ return new CompressImageImpl(context, config, images, listener);
+ }
+ }
+
+ private CompressImageImpl(Context context, CompressConfig config, ArrayList images, CompressImage.CompressListener listener) {
+ compressImageUtil = new CompressImageUtil(context, config);
+ this.images = images;
+ this.listener = listener;
+ }
+
+ @Override
+ public void compress() {
+ if (images == null || images.isEmpty()) {
+ listener.onCompressFailed(images, " images is null");
+ }
+ for (TImage image : images) {
+ if (image == null) {
+ listener.onCompressFailed(images, " There are pictures of compress is null.");
+ return;
+ }
+ }
+ compress(images.get(0));
+ }
+
+ private void compress(final TImage image) {
+ if (TextUtils.isEmpty(image.getOriginalPath())) {
+ continueCompress(image, false);
+ return;
+ }
+
+ File file = new File(image.getOriginalPath());
+ if (file == null || !file.exists() || !file.isFile()) {
+ continueCompress(image, false);
+ return;
+ }
+
+ compressImageUtil.compress(image.getOriginalPath(), new CompressImageUtil.CompressListener() {
+ @Override
+ public void onCompressSuccess(String imgPath) {
+ image.setCompressPath(imgPath);
+ continueCompress(image, true);
+ }
+
+ @Override
+ public void onCompressFailed(String imgPath, String msg) {
+ continueCompress(image, false, msg);
+ }
+ });
+ }
+
+ private void continueCompress(TImage image, boolean preSuccess, String... message) {
+ image.setCompressed(preSuccess);
+ int index = images.indexOf(image);
+ boolean isLast = index == images.size() - 1;
+ if (isLast) {
+ handleCompressCallBack(message);
+ } else {
+ compress(images.get(index + 1));
+ }
+ }
+
+ private void handleCompressCallBack(String... message) {
+ if (message.length > 0) {
+ listener.onCompressFailed(images, message[0]);
+ return;
+ }
+
+ for (TImage image : images) {
+ if (!image.isCompressed()) {
+ listener.onCompressFailed(images, image.getCompressPath() + " is compress failures");
+ return;
+ }
+ }
+ listener.onCompressSuccess(images);
+ }
+}
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImageUtil.java b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImageUtil.java
new file mode 100644
index 00000000..372d3224
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressImageUtil.java
@@ -0,0 +1,184 @@
+package org.devio.takephoto.compress;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.os.Handler;
+
+import org.devio.takephoto.uitl.TFileUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+
+/**
+ * 压缩照片
+ *
+ * @author JPH
+ * Date 2015-08-26 下午1:44:26
+ * Version:1.0.3
+ */
+public class CompressImageUtil {
+ private CompressConfig config;
+ private Context context;
+ Handler mhHandler = new Handler();
+
+ public CompressImageUtil(Context context, CompressConfig config) {
+ this.context = context;
+ this.config = config == null ? CompressConfig.ofDefaultConfig() : config;
+ }
+
+ public void compress(String imagePath, CompressListener listener) {
+ if (config.isEnablePixelCompress()) {
+ try {
+ compressImageByPixel(imagePath, listener);
+ } catch (FileNotFoundException e) {
+ listener.onCompressFailed(imagePath, String.format("图片压缩失败,%s", e.toString()));
+ e.printStackTrace();
+ }
+ } else {
+ compressImageByQuality(BitmapFactory.decodeFile(imagePath), imagePath, listener);
+ }
+ }
+
+ /**
+ * 多线程压缩图片的质量
+ *
+ * @param bitmap 内存中的图片
+ * @param imgPath 图片的保存路径
+ * @author JPH
+ * @date 2014-12-5下午11:30:43
+ */
+ private void compressImageByQuality(final Bitmap bitmap, final String imgPath, final CompressListener listener) {
+ if (bitmap == null) {
+ sendMsg(false, imgPath, "像素压缩失败,bitmap is null", listener);
+ return;
+ }
+ new Thread(new Runnable() {//开启多线程进行压缩处理
+ @Override
+ public void run() {
+ // TODO Auto-generated method stub
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int options = 100;
+ bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小)
+ while (baos.toByteArray().length > config.getMaxSize()) {//循环判断如果压缩后图片是否大于指定大小,大于继续压缩
+ baos.reset();//重置baos即让下一次的写入覆盖之前的内容
+ options -= 5;//图片质量每次减少5
+ if (options <= 5) {
+ options = 5;//如果图片质量小于5,为保证压缩后的图片质量,图片最底压缩质量为5
+ }
+ bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中
+ if (options == 5) {
+ break;//如果图片的质量已降到最低则,不再进行压缩
+ }
+ }
+ // if(bitmap!=null&&!bitmap.isRecycled()){
+ // bitmap.recycle();//回收内存中的图片
+ // }
+ try {
+ File thumbnailFile = getThumbnailFile(new File(imgPath));
+ FileOutputStream fos = new FileOutputStream(thumbnailFile);//将压缩后的图片保存的本地上指定路径中
+ fos.write(baos.toByteArray());
+ fos.flush();
+ fos.close();
+ sendMsg(true, thumbnailFile.getPath(), null, listener);
+ } catch (Exception e) {
+ sendMsg(false, imgPath, "质量压缩失败", listener);
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+
+ /**
+ * 按比例缩小图片的像素以达到压缩的目的
+ *
+ * @param imgPath
+ * @return
+ * @author JPH
+ * @date 2014-12-5下午11:30:59
+ */
+ private void compressImageByPixel(String imgPath, CompressListener listener) throws FileNotFoundException {
+ if (imgPath == null) {
+ sendMsg(false, imgPath, "要压缩的文件不存在", listener);
+ return;
+ }
+ BitmapFactory.Options newOpts = new BitmapFactory.Options();
+ newOpts.inJustDecodeBounds = true;//只读边,不读内容
+ BitmapFactory.decodeFile(imgPath, newOpts);
+ newOpts.inJustDecodeBounds = false;
+ int width = newOpts.outWidth;
+ int height = newOpts.outHeight;
+ float maxSize = config.getMaxPixel();
+ int be = 1;
+ if (width >= height && width > maxSize) {//缩放比,用高或者宽其中较大的一个数据进行计算
+ be = (int) (newOpts.outWidth / maxSize);
+ be++;
+ } else if (width < height && height > maxSize) {
+ be = (int) (newOpts.outHeight / maxSize);
+ be++;
+ }
+ newOpts.inSampleSize = be;//设置采样率
+ newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设
+ newOpts.inPurgeable = true;// 同时设置才会有效
+ newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
+ Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
+ if (config.isEnableQualityCompress()) {
+ compressImageByQuality(bitmap, imgPath, listener);//压缩好比例大小后再进行质量压缩
+ } else {
+ File thumbnailFile = getThumbnailFile(new File(imgPath));
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(thumbnailFile));
+
+ listener.onCompressSuccess(thumbnailFile.getPath());
+ }
+ }
+
+ /**
+ * 发送压缩结果的消息
+ *
+ * @param isSuccess 压缩是否成功
+ * @param imagePath
+ * @param message
+ */
+ private void sendMsg(final boolean isSuccess, final String imagePath, final String message, final CompressListener listener) {
+ mhHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (isSuccess) {
+ listener.onCompressSuccess(imagePath);
+ } else {
+ listener.onCompressFailed(imagePath, message);
+ }
+ }
+ });
+ }
+
+ private File getThumbnailFile(File file) {
+ if (file == null || !file.exists()) {
+ return file;
+ }
+ return TFileUtils.getPhotoCacheDir(context, file);
+ }
+
+ /**
+ * 压缩结果监听器
+ */
+ public interface CompressListener {
+ /**
+ * 压缩成功
+ *
+ * @param imgPath 压缩图片的路径
+ */
+ void onCompressSuccess(String imgPath);
+
+ /**
+ * 压缩失败
+ *
+ * @param imgPath 压缩失败的图片
+ * @param msg 失败的原因
+ */
+ void onCompressFailed(String imgPath, String msg);
+ }
+}
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressWithLuBan.java b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressWithLuBan.java
new file mode 100644
index 00000000..83082439
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/compress/CompressWithLuBan.java
@@ -0,0 +1,118 @@
+package org.devio.takephoto.compress;
+
+import android.content.Context;
+
+import org.devio.takephoto.model.LubanOptions;
+import org.devio.takephoto.model.TImage;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import me.shaohui.advancedluban.Luban;
+import me.shaohui.advancedluban.OnCompressListener;
+import me.shaohui.advancedluban.OnMultiCompressListener;
+
+/**
+ * 压缩照片,采用luban
+ * Author: crazycodeboy
+ * Date: 2016/11/5 0007 20:10
+ * Version:4.0.0
+ * 技术博文:http://www.devio.org/
+ * GitHub:https://github.com/crazycodeboy
+ * Email:crazycodeboy@gmail.com
+ */
+public class CompressWithLuBan implements CompressImage {
+ private ArrayList images;
+ private CompressListener listener;
+ private Context context;
+ private LubanOptions options;
+ private ArrayList files = new ArrayList<>();
+
+ public CompressWithLuBan(Context context, CompressConfig config, ArrayList images, CompressListener listener) {
+ options = config.getLubanOptions();
+ this.images = images;
+ this.listener = listener;
+ this.context = context;
+ }
+
+ @Override
+ public void compress() {
+ if (images == null || images.isEmpty()) {
+ listener.onCompressFailed(images, " images is null");
+ return;
+ }
+ for (TImage image : images) {
+ if (image == null) {
+ listener.onCompressFailed(images, " There are pictures of compress is null.");
+ return;
+ }
+ files.add(new File(image.getOriginalPath()));
+ }
+ if (images.size() == 1) {
+ compressOne();
+ } else {
+ compressMulti();
+ }
+ }
+
+ private void compressOne() {
+ Luban.compress(context, files.get(0))
+ .putGear(Luban.CUSTOM_GEAR)
+ .setMaxHeight(options.getMaxHeight())
+ .setMaxWidth(options.getMaxWidth())
+ .setMaxSize(options.getMaxSize() / 1000)
+ .launch(new OnCompressListener() {
+ @Override
+ public void onStart() {
+
+ }
+
+ @Override
+ public void onSuccess(File file) {
+ TImage image = images.get(0);
+ image.setCompressPath(file.getPath());
+ image.setCompressed(true);
+ listener.onCompressSuccess(images);
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ listener.onCompressFailed(images, e.getMessage() + " is compress failures");
+ }
+ });
+ }
+
+ private void compressMulti() {
+ Luban.compress(context, files)
+ .putGear(Luban.CUSTOM_GEAR)
+ .setMaxSize(options.getMaxSize() / 1000) // limit the final image size(unit:Kb)
+ .setMaxHeight(options.getMaxHeight()) // limit image height
+ .setMaxWidth(options.getMaxWidth())
+ .launch(new OnMultiCompressListener() {
+ @Override
+ public void onStart() {
+
+ }
+
+ @Override
+ public void onSuccess(List fileList) {
+ handleCompressCallBack(fileList);
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ listener.onCompressFailed(images, e.getMessage() + " is compress failures");
+ }
+ });
+ }
+
+ private void handleCompressCallBack(List files) {
+ for (int i = 0, j = images.size(); i < j; i++) {
+ TImage image = images.get(i);
+ image.setCompressed(true);
+ image.setCompressPath(files.get(i).getPath());
+ }
+ listener.onCompressSuccess(images);
+ }
+}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/CropOptions.java b/takephoto_library/src/main/java/org/devio/takephoto/model/CropOptions.java
similarity index 85%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/CropOptions.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/CropOptions.java
index 0d579ebd..7b528b87 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/CropOptions.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/CropOptions.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import java.io.Serializable;
@@ -7,14 +7,18 @@
* Author: JPH
* Date: 2016/7/27 13:19
*/
-public class CropOptions implements Serializable{
- /**使用TakePhoto自带的裁切工具进行裁切*/
+public class CropOptions implements Serializable {
+ /**
+ * 使用TakePhoto自带的裁切工具进行裁切
+ */
private boolean withOwnCrop;
private int aspectX;
private int aspectY;
private int outputX;
private int outputY;
- private CropOptions(){}
+
+ private CropOptions() {
+ }
public int getAspectX() {
return aspectX;
@@ -56,11 +60,11 @@ public void setWithOwnCrop(boolean withOwnCrop) {
this.withOwnCrop = withOwnCrop;
}
- public static class Builder{
+ public static class Builder {
private CropOptions options;
public Builder() {
- options=new CropOptions();
+ options = new CropOptions();
}
public Builder setAspectX(int aspectX) {
@@ -87,7 +91,8 @@ public Builder setWithOwnCrop(boolean withOwnCrop) {
options.setWithOwnCrop(withOwnCrop);
return this;
}
- public CropOptions create(){
+
+ public CropOptions create() {
return options;
}
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/InvokeParam.java b/takephoto_library/src/main/java/org/devio/takephoto/model/InvokeParam.java
similarity index 95%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/InvokeParam.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/InvokeParam.java
index 160feebb..b6677cc4 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/InvokeParam.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/InvokeParam.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import java.lang.reflect.Method;
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/LubanOptions.java b/takephoto_library/src/main/java/org/devio/takephoto/model/LubanOptions.java
similarity index 69%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/LubanOptions.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/LubanOptions.java
index 555bc2e1..96c3d082 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/LubanOptions.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/LubanOptions.java
@@ -1,9 +1,7 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import java.io.Serializable;
-import me.shaohui.advancedluban.Luban;
-
/**
* Luban配置类
* Author: crazycodeboy
@@ -11,17 +9,18 @@
* Version:4.0.1
* 技术博文:http://www.devio.org/
* GitHub:https://github.com/crazycodeboy
- * Eamil:crazycodeboy@gmail.com
+ * Email:crazycodeboy@gmail.com
*/
-public class LubanOptions implements Serializable{
+public class LubanOptions implements Serializable {
/**
* 压缩到的最大大小,单位B
*/
private int maxSize;
private int maxHeight;
private int maxWidth;
- private int gear= Luban.CUSTOM_GEAR;
- private LubanOptions(){}
+
+ private LubanOptions() {
+ }
public int getMaxSize() {
return maxSize;
@@ -47,19 +46,11 @@ public void setMaxWidth(int maxWidth) {
this.maxWidth = maxWidth;
}
- public int getGear() {
- return gear;
- }
-
- public void setGear(int gear) {
- this.gear = gear;
- }
-
- public static class Builder{
+ public static class Builder {
private LubanOptions options;
public Builder() {
- options=new LubanOptions();
+ options = new LubanOptions();
}
public Builder setMaxSize(int maxSize) {
@@ -77,11 +68,7 @@ public Builder setMaxWidth(int maxWidth) {
return this;
}
- public Builder setGear(int gear) {
- options.setGear(gear);
- return this;
- }
- public LubanOptions create(){
+ public LubanOptions create() {
return options;
}
}
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/model/MultipleCrop.java b/takephoto_library/src/main/java/org/devio/takephoto/model/MultipleCrop.java
new file mode 100644
index 00000000..f8df7a66
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/MultipleCrop.java
@@ -0,0 +1,91 @@
+package org.devio.takephoto.model;
+
+import android.app.Activity;
+import android.net.Uri;
+
+import org.devio.takephoto.uitl.TImageFiles;
+import org.devio.takephoto.uitl.TUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Author: JPH
+ * Date: 2016/8/11 17:01
+ */
+public class MultipleCrop {
+ private ArrayList uris;
+ private ArrayList outUris;
+ private ArrayList tImages;
+ private TImage.FromType fromType;
+ public boolean hasFailed;//是否有裁切失败的标识
+
+ public static MultipleCrop of(ArrayList uris, Activity activity, TImage.FromType fromType) throws TException {
+ return new MultipleCrop(uris, activity, fromType);
+ }
+
+ public static MultipleCrop of(ArrayList uris, ArrayList outUris, TImage.FromType fromType) {
+ return new MultipleCrop(uris, outUris, fromType);
+ }
+
+ private MultipleCrop(ArrayList uris, Activity activity, TImage.FromType fromType) throws TException {
+ this.uris = uris;
+ ArrayList outUris = new ArrayList<>();
+ for (Uri uri : uris) {
+ outUris.add(Uri.fromFile(TImageFiles.getTempFile(activity, uri)));//生成临时裁切输出路径
+ }
+ this.outUris = outUris;
+ this.tImages = TUtils.getTImagesWithUris(outUris, fromType);
+ this.fromType = fromType;
+ }
+
+ private MultipleCrop(ArrayList uris, ArrayList outUris, TImage.FromType fromType) {
+ this.uris = uris;
+ this.outUris = outUris;
+ this.tImages = TUtils.getTImagesWithUris(outUris, fromType);
+ this.fromType = fromType;
+ }
+
+ public ArrayList getUris() {
+ return uris;
+ }
+
+ public void setUris(ArrayList uris) {
+ this.uris = uris;
+ }
+
+ public ArrayList getOutUris() {
+ return outUris;
+ }
+
+ public void setOutUris(ArrayList outUris) {
+ this.outUris = outUris;
+ }
+
+ public ArrayList gettImages() {
+ return tImages;
+ }
+
+ public void settImages(ArrayList tImages) {
+ this.tImages = tImages;
+ }
+
+ /**
+ * 为被裁切的图片设置已被裁切的标识
+ *
+ * @param uri 被裁切的图片
+ * @return 该图片是否是最后一张
+ */
+ public Map setCropWithUri(Uri uri, boolean cropped) {
+ if (!cropped) {
+ hasFailed = true;
+ }
+ int index = outUris.indexOf(uri);
+ tImages.get(index).setCropped(cropped);
+ Map result = new HashMap();
+ result.put("index", index);
+ result.put("isLast", index == outUris.size() - 1 ? true : false);
+ return result;
+ }
+}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/TContextWrap.java b/takephoto_library/src/main/java/org/devio/takephoto/model/TContextWrap.java
similarity index 80%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/TContextWrap.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/TContextWrap.java
index 439a30be..80e6bcfc 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/TContextWrap.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/TContextWrap.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import android.app.Activity;
import android.support.v4.app.Fragment;
@@ -10,19 +10,22 @@
public class TContextWrap {
private Activity activity;
private Fragment fragment;
- public static TContextWrap of(Activity activity){
+
+ public static TContextWrap of(Activity activity) {
return new TContextWrap(activity);
}
- public static TContextWrap of(Fragment fragment){
+
+ public static TContextWrap of(Fragment fragment) {
return new TContextWrap(fragment);
}
+
private TContextWrap(Activity activity) {
this.activity = activity;
}
private TContextWrap(Fragment fragment) {
this.fragment = fragment;
- this.activity=fragment.getActivity();
+ this.activity = fragment.getActivity();
}
public Activity getActivity() {
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/TException.java b/takephoto_library/src/main/java/org/devio/takephoto/model/TException.java
similarity index 64%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/TException.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/TException.java
index 844f36c3..1048756f 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/TException.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/TException.java
@@ -1,15 +1,17 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
/**
* Author: JPH
* Date: 2016/7/26 10:53
*/
-public class TException extends Exception{
+public class TException extends Exception {
String detailMessage;
+
public TException(TExceptionType exceptionType) {
super(exceptionType.getStringValue());
- this.detailMessage=exceptionType.getStringValue();
+ this.detailMessage = exceptionType.getStringValue();
}
+
public String getDetailMessage() {
return detailMessage;
}
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/model/TExceptionType.java b/takephoto_library/src/main/java/org/devio/takephoto/model/TExceptionType.java
new file mode 100644
index 00000000..b454b0a9
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/TExceptionType.java
@@ -0,0 +1,21 @@
+package org.devio.takephoto.model;
+
+/**
+ * Author: JPH
+ * Date: 2016/7/26 11:01
+ */
+public enum TExceptionType {
+ TYPE_NOT_IMAGE("选择的文件不是图片"), TYPE_WRITE_FAIL("保存选择的的文件失败"), TYPE_URI_NULL("所选照片的Uri 为null"), TYPE_URI_PARSE_FAIL("从Uri中获取文件路径失败"),
+ TYPE_NO_MATCH_PICK_INTENT("没有匹配到选择图片的Intent"), TYPE_NO_MATCH_CROP_INTENT("没有匹配到裁切图片的Intent"), TYPE_NO_CAMERA("没有相机"),
+ TYPE_NO_FIND("选择的文件没有找到");
+
+ String stringValue;
+
+ TExceptionType(String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public String getStringValue() {
+ return stringValue;
+ }
+}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/TImage.java b/takephoto_library/src/main/java/org/devio/takephoto/model/TImage.java
similarity index 87%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/TImage.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/TImage.java
index af661498..35374670 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/TImage.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/TImage.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import android.net.Uri;
@@ -6,26 +6,30 @@
/**
* TakePhoto 操作成功返回的处理结果
- *
+ *
* Author: JPH
* Date: 2016/8/11 17:01
*/
-public class TImage implements Serializable{
+public class TImage implements Serializable {
private String originalPath;
private String compressPath;
private FromType fromType;
private boolean cropped;
private boolean compressed;
- public static TImage of(String path, FromType fromType){
+
+ public static TImage of(String path, FromType fromType) {
return new TImage(path, fromType);
}
- public static TImage of(Uri uri, FromType fromType){
+
+ public static TImage of(Uri uri, FromType fromType) {
return new TImage(uri, fromType);
}
+
private TImage(String path, FromType fromType) {
this.originalPath = path;
this.fromType = fromType;
}
+
private TImage(Uri uri, FromType fromType) {
this.originalPath = uri.getPath();
this.fromType = fromType;
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/TIntentWap.java b/takephoto_library/src/main/java/org/devio/takephoto/model/TIntentWap.java
similarity index 94%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/TIntentWap.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/TIntentWap.java
index 4517acfc..7ac24c90 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/TIntentWap.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/TIntentWap.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import android.content.Intent;
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/TResult.java b/takephoto_library/src/main/java/org/devio/takephoto/model/TResult.java
similarity index 66%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/TResult.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/TResult.java
index bc639883..476bda80 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/TResult.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/TResult.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import java.util.ArrayList;
@@ -8,19 +8,24 @@
* Date: 2016/8/11 17:01
*/
public class TResult {
- private ArrayList images;
+ private ArrayList images;
private TImage image;
- public static TResult of(TImage image){
- ArrayList images=new ArrayList<>(1);
+
+ public static TResult of(TImage image) {
+ ArrayList images = new ArrayList<>(1);
images.add(image);
return new TResult(images);
}
- public static TResult of(ArrayList images){
+
+ public static TResult of(ArrayList images) {
return new TResult(images);
}
+
private TResult(ArrayList images) {
this.images = images;
- if(images!=null&&!images.isEmpty())this.image=images.get(0);
+ if (images != null && !images.isEmpty()) {
+ this.image = images.get(0);
+ }
}
public ArrayList getImages() {
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/TakePhotoOptions.java b/takephoto_library/src/main/java/org/devio/takephoto/model/TakePhotoOptions.java
similarity index 92%
rename from takephoto_library/src/main/java/com/jph/takephoto/model/TakePhotoOptions.java
rename to takephoto_library/src/main/java/org/devio/takephoto/model/TakePhotoOptions.java
index 49f2a2a1..415acd71 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/TakePhotoOptions.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/model/TakePhotoOptions.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.model;
+package org.devio.takephoto.model;
import java.io.Serializable;
@@ -8,7 +8,7 @@
* Version:4.0.0
* 技术博文:http://www.devio.org/
* GitHub:https://github.com/crazycodeboy
- * Eamil:crazycodeboy@gmail.com
+ * Email:crazycodeboy@gmail.com
*/
public class TakePhotoOptions implements Serializable {
/**
@@ -50,11 +50,13 @@ public Builder setWithOwnGallery(boolean withOwnGallery) {
options.setWithOwnGallery(withOwnGallery);
return this;
}
+
public Builder setCorrectImage(boolean isCorrectImage) {
options.setCorrectImage(isCorrectImage);
return this;
}
- public TakePhotoOptions create(){
+
+ public TakePhotoOptions create() {
return options;
}
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/permission/InvokeListener.java b/takephoto_library/src/main/java/org/devio/takephoto/permission/InvokeListener.java
similarity index 61%
rename from takephoto_library/src/main/java/com/jph/takephoto/permission/InvokeListener.java
rename to takephoto_library/src/main/java/org/devio/takephoto/permission/InvokeListener.java
index 45297cee..398384da 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/permission/InvokeListener.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/permission/InvokeListener.java
@@ -1,6 +1,6 @@
-package com.jph.takephoto.permission;
+package org.devio.takephoto.permission;
-import com.jph.takephoto.model.InvokeParam;
+import org.devio.takephoto.model.InvokeParam;
/**
* 授权管理回调
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/permission/PermissionManager.java b/takephoto_library/src/main/java/org/devio/takephoto/permission/PermissionManager.java
new file mode 100644
index 00000000..71fb2f57
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/permission/PermissionManager.java
@@ -0,0 +1,164 @@
+package org.devio.takephoto.permission;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.text.TextUtils;
+import android.widget.Toast;
+
+import org.devio.takephoto.app.TakePhoto;
+import org.devio.takephoto.model.InvokeParam;
+import org.devio.takephoto.model.TContextWrap;
+import org.devio.takephoto.uitl.TConstant;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+/**
+ * Created by penn on 16/9/22.
+ */
+public class PermissionManager {
+ public enum TPermission {
+ STORAGE(Manifest.permission.WRITE_EXTERNAL_STORAGE), CAMERA(Manifest.permission.CAMERA);
+ String stringValue;
+
+ TPermission(String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public String stringValue() {
+ return stringValue;
+ }
+ }
+
+
+ public enum TPermissionType {
+ GRANTED("已授权"), DENIED("未授权"), WAIT("等待授权"), NOT_NEED("无需授权"), ONLY_CAMERA_DENIED("没有拍照权限"), ONLY_STORAGE_DENIED("没有读写SD卡权限");
+ String stringValue;
+
+ TPermissionType(String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public String stringValue() {
+ return stringValue;
+ }
+ }
+
+
+ private final static String[] methodNames =
+ {"onPickFromCapture", "onPickFromCaptureWithCrop", "onPickMultiple", "onPickMultipleWithCrop", "onPickFromDocuments",
+ "onPickFromDocumentsWithCrop", "onPickFromGallery", "onPickFromGalleryWithCrop", "onCrop"};
+
+ /**
+ * 检查当前应用是否被授予相应权限
+ *
+ * @param contextWrap
+ * @param method
+ * @return
+ */
+ public static TPermissionType checkPermission(@NonNull TContextWrap contextWrap, @NonNull Method method) {
+ String methodName = method.getName();
+ boolean contain = false;
+ for (int i = 0, j = methodNames.length; i < j; i++) {
+ if (TextUtils.equals(methodName, methodNames[i])) {
+ contain = true;
+ break;
+ }
+ }
+ if (!contain) {
+ return TPermissionType.NOT_NEED;
+ }
+
+ boolean cameraGranted = true, storageGranted =
+ ContextCompat.checkSelfPermission(contextWrap.getActivity(), TPermission.STORAGE.stringValue())
+ == PackageManager.PERMISSION_GRANTED ? true : false;
+
+ if (TextUtils.equals(methodName, "onPickFromCapture") || TextUtils.equals(methodName, "onPickFromCaptureWithCrop")) {
+ cameraGranted = ContextCompat.checkSelfPermission(contextWrap.getActivity(), TPermission.CAMERA.stringValue())
+ == PackageManager.PERMISSION_GRANTED ? true : false;
+ }
+
+ boolean granted = storageGranted && cameraGranted;
+ if (!granted) {
+ ArrayList permissions = new ArrayList<>();
+ if (!storageGranted) {
+ permissions.add(TPermission.STORAGE.stringValue());
+ }
+ if (!cameraGranted) {
+ permissions.add(TPermission.CAMERA.stringValue());
+ }
+ requestPermission(contextWrap, permissions.toArray(new String[permissions.size()]));
+ }
+ return granted ? TPermissionType.GRANTED : TPermissionType.WAIT;
+ }
+
+ public static void requestPermission(@NonNull TContextWrap contextWrap, @NonNull String[] permissions) {
+ if (contextWrap.getFragment() != null) {
+ contextWrap.getFragment().requestPermissions(permissions, TConstant.PERMISSION_REQUEST_TAKE_PHOTO);
+ } else {
+ ActivityCompat.requestPermissions(contextWrap.getActivity(), permissions, TConstant.PERMISSION_REQUEST_TAKE_PHOTO);
+ }
+ }
+
+ public static TPermissionType onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ if (requestCode == TConstant.PERMISSION_REQUEST_TAKE_PHOTO) {
+ boolean cameraGranted = true, storageGranted = true;
+ for (int i = 0, j = permissions.length; i < j; i++) {
+ if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
+ if (TextUtils.equals(TPermission.STORAGE.stringValue(), permissions[i])) {
+ storageGranted = false;
+ } else if (TextUtils.equals(TPermission.CAMERA.stringValue(), permissions[i])) {
+ cameraGranted = false;
+ }
+ }
+ }
+ if (cameraGranted && storageGranted) {
+ return TPermissionType.GRANTED;
+ }
+ if (!cameraGranted && storageGranted) {
+ return TPermissionType.ONLY_CAMERA_DENIED;
+ }
+ if (!storageGranted && cameraGranted) {
+ return TPermissionType.ONLY_STORAGE_DENIED;
+ }
+ if (!storageGranted && !cameraGranted) {
+ return TPermissionType.DENIED;
+ }
+ }
+ return TPermissionType.WAIT;
+ }
+
+ public static void handlePermissionsResult(Activity activity, TPermissionType type, InvokeParam invokeParam,
+ TakePhoto.TakeResultListener listener) {
+ String tip = null;
+ switch (type) {
+ case DENIED:
+ listener.takeFail(null, tip = activity.getResources().getString(org.devio.takephoto.R.string.tip_permission_camera_storage));
+ break;
+ case ONLY_CAMERA_DENIED:
+ listener.takeFail(null, tip = activity.getResources().getString(org.devio.takephoto.R.string.tip_permission_camera));
+ break;
+ case ONLY_STORAGE_DENIED:
+ listener.takeFail(null, tip = activity.getResources().getString(org.devio.takephoto.R.string.tip_permission_storage));
+ break;
+ case GRANTED:
+ try {
+ invokeParam.getMethod().invoke(invokeParam.getProxy(), invokeParam.getArgs());
+ } catch (Exception e) {
+ e.printStackTrace();
+ listener.takeFail(null, tip = activity.getResources().getString(org.devio.takephoto.R.string.tip_permission_camera_storage));
+ }
+ break;
+ default:
+ break;
+ }
+ if (tip != null) {
+ Toast.makeText(activity, tip, Toast.LENGTH_LONG).show();
+ }
+
+ }
+}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/permission/TakePhotoInvocationHandler.java b/takephoto_library/src/main/java/org/devio/takephoto/permission/TakePhotoInvocationHandler.java
similarity index 64%
rename from takephoto_library/src/main/java/com/jph/takephoto/permission/TakePhotoInvocationHandler.java
rename to takephoto_library/src/main/java/org/devio/takephoto/permission/TakePhotoInvocationHandler.java
index 538b821f..475a03fc 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/permission/TakePhotoInvocationHandler.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/permission/TakePhotoInvocationHandler.java
@@ -1,25 +1,27 @@
-package com.jph.takephoto.permission;
+package org.devio.takephoto.permission;
-import com.jph.takephoto.app.TakePhoto;
-import com.jph.takephoto.model.InvokeParam;
+import org.devio.takephoto.app.TakePhoto;
+import org.devio.takephoto.model.InvokeParam;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-public class TakePhotoInvocationHandler implements InvocationHandler{
+public class TakePhotoInvocationHandler implements InvocationHandler {
private TakePhoto delegate;
private InvokeListener listener;
- public static TakePhotoInvocationHandler of(InvokeListener listener){
+
+ public static TakePhotoInvocationHandler of(InvokeListener listener) {
return new TakePhotoInvocationHandler(listener);
}
private TakePhotoInvocationHandler(InvokeListener listener) {
- this.listener=listener;
+ this.listener = listener;
}
/**
* 绑定委托对象并返回一个代理类
+ *
* @param delegate
* @return
*/
@@ -27,13 +29,13 @@ public Object bind(TakePhoto delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this);
}
+
@Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- PermissionManager.TPermissionType type=listener.invoke(new InvokeParam(proxy,method,args));
- if(proxy instanceof TakePhoto){
- if(!PermissionManager.TPermissionType.NOT_NEED.equals(type)){
- ((TakePhoto)proxy).permissionNotify(type);
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ PermissionManager.TPermissionType type = listener.invoke(new InvokeParam(proxy, method, args));
+ if (proxy instanceof TakePhoto) {
+ if (!PermissionManager.TPermissionType.NOT_NEED.equals(type)) {
+ ((TakePhoto) proxy).permissionNotify(type);
}
}
return method.invoke(delegate, args);
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/uitl/ImageRotateUtil.java b/takephoto_library/src/main/java/org/devio/takephoto/uitl/ImageRotateUtil.java
similarity index 77%
rename from takephoto_library/src/main/java/com/jph/takephoto/uitl/ImageRotateUtil.java
rename to takephoto_library/src/main/java/org/devio/takephoto/uitl/ImageRotateUtil.java
index ee4aaa1f..01295dd0 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/ImageRotateUtil.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/uitl/ImageRotateUtil.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.uitl;
+package org.devio.takephoto.uitl;
import android.content.Context;
import android.graphics.Bitmap;
@@ -17,13 +17,13 @@
* Author: crazycodeboy
* Date: 2016/9/21 0007 20:10
* Version:3.0.0
- * 技术博文:http://www.cboy.me
+ * 技术博文:http://www.devio.org
* GitHub:https://github.com/crazycodeboy
- * Eamil:crazycodeboy@gmail.com
+ * Email:crazycodeboy@gmail.com
*/
public class ImageRotateUtil {
- public static ImageRotateUtil of(){
+ public static ImageRotateUtil of() {
return new ImageRotateUtil();
}
@@ -32,22 +32,27 @@ private ImageRotateUtil() {
/**
* 纠正照片的旋转角度
+ *
* @param path
*/
- public void correctImage(Context context,Uri path){
+ public void correctImage(Context context, Uri path) {
- String imagePath=TUriParse.parseOwnUri(context,path);
+ String imagePath = TUriParse.parseOwnUri(context, path);
int degree;
- if((degree=getBitmapDegree(imagePath))!=0){
- Bitmap bitmap= BitmapFactory.decodeFile(imagePath);
- if(bitmap==null)return;
- Bitmap resultBitmap=rotateBitmapByDegree(bitmap,degree);
- if(resultBitmap==null)return;
+ if ((degree = getBitmapDegree(imagePath)) != 0) {
+ Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
+ if (bitmap == null) {
+ return;
+ }
+ Bitmap resultBitmap = rotateBitmapByDegree(bitmap, degree);
+ if (resultBitmap == null) {
+ return;
+ }
try {
- resultBitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(new File(imagePath)));
+ resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(imagePath)));
} catch (FileNotFoundException e) {
e.printStackTrace();
- }catch (OutOfMemoryError e){
+ } catch (OutOfMemoryError e) {
e.printStackTrace();
}
}
@@ -65,8 +70,7 @@ private int getBitmapDegree(String path) {
// 从指定路径下读取图片,并获取其EXIF信息
ExifInterface exifInterface = new ExifInterface(path);
// 获取图片的旋转信息
- int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
- ExifInterface.ORIENTATION_NORMAL);
+ int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/uitl/IntentUtils.java b/takephoto_library/src/main/java/org/devio/takephoto/uitl/IntentUtils.java
similarity index 86%
rename from takephoto_library/src/main/java/com/jph/takephoto/uitl/IntentUtils.java
rename to takephoto_library/src/main/java/org/devio/takephoto/uitl/IntentUtils.java
index 4b54c475..880559b9 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/IntentUtils.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/uitl/IntentUtils.java
@@ -1,14 +1,15 @@
-package com.jph.takephoto.uitl;
+package org.devio.takephoto.uitl;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
+
import com.darsh.multipleimageselect.activities.AlbumSelectActivity;
import com.darsh.multipleimageselect.helpers.Constants;
-import com.jph.takephoto.model.CropOptions;
-import com.jph.takephoto.model.TContextWrap;
+import org.devio.takephoto.model.CropOptions;
+import org.devio.takephoto.model.TContextWrap;
/**
* Intent工具类用于生成拍照、
@@ -20,20 +21,22 @@ public class IntentUtils {
private static final String TAG = IntentUtils.class.getName();
/**
- * 获取图片多选的Intent
+ * 获取图片多选的Intent
+ *
* @param limit 最多选择图片张数的限制
- * */
- public static Intent getPickMultipleIntent(TContextWrap contextWrap, int limit){
+ */
+ public static Intent getPickMultipleIntent(TContextWrap contextWrap, int limit) {
Intent intent = new Intent(contextWrap.getActivity(), AlbumSelectActivity.class);
- intent.putExtra(Constants.INTENT_EXTRA_LIMIT, limit>0? limit:1);
+ intent.putExtra(Constants.INTENT_EXTRA_LIMIT, limit > 0 ? limit : 1);
return intent;
}
/**
* 获取裁剪照片的Intent
+ *
* @param targetUri 要裁剪的照片
* @param outPutUri 裁剪完成的照片
- * @param options 裁剪配置
+ * @param options 裁剪配置
* @return
*/
public static Intent getCropIntentWithOtherApp(Uri targetUri, Uri outPutUri, CropOptions options) {
@@ -43,11 +46,11 @@ public static Intent getCropIntentWithOtherApp(Uri targetUri, Uri outPutUri, Cro
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(targetUri, "image/*");
intent.putExtra("crop", "true");
- if (options.getAspectX()*options.getAspectY()>0){
+ if (options.getAspectX() * options.getAspectY() > 0) {
intent.putExtra("aspectX", options.getAspectX());
intent.putExtra("aspectY", options.getAspectY());
}
- if (options.getOutputX()*options.getOutputY()>0){
+ if (options.getOutputX() * options.getOutputY() > 0) {
intent.putExtra("outputX", options.getOutputX());
intent.putExtra("outputY", options.getOutputY());
}
@@ -61,6 +64,7 @@ public static Intent getCropIntentWithOtherApp(Uri targetUri, Uri outPutUri, Cro
/**
* 获取拍照的Intent
+ *
* @return
*/
public static Intent getCaptureIntent(Uri outPutUri) {
@@ -70,8 +74,10 @@ public static Intent getCaptureIntent(Uri outPutUri) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);//将拍取的照片保存到指定URI
return intent;
}
+
/**
* 获取选择照片的Intent
+ *
* @return
*/
public static Intent getPickIntentWithGallery() {
@@ -80,8 +86,10 @@ public static Intent getPickIntentWithGallery() {
intent.setType("image/*");//从所有图片中进行选择
return intent;
}
+
/**
* 获取从文件中选择照片的Intent
+ *
* @return
*/
public static Intent getPickIntentWithDocuments() {
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TConstant.java b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TConstant.java
similarity index 90%
rename from takephoto_library/src/main/java/com/jph/takephoto/uitl/TConstant.java
rename to takephoto_library/src/main/java/org/devio/takephoto/uitl/TConstant.java
index 6aa9ead7..2bfdb902 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TConstant.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TConstant.java
@@ -1,11 +1,12 @@
-package com.jph.takephoto.uitl;
+package org.devio.takephoto.uitl;
import android.content.Context;
/**
* 常量类
+ *
* @author JPH
- * Date 2016/6/7 0007 9:39
+ * Date 2016/6/7 0007 9:39
*/
public class TConstant {
@@ -49,7 +50,7 @@ public class TConstant {
**/
public final static int PERMISSION_REQUEST_TAKE_PHOTO = 2000;
- public final static String getFileProviderName(Context context){
- return context.getPackageName()+".fileprovider";
+ public final static String getFileProviderName(Context context) {
+ return context.getPackageName() + ".fileprovider";
}
- }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TFileUtils.java b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TFileUtils.java
similarity index 78%
rename from takephoto_library/src/main/java/com/jph/takephoto/uitl/TFileUtils.java
rename to takephoto_library/src/main/java/org/devio/takephoto/uitl/TFileUtils.java
index 90a17403..2856e794 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TFileUtils.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TFileUtils.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.uitl;
+package org.devio.takephoto.uitl;
import android.content.Context;
import android.util.Log;
@@ -11,18 +11,19 @@
* Version:4.0.0
* 技术博文:http://www.devio.org/
* GitHub:https://github.com/crazycodeboy
- * Eamil:crazycodeboy@gmail.com
+ * Email:crazycodeboy@gmail.com
*/
public class TFileUtils {
- private static final String TAG="TFileUtils";
+ private static final String TAG = "TFileUtils";
private static String DEFAULT_DISK_CACHE_DIR = "takephoto_cache";
+
public static File getPhotoCacheDir(Context context, File file) {
File cacheDir = context.getCacheDir();
if (cacheDir != null) {
- File mCacheDir = new File(cacheDir,DEFAULT_DISK_CACHE_DIR);
+ File mCacheDir = new File(cacheDir, DEFAULT_DISK_CACHE_DIR);
if (!mCacheDir.mkdirs() && (!mCacheDir.exists() || !mCacheDir.isDirectory())) {
return file;
- }else {
+ } else {
return new File(mCacheDir, file.getName());
}
}
@@ -34,11 +35,11 @@ public static File getPhotoCacheDir(Context context, File file) {
public static void delete(String path) {
try {
- if(path == null) {
- return ;
+ if (path == null) {
+ return;
}
File file = new File(path);
- if(!file.delete()) {
+ if (!file.delete()) {
file.deleteOnExit();
}
} catch (Exception e) {
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TImageFiles.java b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TImageFiles.java
similarity index 59%
rename from takephoto_library/src/main/java/com/jph/takephoto/uitl/TImageFiles.java
rename to takephoto_library/src/main/java/org/devio/takephoto/uitl/TImageFiles.java
index 92b6c2cc..02414dda 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TImageFiles.java
+++ b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TImageFiles.java
@@ -1,4 +1,4 @@
-package com.jph.takephoto.uitl;
+package org.devio.takephoto.uitl;
import android.app.Activity;
import android.content.ContentResolver;
@@ -11,9 +11,8 @@
import android.webkit.MimeTypeMap;
import android.widget.Toast;
-import com.jph.takephoto.R;
-import com.jph.takephoto.model.TException;
-import com.jph.takephoto.model.TExceptionType;
+import org.devio.takephoto.model.TException;
+import org.devio.takephoto.model.TExceptionType;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -24,18 +23,22 @@
/**
* ImageFiles工具类
+ *
* @author JPH
- * Date 2016/6/7 0007 9:39
+ * Date 2016/6/7 0007 9:39
*/
public class TImageFiles {
private static final String TAG = IntentUtils.class.getName();
+
/**
* 将bitmap写入到文件
*
* @param bitmap
*/
public static void writeToFile(Bitmap bitmap, Uri imageUri) {
- if (bitmap == null) return;
+ if (bitmap == null) {
+ return;
+ }
File file = new File(imageUri.getPath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
@@ -48,20 +51,25 @@ public static void writeToFile(Bitmap bitmap, Uri imageUri) {
} catch (java.io.IOException e) {
e.printStackTrace();
} finally {
- if (fos != null) try {
- fos.close();
- if (bos != null) bos.close();
- } catch (IOException e) {
- e.printStackTrace();
+ if (fos != null) {
+ try {
+ fos.close();
+ if (bos != null) {
+ bos.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
}
}
+
/**
* InputStream 转File
- * */
+ */
public static void inputStreamToFile(InputStream is, File file) throws TException {
- if (file==null){
- Log.i(TAG,"inputStreamToFile:file not be null");
+ if (file == null) {
+ Log.i(TAG, "inputStreamToFile:file not be null");
throw new TException(TExceptionType.TYPE_WRITE_FAIL);
}
FileOutputStream fos = null;
@@ -73,7 +81,7 @@ public static void inputStreamToFile(InputStream is, File file) throws TExceptio
fos.write(buffer, 0, i);
}
} catch (IOException e) {
- Log.e(TAG,"InputStream 写入文件出错:"+e.toString());
+ Log.e(TAG, "InputStream 写入文件出错:" + e.toString());
throw new TException(TExceptionType.TYPE_WRITE_FAIL);
} finally {
try {
@@ -88,27 +96,36 @@ public static void inputStreamToFile(InputStream is, File file) throws TExceptio
/**
* 获取临时文件
+ *
* @param context
* @param photoUri
* @return
*/
- public static File getTempFile(Activity context, Uri photoUri)throws TException {
- String minType=getMimeType(context, photoUri);
- if (!checkMimeType(context,minType))throw new TException(TExceptionType.TYPE_NOT_IMAGE);
- File filesDir=context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
- if (!filesDir.exists())filesDir.mkdirs();
- File photoFile = new File(filesDir, UUID.randomUUID().toString() + "." +minType );
+ public static File getTempFile(Activity context, Uri photoUri) throws TException {
+ String minType = getMimeType(context, photoUri);
+ if (!checkMimeType(context, minType)) {
+ throw new TException(TExceptionType.TYPE_NOT_IMAGE);
+ }
+ File filesDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
+ if (!filesDir.exists()) {
+ filesDir.mkdirs();
+ }
+ File photoFile = new File(filesDir, UUID.randomUUID().toString() + "." + minType);
return photoFile;
}
/**
* 检查文件类型是否是图片
+ *
* @param minType
* @return
*/
- public static boolean checkMimeType(Context context,String minType) {
- boolean isPicture=TextUtils.isEmpty(minType)?false:".jpg|.gif|.png|.bmp|.jpeg|.webp|".contains(minType.toLowerCase())?true:false;
- if (!isPicture)Toast.makeText(context,context.getResources().getText(R.string.tip_type_not_image),Toast.LENGTH_SHORT).show();
+ public static boolean checkMimeType(Context context, String minType) {
+ boolean isPicture =
+ TextUtils.isEmpty(minType) ? false : ".jpg|.gif|.png|.bmp|.jpeg|.webp|".contains(minType.toLowerCase()) ? true : false;
+ if (!isPicture) {
+ Toast.makeText(context, context.getResources().getText(org.devio.takephoto.R.string.tip_type_not_image), Toast.LENGTH_SHORT).show();
+ }
return isPicture;
}
@@ -122,19 +139,25 @@ public static String getMimeType(Activity context, Uri uri) {
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
//If scheme is a content
extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(context.getContentResolver().getType(uri));
- if (TextUtils.isEmpty(extension))extension=MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
+ if (TextUtils.isEmpty(extension)) {
+ extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
+ }
} else {
//If scheme is a File
- //This will replace white spaces with %20 and also other special characters. This will avoid returning null values on file name with spaces and special characters.
+ //This will replace white spaces with %20 and also other special characters. This will avoid returning null values on file
+ // name with spaces and special characters.
extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
- if (TextUtils.isEmpty(extension))extension=MimeTypeMap.getSingleton().getExtensionFromMimeType(context.getContentResolver().getType(uri));
+ if (TextUtils.isEmpty(extension)) {
+ extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(context.getContentResolver().getType(uri));
+ }
}
- if(TextUtils.isEmpty(extension)){
- extension=getMimeTypeByFileName(TUriParse.getFileWithUri(uri,context).getName());
+ if (TextUtils.isEmpty(extension)) {
+ extension = getMimeTypeByFileName(TUriParse.getFileWithUri(uri, context).getName());
}
return extension;
}
- public static String getMimeTypeByFileName(String fileName){
- return fileName.substring(fileName.lastIndexOf("."),fileName.length());
+
+ public static String getMimeTypeByFileName(String fileName) {
+ return fileName.substring(fileName.lastIndexOf("."), fileName.length());
}
- }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/uitl/TUriParse.java b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TUriParse.java
new file mode 100644
index 00000000..270244bf
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TUriParse.java
@@ -0,0 +1,197 @@
+package org.devio.takephoto.uitl;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.support.v4.content.FileProvider;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.devio.takephoto.model.TException;
+import org.devio.takephoto.model.TExceptionType;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+
+/**
+ * Uri解析工具类
+ * Author: JPH
+ * Date: 2015/8/26 0026 16:23
+ */
+public class TUriParse {
+ private static final String TAG = IntentUtils.class.getName();
+
+ /**
+ * 将scheme为file的uri转成FileProvider 提供的content uri
+ *
+ * @param context
+ * @param uri
+ * @return
+ */
+ public static Uri convertFileUriToFileProviderUri(Context context, Uri uri) {
+ if (uri == null) {
+ return null;
+ }
+ if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
+ return getUriForFile(context, new File(uri.getPath()));
+ }
+ return uri;
+
+ }
+
+ /**
+ * 获取一个临时的Uri, 文件名随机生成
+ *
+ * @param context
+ * @return
+ */
+ public static Uri getTempUri(Context context) {
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
+ File file = new File(Environment.getExternalStorageDirectory(), "/images/" + timeStamp + ".jpg");
+ if (!file.getParentFile().exists()) {
+ file.getParentFile().mkdirs();
+ }
+ return getUriForFile(context, file);
+ }
+
+ /**
+ * 获取一个临时的Uri, 通过传入字符串路径
+ *
+ * @param context
+ * @param path
+ * @return
+ */
+ public static Uri getTempUri(Context context, String path) {
+ File file = new File(path);
+ return getTempUri(context, file);
+ }
+
+ /**
+ * 获取一个临时的Uri, 通过传入File对象
+ *
+ * @param context
+ * @return
+ */
+ public static Uri getTempUri(Context context, File file) {
+ if (!file.getParentFile().exists()) {
+ file.getParentFile().mkdirs();
+ }
+ return getUriForFile(context, file);
+ }
+
+ /**
+ * 创建一个用于拍照图片输出路径的Uri (FileProvider)
+ *
+ * @param context
+ * @return
+ */
+ public static Uri getUriForFile(Context context, File file) {
+ return FileProvider.getUriForFile(context, TConstant.getFileProviderName(context), file);
+ }
+
+ /**
+ * 将TakePhoto 提供的Uri 解析出文件绝对路径
+ *
+ * @param uri
+ * @return
+ */
+ public static String parseOwnUri(Context context, Uri uri) {
+ if (uri == null) {
+ return null;
+ }
+ String path;
+ if (TextUtils.equals(uri.getAuthority(), TConstant.getFileProviderName(context))) {
+ path = new File(uri.getPath().replace("camera_photos/", "")).getAbsolutePath();
+ } else {
+ path = uri.getPath();
+ }
+ return path;
+ }
+
+ /**
+ * 通过URI获取文件的路径
+ *
+ * @param uri
+ * @param activity
+ * @return Author JPH
+ * Date 2016/6/6 0006 20:01
+ */
+ public static String getFilePathWithUri(Uri uri, Activity activity) throws TException {
+ if (uri == null) {
+ Log.w(TAG, "uri is null,activity may have been recovered?");
+ throw new TException(TExceptionType.TYPE_URI_NULL);
+ }
+ File picture = getFileWithUri(uri, activity);
+ String picturePath = picture == null ? null : picture.getPath();
+ if (TextUtils.isEmpty(picturePath)) {
+ throw new TException(TExceptionType.TYPE_URI_PARSE_FAIL);
+ }
+ if (!TImageFiles.checkMimeType(activity, TImageFiles.getMimeType(activity, uri))) {
+ throw new TException(TExceptionType.TYPE_NOT_IMAGE);
+ }
+ return picturePath;
+ }
+
+ /**
+ * 通过URI获取文件
+ *
+ * @param uri
+ * @param activity
+ * @return Author JPH
+ * Date 2016/10/25
+ */
+ public static File getFileWithUri(Uri uri, Activity activity) {
+ String picturePath = null;
+ String scheme = uri.getScheme();
+ if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
+ String[] filePathColumn = {MediaStore.Images.Media.DATA};
+ Cursor cursor = activity.getContentResolver().query(uri, filePathColumn, null, null, null);//从系统表中查询指定Uri对应的照片
+ cursor.moveToFirst();
+ int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
+ if (columnIndex >= 0) {
+ picturePath = cursor.getString(columnIndex); //获取照片路径
+ } else if (TextUtils.equals(uri.getAuthority(), TConstant.getFileProviderName(activity))) {
+ picturePath = parseOwnUri(activity, uri);
+ }
+ cursor.close();
+ } else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
+ picturePath = uri.getPath();
+ }
+ return TextUtils.isEmpty(picturePath) ? null : new File(picturePath);
+ }
+
+ /**
+ * 通过从文件中得到的URI获取文件的路径
+ *
+ * @param uri
+ * @param activity
+ * @return Author JPH
+ * Date 2016/6/6 0006 20:01
+ */
+ public static String getFilePathWithDocumentsUri(Uri uri, Activity activity) throws TException {
+ if (uri == null) {
+ Log.e(TAG, "uri is null,activity may have been recovered?");
+ return null;
+ }
+ if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && uri.getPath().contains("document")) {
+ File tempFile = TImageFiles.getTempFile(activity, uri);
+ try {
+ TImageFiles.inputStreamToFile(activity.getContentResolver().openInputStream(uri), tempFile);
+ return tempFile.getPath();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new TException(TExceptionType.TYPE_NO_FIND);
+ }
+ } else {
+ return getFilePathWithUri(uri, activity);
+ }
+ }
+}
diff --git a/takephoto_library/src/main/java/org/devio/takephoto/uitl/TUtils.java b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TUtils.java
new file mode 100644
index 00000000..84cbfc8d
--- /dev/null
+++ b/takephoto_library/src/main/java/org/devio/takephoto/uitl/TUtils.java
@@ -0,0 +1,229 @@
+package org.devio.takephoto.uitl;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.support.v4.content.FileProvider;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.darsh.multipleimageselect.models.Image;
+import org.devio.takephoto.model.CropOptions;
+import org.devio.takephoto.model.TException;
+import org.devio.takephoto.model.TExceptionType;
+import org.devio.takephoto.model.TImage;
+import org.devio.takephoto.model.TIntentWap;
+import org.devio.takephoto.R;
+import org.devio.takephoto.model.TContextWrap;
+import com.soundcloud.android.crop.Crop;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 工具类
+ * Author: JPH
+ * Date: 2016/7/26 10:04
+ */
+public class TUtils {
+ private static final String TAG = IntentUtils.class.getName();
+
+
+ /**
+ * 将Image集合转换成Uri集合
+ *
+ * @param images
+ * @return
+ */
+ public static ArrayList convertImageToUri(Context context, ArrayList images) throws TException {
+ ArrayList uris = new ArrayList();
+ for (Image image : images) {
+ uris.add(FileProvider.getUriForFile(context, TConstant.getFileProviderName(context), new File(image.path)));
+ }
+ return uris;
+ }
+
+ /**
+ * 将Image集合转换成TImage集合
+ *
+ * @param images
+ * @return
+ */
+ public static ArrayList getTImagesWithImages(ArrayList images, TImage.FromType fromType) {
+ ArrayList tImages = new ArrayList();
+ for (Image image : images) {
+ tImages.add(TImage.of(image.path, fromType));
+ }
+ return tImages;
+ }
+
+ /**
+ * 将Uri集合转换成TImage集合
+ *
+ * @param uris
+ * @return
+ */
+ public static ArrayList getTImagesWithUris(ArrayList uris, TImage.FromType fromType) {
+ ArrayList tImages = new ArrayList();
+ for (Uri uri : uris) {
+ tImages.add(TImage.of(uri, fromType));
+ }
+ return tImages;
+ }
+
+ /**
+ * @param contextWrap
+ * @param intentWap
+ */
+ public static void startActivityForResult(TContextWrap contextWrap, TIntentWap intentWap) {
+ if (contextWrap.getFragment() != null) {
+ contextWrap.getFragment().startActivityForResult(intentWap.getIntent(), intentWap.getRequestCode());
+ } else {
+ contextWrap.getActivity().startActivityForResult(intentWap.getIntent(), intentWap.getRequestCode());
+ }
+ }
+
+ /**
+ * 安全地发送Intent
+ *
+ * @param contextWrap
+ * @param intentWapList 要发送的Intent以及候选Intent
+ * @param defaultIndex 默认发送的Intent
+ * @param isCrop 是否为裁切照片的Intent
+ * @throws TException
+ */
+ public static void sendIntentBySafely(TContextWrap contextWrap, List intentWapList, int defaultIndex, boolean isCrop)
+ throws TException {
+ if (defaultIndex + 1 > intentWapList.size()) {
+ throw new TException(isCrop ? TExceptionType.TYPE_NO_MATCH_PICK_INTENT : TExceptionType.TYPE_NO_MATCH_CROP_INTENT);
+ }
+ TIntentWap intentWap = intentWapList.get(defaultIndex);
+ List result = contextWrap.getActivity().getPackageManager().queryIntentActivities(intentWap.getIntent(), PackageManager.MATCH_ALL);
+ if (result.isEmpty()) {
+ sendIntentBySafely(contextWrap, intentWapList, ++defaultIndex, isCrop);
+ } else {
+ startActivityForResult(contextWrap, intentWap);
+ }
+ }
+
+ /**
+ * 拍照前检查是否有相机
+ **/
+ public static void captureBySafely(TContextWrap contextWrap, TIntentWap intentWap) throws TException {
+ List result = contextWrap.getActivity().getPackageManager().queryIntentActivities(intentWap.getIntent(), PackageManager.MATCH_ALL);
+ if (result.isEmpty()) {
+ Toast.makeText(contextWrap.getActivity(), contextWrap.getActivity().getResources().getText(R.string.tip_no_camera),
+ Toast.LENGTH_SHORT).show();
+ throw new TException(TExceptionType.TYPE_NO_CAMERA);
+ } else {
+ startActivityForResult(contextWrap, intentWap);
+ }
+ }
+
+ /**
+ * 通过第三方工具裁切照片,当没有第三方裁切工具时,会自动使用自带裁切工具进行裁切
+ *
+ * @param contextWrap
+ * @param imageUri
+ * @param outPutUri
+ * @param options
+ */
+ public static void cropWithOtherAppBySafely(TContextWrap contextWrap, Uri imageUri, Uri outPutUri, CropOptions options) {
+ Intent nativeCropIntent = IntentUtils.getCropIntentWithOtherApp(imageUri, outPutUri, options);
+ List result = contextWrap.getActivity().getPackageManager().queryIntentActivities(nativeCropIntent, PackageManager.MATCH_ALL);
+ if (result.isEmpty()) {
+ cropWithOwnApp(contextWrap, imageUri, outPutUri, options);
+ } else {
+ // try {
+ // imageUri=Uri.fromFile(new File(TUriParse.getFilePathWithDocumentsUri(imageUri,contextWrap.getActivity())));
+ // } catch (TException e) {
+ // e.printStackTrace();
+ // }
+ startActivityForResult(contextWrap,
+ new TIntentWap(IntentUtils.getCropIntentWithOtherApp(imageUri, outPutUri, options), TConstant.RC_CROP));
+ }
+ }
+
+ /**
+ * 通过TakePhoto自带的裁切工具裁切图片
+ *
+ * @param contextWrap
+ * @param imageUri
+ * @param outPutUri
+ * @param options
+ */
+ public static void cropWithOwnApp(TContextWrap contextWrap, Uri imageUri, Uri outPutUri, CropOptions options) {
+ if (options.getAspectX() * options.getAspectY() > 0) {
+ if (contextWrap.getFragment() != null) {
+ Crop.of(imageUri, outPutUri)
+ .withAspect(options.getAspectX(), options.getAspectY())
+ .start(contextWrap.getActivity(), contextWrap.getFragment());
+ } else {
+ Crop.of(imageUri, outPutUri).withAspect(options.getAspectX(), options.getAspectY()).start(contextWrap.getActivity());
+ }
+ } else if (options.getOutputX() * options.getOutputY() > 0) {
+ if (contextWrap.getFragment() != null) {
+ Crop.of(imageUri, outPutUri)
+ .withMaxSize(options.getOutputX(), options.getOutputY())
+ .start(contextWrap.getActivity(), contextWrap.getFragment());
+ } else {
+ Crop.of(imageUri, outPutUri).withMaxSize(options.getOutputX(), options.getOutputY()).start(contextWrap.getActivity());
+ }
+ } else {
+ if (contextWrap.getFragment() != null) {
+ Crop.of(imageUri, outPutUri).asSquare().start(contextWrap.getActivity(), contextWrap.getFragment());
+ } else {
+ Crop.of(imageUri, outPutUri).asSquare().start(contextWrap.getActivity());
+ }
+ }
+ }
+
+ /**
+ * 是否裁剪之后返回数据
+ **/
+ public static boolean isReturnData() {
+ String release = Build.VERSION.RELEASE;
+ int sdk = Build.VERSION.SDK_INT;
+ Log.i(TAG, "release:" + release + "sdk:" + sdk);
+ String manufacturer = android.os.Build.MANUFACTURER;
+ if (!TextUtils.isEmpty(manufacturer)) {
+ if (manufacturer.toLowerCase().contains("lenovo")) {//对于联想的手机返回数据
+ return true;
+ }
+ }
+ // if (sdk>=21){//5.0或以上版本要求返回数据
+ // return true;
+ // }
+ return false;
+ }
+
+ /**
+ * 显示圆形进度对话框
+ *
+ * @param activity
+ * @param progressTitle 显示的标题
+ * @return
+ * @author JPH
+ * Date 2014-12-12 下午7:04:09
+ */
+ public static ProgressDialog showProgressDialog(final Activity activity, String... progressTitle) {
+ if (activity == null || activity.isFinishing()) {
+ return null;
+ }
+ String title = activity.getResources().getString(R.string.tip_tips);
+ if (progressTitle != null && progressTitle.length > 0) {
+ title = progressTitle[0];
+ }
+ ProgressDialog progressDialog = new ProgressDialog(activity);
+ progressDialog.setTitle(title);
+ progressDialog.setCancelable(false);
+ progressDialog.show();
+ return progressDialog;
+ }
+}
diff --git a/takephoto_library/src/main/res/xml/file_paths.xml b/takephoto_library/src/main/res/xml/file_paths.xml
index e69a0795..55eecb07 100644
--- a/takephoto_library/src/main/res/xml/file_paths.xml
+++ b/takephoto_library/src/main/res/xml/file_paths.xml
@@ -1,6 +1,8 @@
-
+
\ No newline at end of file