diff --git a/README -V1.0+.md b/README -V1.0+.md index 7c7ac2b8..31c2ee2a 100644 --- a/README -V1.0+.md +++ b/README -V1.0+.md @@ -11,8 +11,8 @@ - 支持因拍照Activity被回收后的自动恢复 GitHub地址: [https://github.com/crazycodeboy/TakePhoto](https://github.com/crazycodeboy/TakePhoto) -##如何使用 -###使用TakePhoto有以下两种方式: +## 如何使用 +### 使用TakePhoto有以下两种方式: **方式一:通过继承的方式** 1. 继承TakePhotoActivity、TakePhotoFragmentActivity、TakePhotoFragment三者之一。 2. 通过`getTakePhoto()`获取TakePhoto实例进行相关操作。 @@ -29,7 +29,7 @@ void takeCancel(); 2. 在 `onCreate`,`onActivityResult`,`onSaveInstanceState`方法中调用TakePhoto对用的方法。 3. 调用TakePhoto实例进行相关操作。 4. 在`TakeResultListener`相关方法中获取结果。 -###关于压缩照片 +### 关于压缩照片 你可以选择是否对照片进行压缩处理。 ```java /** @@ -44,7 +44,7 @@ eg: `getTakePhoto().onEnableCompress(new CompressConfig.Builder().setMaxSize(50*1024).setMaxPixel(800).create(),true).onPicSelectCrop(imageUri);` 如果你启用了照片压缩,TakePhoto会使用`CompressImage`对照片进行压缩处理,CompressImage目前支持对照片的尺寸以及照片的质量进行压缩。默认情况下,CompressImage开启了尺寸与质量双重压缩, 你可以通过CompressConfig.Builder对照片压缩后的尺寸以及质量进行相关设置。如果你想改变压缩的方式可以通过CompressConfig.Builder进行相关设置。 -##关于兼容性问题 +## 关于兼容性问题 TakePhoto是基于Android官方标准API编写的,适配了目前市场上主流的Rom。如果你在使用过程中发现了适配问题,可以提交Issues。 1. 为适配部分手机拍照时会回收Activity,TakePhoto在`onSaveInstanceState`与 `onCreate`做了相应的恢复处理。 2. 为适配部分手机拍照或从相册选择照片时屏幕方向会发生转变,从而导致拍照失败的问题,可以在AndroidManifest.xml中对使用了TakePhoto的Activity添加android:configChanges="orientation|keyboardHidden|screenSize"配置。 @@ -62,7 +62,7 @@ eg: ``` -##在项目中使用 +## 在项目中使用 为方便大家使用,现已将TakePhoto发布到JCenter(如果你对如何将项目发布到JCenter感兴趣可以参考:《[教你轻松将Android library 发布到JCenter](http://blog.csdn.net/fengyuzhengfan/article/details/51407009))》 Gradle: ```groovy @@ -78,5 +78,5 @@ Maven: pom ``` -##最后 +## 最后 如果你对[TakePhoto](https://github.com/crazycodeboy/TakePhoto)有更好的建议或想改造它,欢迎大家Fork and Pull requests。 diff --git a/README.md b/README.md index 70dc4e15..e408555d 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ -`TakePhoto`是一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库,目前最新版本[4.0.1](https://github.com/crazycodeboy/TakePhoto/)。 +`TakePhoto`是一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库,目前最新版本[4.1.0](https://github.com/crazycodeboy/TakePhoto/)。 3.0以下版本及API说明,详见[TakePhoto2.0+](https://github.com/crazycodeboy/TakePhoto/blob/master/README.2+.md)。 >TakePhoto交流平台:QQ群:556387607(群1,未满) @@ -26,7 +26,7 @@ - 提供自带裁剪工具(可选) - 支持智能选取及裁剪异常处理 - 支持因拍照Activity被回收后的自动恢复 -- 支持Android7.0 +- 支持Android8.1 - +支持多种压缩工具 - +支持多种图片选择工具 @@ -47,7 +47,7 @@ GitHub地址: [https://github.com/crazycodeboy/TakePhoto](https://github.com/c **Gradle:** ```groovy - compile 'com.jph.takephoto:takephoto_library:4.0.1' + compile 'com.jph.takephoto:takephoto_library:4.1.0' ``` **Maven:** @@ -56,7 +56,7 @@ GitHub地址: [https://github.com/crazycodeboy/TakePhoto](https://github.com/c com.jph.takephoto takephoto_library - 4.0.1 + 4.1.0 pom ``` @@ -442,11 +442,29 @@ eg: 如果你在使用TakePhoto中遇到任何问题可以提[Issues](https://github.com/crazycodeboy/TakePhoto/issues)出来。另外欢迎大家为TakePhoto贡献智慧,欢迎大家[Fork and Pull requests](https://github.com/crazycodeboy/TakePhoto)。 ## 更新说明 -**2016/11/28** -1、压缩成功后返回原图路径(originalPath), 以便用户可以自行处理原图。 -2、压缩成功后压缩路径path改为compressPath。 -2、压缩成功后返回图片来源类型,现在分CAMERA, OTHER两种。 -3、用户可以配置CompressConfig.enableReserveRaw(boolean)方法,ture保留原图,false删除原图,当且仅当类型为CAMERA此配置才有效 + +v4.1.0(2018/4/2) +----------------- + +1. Upgrade glide to 4.6.1; +2. Upgrade buildToolsVersion & targetSdkVersion ; +3. rename package name ; + +v4.0.3(2017/1/18) +----------------- +**Bugfixes** + +1. Fixed bug and add new features([`62a6725`](https://github.com/crazycodeboy/TakePhoto/commit/62a6725a99118ec0ce0f4cf1cd76b2ba70e21745))-@[Yanqilong](https://github.com/Yanqilong) +2. fix 鲁班压缩出现路径重复([`a0a64a59`](https://github.com/crazycodeboy/TakePhoto/commit/a0a64a59762fa8554eb46b6ec544f70a5d46f551))-@[namezhouyu](https://github.com/namezhouyu) + + +v4.0.2(2016/11/28) +------------------ +1. 压缩成功后返回原图路径(originalPath), 以便用户可以自行处理原图。 +2. 压缩成功后压缩路径path改为compressPath。 +3. 压缩成功后返回图片来源类型,现在分CAMERA, OTHER两种。 +4. 用户可以配置CompressConfig.enableReserveRaw(boolean)方法,ture保留原图,false删除原图,当且仅当类型为CAMERA此配置才有效 +5. 纠正拍照旋转角度功能改为可选 ## 最后 diff --git a/build.gradle b/build.gradle index 1b49c906..03e3cd7b 100644 --- a/build.gradle +++ b/build.gradle @@ -3,11 +3,12 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' -// classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' -// classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' + classpath 'com.android.tools.build:gradle:3.1.0' +// classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' +// classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -16,5 +17,6 @@ buildscript { allprojects { repositories { jcenter() + google() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cd8ba728..f48caf51 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Sep 19 14:51:40 CST 2016 +#Mon Apr 02 19:53:50 CST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/simple/build.gradle b/simple/build.gradle index c2615986..3b9b2eff 100644 --- a/simple/build.gradle +++ b/simple/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 25 - buildToolsVersion "25.0.0" + compileSdkVersion 26 + buildToolsVersion '26.0.3' defaultConfig { - applicationId "com.jph.simple" - minSdkVersion 9 - targetSdkVersion 25 + applicationId "org.devio.simple" + minSdkVersion 14 + targetSdkVersion 26 versionCode 1 versionName "1.0" } diff --git a/simple/src/androidTest/java/com/jph/simple/ApplicationTest.java b/simple/src/androidTest/java/org/devio/simple/ApplicationTest.java similarity index 92% rename from simple/src/androidTest/java/com/jph/simple/ApplicationTest.java rename to simple/src/androidTest/java/org/devio/simple/ApplicationTest.java index 66d17981..e0b12352 100644 --- a/simple/src/androidTest/java/com/jph/simple/ApplicationTest.java +++ b/simple/src/androidTest/java/org/devio/simple/ApplicationTest.java @@ -1,4 +1,4 @@ -package com.jph.simple; +package org.devio.simple; import android.app.Application; import android.test.ApplicationTestCase; diff --git a/simple/src/main/AndroidManifest.xml b/simple/src/main/AndroidManifest.xml index 8908ec7c..a3d8a6c8 100644 --- a/simple/src/main/AndroidManifest.xml +++ b/simple/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="org.devio.simple" > 1){ - if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){ - takePhoto.onPickMultipleWithCrop(limit,getCropOptions()); - }else { - takePhoto.onPickMultiple(limit); - } - return; - } - if(rgFrom.getCheckedRadioButtonId()==R.id.rbFile){ - if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){ - takePhoto.onPickFromDocumentsWithCrop(imageUri,getCropOptions()); - }else { - takePhoto.onPickFromDocuments(); - } - return; - }else { - if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){ - takePhoto.onPickFromGalleryWithCrop(imageUri,getCropOptions()); - }else { - takePhoto.onPickFromGallery(); - } - } - break; - case R.id.btnPickByTake: - if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){ - takePhoto.onPickFromCaptureWithCrop(imageUri,getCropOptions()); - }else { - takePhoto.onPickFromCapture(imageUri); - } - break; - default: - break; - } - } - private void configTakePhotoOption(TakePhoto takePhoto){ - TakePhotoOptions.Builder builder=new TakePhotoOptions.Builder(); - if(rgPickTool.getCheckedRadioButtonId()==R.id.rbPickWithOwn){ - builder.setWithOwnGallery(true); - } - if(rgCorrectTool.getCheckedRadioButtonId()==R.id.rbCorrectYes){ - builder.setCorrectImage(true); - } - takePhoto.setTakePhotoOptions(builder.create()); - - } - private void configCompress(TakePhoto takePhoto){ - if(rgCompress.getCheckedRadioButtonId()!=R.id.rbCompressYes){ - takePhoto.onEnableCompress(null,false); - return ; - } - int maxSize= Integer.parseInt(etSize.getText().toString()); - int width= Integer.parseInt(etCropWidth.getText().toString()); - int height= Integer.parseInt(etHeightPx.getText().toString()); - boolean showProgressBar=rgShowProgressBar.getCheckedRadioButtonId()==R.id.rbShowYes? true:false; - boolean enableRawFile = rgRawFile.getCheckedRadioButtonId() == R.id.rbRawYes ? true : false; - CompressConfig config; - if(rgCompressTool.getCheckedRadioButtonId()==R.id.rbCompressWithOwn){ - config=new CompressConfig.Builder() - .setMaxSize(maxSize) - .setMaxPixel(width>=height? width:height) - .enableReserveRaw(enableRawFile) - .create(); - }else { - LubanOptions option=new LubanOptions.Builder() - .setGear(Luban.CUSTOM_GEAR) - .setMaxHeight(height) - .setMaxWidth(width) - .setMaxSize(maxSize) - .create(); - config=CompressConfig.ofLuban(option); - config.enableReserveRaw(enableRawFile); - } - takePhoto.onEnableCompress(config,showProgressBar); - - - } - private CropOptions getCropOptions(){ - if(rgCrop.getCheckedRadioButtonId()!=R.id.rbCropYes)return null; - int height= Integer.parseInt(etCropHeight.getText().toString()); - int width= Integer.parseInt(etCropWidth.getText().toString()); - boolean withWonCrop=rgCropTool.getCheckedRadioButtonId()==R.id.rbCropOwn? true:false; - - CropOptions.Builder builder=new CropOptions.Builder(); - - if(rgCropSize.getCheckedRadioButtonId()==R.id.rbAspect){ - builder.setAspectX(width).setAspectY(height); - }else { - builder.setOutputX(width).setOutputY(height); - } - builder.setWithOwnCrop(withWonCrop); - return builder.create(); - } - -} diff --git a/simple/src/main/java/com/jph/simple/MainActivity.java b/simple/src/main/java/com/jph/simple/MainActivity.java deleted file mode 100644 index a7902db2..00000000 --- a/simple/src/main/java/com/jph/simple/MainActivity.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.jph.simple; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; - - -/** - - 支持通过相机拍照获取图片 - - 支持从相册选择图片 - - 支持从文件选择图片 - - 支持多图选择 - - 支持批量图片裁切 - - 支持批量图片压缩 - - 支持对图片进行压缩 - - 支持对图片进行裁剪 - - 支持对裁剪及压缩参数自定义 - - 提供自带裁剪工具(可选) - - 支持智能选取及裁剪异常处理 - - 支持因拍照Activity被回收后的自动恢复 - * Author: crazycodeboy - * Date: 2016/9/21 0007 20:10 - * Version:4.0.0 - * 技术博文:http://www.cboy.me - * GitHub:https://github.com/crazycodeboy - * Eamil:crazycodeboy@gmail.com - */ -public class MainActivity extends Activity implements View.OnClickListener{ - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main_layout); - } - - @Override - public void onClick(View view) { - switch (view.getId()){ - case R.id.btnTakePhotoActivity: - startActivity(new Intent(this,SimpleActivity.class)); - break; - case R.id.btnTakePhotoFragment: - startActivity(new Intent(this,SimpleFragmentActivity.class)); - break; - default: - } - } -} diff --git a/simple/src/main/java/com/jph/simple/SimpleFragmentActivity.java b/simple/src/main/java/com/jph/simple/SimpleFragmentActivity.java deleted file mode 100644 index d97fa726..00000000 --- a/simple/src/main/java/com/jph/simple/SimpleFragmentActivity.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.jph.simple; - -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentTransaction; -import android.view.View; - - -/** - - 支持通过相机拍照获取图片 - - 支持从相册选择图片 - - 支持从文件选择图片 - - 支持多图选择 - - 支持批量图片裁切 - - 支持批量图片压缩 - - 支持对图片进行压缩 - - 支持对图片进行裁剪 - - 支持对裁剪及压缩参数自定义 - - 提供自带裁剪工具(可选) - - 支持智能选取及裁剪异常处理 - - 支持因拍照Activity被回收后的自动恢复 - * Author: crazycodeboy - * Date: 2016/9/21 0007 20:10 - * Version:4.0.0 - * 技术博文:http://www.cboy.me - * GitHub:https://github.com/crazycodeboy - * Eamil:crazycodeboy@gmail.com - */ -public class SimpleFragmentActivity extends FragmentActivity{ - SimpleFragment fragment; - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.simple_fragment_layout); - FragmentTransaction transaction=getSupportFragmentManager().beginTransaction(); - transaction.add(R.id.fragment1,fragment=new SimpleFragment(),"test"); - transaction.commit(); - } - public void onClick(View v){ - fragment.onClick(v); - } -} diff --git a/simple/src/main/java/org/devio/simple/CustomHelper.java b/simple/src/main/java/org/devio/simple/CustomHelper.java new file mode 100644 index 00000000..b2f8a266 --- /dev/null +++ b/simple/src/main/java/org/devio/simple/CustomHelper.java @@ -0,0 +1,179 @@ +package org.devio.simple; + +import android.net.Uri; +import android.os.Environment; +import android.view.View; +import android.widget.EditText; +import android.widget.RadioGroup; + +import org.devio.takephoto.app.TakePhoto; +import org.devio.takephoto.compress.CompressConfig; +import org.devio.takephoto.model.CropOptions; +import org.devio.takephoto.model.LubanOptions; +import org.devio.takephoto.model.TakePhotoOptions; + +import java.io.File; + + +/** + * - 支持通过相机拍照获取图片 + * - 支持从相册选择图片 + * - 支持从文件选择图片 + * - 支持多图选择 + * - 支持批量图片裁切 + * - 支持批量图片压缩 + * - 支持对图片进行压缩 + * - 支持对图片进行裁剪 + * - 支持对裁剪及压缩参数自定义 + * - 提供自带裁剪工具(可选) + * - 支持智能选取及裁剪异常处理 + * - 支持因拍照Activity被回收后的自动恢复 + * Author: crazycodeboy + * Date: 2016/9/21 0007 20:10 + * Version:4.0.0 + * 技术博文:http://www.devio.org + * GitHub:https://github.com/crazycodeboy + * Email:crazycodeboy@gmail.com + */ +public class CustomHelper { + private View rootView; + private RadioGroup rgCrop, rgCompress, rgFrom, rgCropSize, rgCropTool, rgShowProgressBar, rgPickTool, rgCompressTool, rgCorrectTool, + rgRawFile; + private EditText etCropHeight, etCropWidth, etLimit, etSize, etHeightPx, etWidthPx; + + public static CustomHelper of(View rootView) { + return new CustomHelper(rootView); + } + + private CustomHelper(View rootView) { + this.rootView = rootView; + init(); + } + + private void init() { + rgCrop = (RadioGroup) rootView.findViewById(R.id.rgCrop); + rgCompress = (RadioGroup) rootView.findViewById(R.id.rgCompress); + rgCompressTool = (RadioGroup) rootView.findViewById(R.id.rgCompressTool); + rgCropSize = (RadioGroup) rootView.findViewById(R.id.rgCropSize); + rgFrom = (RadioGroup) rootView.findViewById(R.id.rgFrom); + rgPickTool = (RadioGroup) rootView.findViewById(R.id.rgPickTool); + rgRawFile = (RadioGroup) rootView.findViewById(R.id.rgRawFile); + rgCorrectTool = (RadioGroup) rootView.findViewById(R.id.rgCorrectTool); + rgShowProgressBar = (RadioGroup) rootView.findViewById(R.id.rgShowProgressBar); + rgCropTool = (RadioGroup) rootView.findViewById(R.id.rgCropTool); + etCropHeight = (EditText) rootView.findViewById(R.id.etCropHeight); + etCropWidth = (EditText) rootView.findViewById(R.id.etCropWidth); + etLimit = (EditText) rootView.findViewById(R.id.etLimit); + etSize = (EditText) rootView.findViewById(R.id.etSize); + etHeightPx = (EditText) rootView.findViewById(R.id.etHeightPx); + etWidthPx = (EditText) rootView.findViewById(R.id.etWidthPx); + + + + } + + public void onClick(View view, TakePhoto takePhoto) { + File file = new File(Environment.getExternalStorageDirectory(), "/temp/" + System.currentTimeMillis() + ".jpg"); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + Uri imageUri = Uri.fromFile(file); + + configCompress(takePhoto); + configTakePhotoOption(takePhoto); + switch (view.getId()) { + case R.id.btnPickBySelect: + int limit = Integer.parseInt(etLimit.getText().toString()); + if (limit > 1) { + if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) { + takePhoto.onPickMultipleWithCrop(limit, getCropOptions()); + } else { + takePhoto.onPickMultiple(limit); + } + return; + } + if (rgFrom.getCheckedRadioButtonId() == R.id.rbFile) { + if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) { + takePhoto.onPickFromDocumentsWithCrop(imageUri, getCropOptions()); + } else { + takePhoto.onPickFromDocuments(); + } + return; + } else { + if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) { + takePhoto.onPickFromGalleryWithCrop(imageUri, getCropOptions()); + } else { + takePhoto.onPickFromGallery(); + } + } + break; + case R.id.btnPickByTake: + if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) { + takePhoto.onPickFromCaptureWithCrop(imageUri, getCropOptions()); + } else { + takePhoto.onPickFromCapture(imageUri); + } + break; + default: + break; + } + } + + private void configTakePhotoOption(TakePhoto takePhoto) { + TakePhotoOptions.Builder builder = new TakePhotoOptions.Builder(); + if (rgPickTool.getCheckedRadioButtonId() == R.id.rbPickWithOwn) { + builder.setWithOwnGallery(true); + } + if (rgCorrectTool.getCheckedRadioButtonId() == R.id.rbCorrectYes) { + builder.setCorrectImage(true); + } + takePhoto.setTakePhotoOptions(builder.create()); + + } + + private void configCompress(TakePhoto takePhoto) { + if (rgCompress.getCheckedRadioButtonId() != R.id.rbCompressYes) { + takePhoto.onEnableCompress(null, false); + return; + } + int maxSize = Integer.parseInt(etSize.getText().toString()); + int width = Integer.parseInt(etCropWidth.getText().toString()); + int height = Integer.parseInt(etHeightPx.getText().toString()); + boolean showProgressBar = rgShowProgressBar.getCheckedRadioButtonId() == R.id.rbShowYes ? true : false; + boolean enableRawFile = rgRawFile.getCheckedRadioButtonId() == R.id.rbRawYes ? true : false; + CompressConfig config; + if (rgCompressTool.getCheckedRadioButtonId() == R.id.rbCompressWithOwn) { + config = new CompressConfig.Builder().setMaxSize(maxSize) + .setMaxPixel(width >= height ? width : height) + .enableReserveRaw(enableRawFile) + .create(); + } else { + LubanOptions option = new LubanOptions.Builder().setMaxHeight(height).setMaxWidth(width).setMaxSize(maxSize).create(); + config = CompressConfig.ofLuban(option); + config.enableReserveRaw(enableRawFile); + } + takePhoto.onEnableCompress(config, showProgressBar); + + + } + + private CropOptions getCropOptions() { + if (rgCrop.getCheckedRadioButtonId() != R.id.rbCropYes) { + return null; + } + int height = Integer.parseInt(etCropHeight.getText().toString()); + int width = Integer.parseInt(etCropWidth.getText().toString()); + boolean withWonCrop = rgCropTool.getCheckedRadioButtonId() == R.id.rbCropOwn ? true : false; + + CropOptions.Builder builder = new CropOptions.Builder(); + + if (rgCropSize.getCheckedRadioButtonId() == R.id.rbAspect) { + builder.setAspectX(width).setAspectY(height); + } else { + builder.setOutputX(width).setOutputY(height); + } + builder.setWithOwnCrop(withWonCrop); + return builder.create(); + } + +} diff --git a/simple/src/main/java/org/devio/simple/MainActivity.java b/simple/src/main/java/org/devio/simple/MainActivity.java new file mode 100644 index 00000000..4639ed28 --- /dev/null +++ b/simple/src/main/java/org/devio/simple/MainActivity.java @@ -0,0 +1,48 @@ +package org.devio.simple; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + + +/** + * - 支持通过相机拍照获取图片 + * - 支持从相册选择图片 + * - 支持从文件选择图片 + * - 支持多图选择 + * - 支持批量图片裁切 + * - 支持批量图片压缩 + * - 支持对图片进行压缩 + * - 支持对图片进行裁剪 + * - 支持对裁剪及压缩参数自定义 + * - 提供自带裁剪工具(可选) + * - 支持智能选取及裁剪异常处理 + * - 支持因拍照Activity被回收后的自动恢复 + * Author: crazycodeboy + * Date: 2016/9/21 0007 20:10 + * Version:4.0.0 + * 技术博文:http://www.devio.org + * GitHub:https://github.com/crazycodeboy + * Email:crazycodeboy@gmail.com + */ +public class MainActivity extends Activity implements View.OnClickListener { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main_layout); + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.btnTakePhotoActivity: + startActivity(new Intent(this, SimpleActivity.class)); + break; + case R.id.btnTakePhotoFragment: + startActivity(new Intent(this, SimpleFragmentActivity.class)); + break; + default: + } + } +} diff --git a/simple/src/main/java/com/jph/simple/ResultActivity.java b/simple/src/main/java/org/devio/simple/ResultActivity.java similarity index 89% rename from simple/src/main/java/com/jph/simple/ResultActivity.java rename to simple/src/main/java/org/devio/simple/ResultActivity.java index 9d3ad1f9..f1be4d50 100644 --- a/simple/src/main/java/com/jph/simple/ResultActivity.java +++ b/simple/src/main/java/org/devio/simple/ResultActivity.java @@ -1,4 +1,4 @@ -package com.jph.simple; +package org.devio.simple; import android.app.Activity; import android.os.Bundle; @@ -8,7 +8,8 @@ import android.widget.LinearLayout; import com.bumptech.glide.Glide; -import com.jph.takephoto.model.TImage; + +import org.devio.takephoto.model.TImage; import java.io.File; import java.util.ArrayList; @@ -30,19 +31,21 @@ * Author: crazycodeboy * Date: 2016/9/21 0007 20:10 * Version:4.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 ResultActivity extends Activity { - ArrayListimages; + ArrayList images; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_result_layout); - images= (ArrayList) getIntent().getSerializableExtra("images"); + images = (ArrayList) getIntent().getSerializableExtra("images"); showImg(); } + private void showImg() { LinearLayout linearLayout = (LinearLayout) findViewById(R.id.llImages); for (int i = 0, j = images.size(); i < j - 1; i += 2) { diff --git a/simple/src/main/java/com/jph/simple/SimpleActivity.java b/simple/src/main/java/org/devio/simple/SimpleActivity.java similarity index 72% rename from simple/src/main/java/com/jph/simple/SimpleActivity.java rename to simple/src/main/java/org/devio/simple/SimpleActivity.java index c3453896..ed6c92b8 100644 --- a/simple/src/main/java/com/jph/simple/SimpleActivity.java +++ b/simple/src/main/java/org/devio/simple/SimpleActivity.java @@ -1,13 +1,13 @@ -package com.jph.simple; +package org.devio.simple; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; -import com.jph.takephoto.app.TakePhotoActivity; -import com.jph.takephoto.model.TImage; -import com.jph.takephoto.model.TResult; +import org.devio.takephoto.app.TakePhotoActivity; +import org.devio.takephoto.model.TImage; +import org.devio.takephoto.model.TResult; import java.util.ArrayList; @@ -28,22 +28,23 @@ * Author: crazycodeboy * Date: 2016/9/21 0007 20:10 * Version:4.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 SimpleActivity extends TakePhotoActivity { private CustomHelper customHelper; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - View contentView=LayoutInflater.from(this).inflate(R.layout.common_layout,null); + View contentView = LayoutInflater.from(this).inflate(R.layout.common_layout, null); setContentView(contentView); - customHelper=CustomHelper.of(contentView); + customHelper = CustomHelper.of(contentView); } public void onClick(View view) { - customHelper.onClick(view,getTakePhoto()); + customHelper.onClick(view, getTakePhoto()); } @Override @@ -63,8 +64,8 @@ public void takeSuccess(TResult result) { } private void showImg(ArrayList images) { - Intent intent=new Intent(this,ResultActivity.class); - intent.putExtra("images",images); + Intent intent = new Intent(this, ResultActivity.class); + intent.putExtra("images", images); startActivity(intent); } } diff --git a/simple/src/main/java/com/jph/simple/SimpleFragment.java b/simple/src/main/java/org/devio/simple/SimpleFragment.java similarity index 51% rename from simple/src/main/java/com/jph/simple/SimpleFragment.java rename to simple/src/main/java/org/devio/simple/SimpleFragment.java index 449b4d7b..735adfb4 100644 --- a/simple/src/main/java/com/jph/simple/SimpleFragment.java +++ b/simple/src/main/java/org/devio/simple/SimpleFragment.java @@ -1,4 +1,4 @@ -package com.jph.simple; +package org.devio.simple; import android.content.Intent; import android.os.Bundle; @@ -7,35 +7,36 @@ import android.view.View; import android.view.ViewGroup; -import com.jph.takephoto.app.TakePhotoFragment; -import com.jph.takephoto.model.TImage; -import com.jph.takephoto.model.TResult; +import org.devio.takephoto.app.TakePhotoFragment; +import org.devio.takephoto.model.TImage; +import org.devio.takephoto.model.TResult; import java.util.ArrayList; /** - - 支持通过相机拍照获取图片 - - 支持从相册选择图片 - - 支持从文件选择图片 - - 支持多图选择 - - 支持批量图片裁切 - - 支持批量图片压缩 - - 支持对图片进行压缩 - - 支持对图片进行裁剪 - - 支持对裁剪及压缩参数自定义 - - 提供自带裁剪工具(可选) - - 支持智能选取及裁剪异常处理 - - 支持因拍照Activity被回收后的自动恢复 + * - 支持通过相机拍照获取图片 + * - 支持从相册选择图片 + * - 支持从文件选择图片 + * - 支持多图选择 + * - 支持批量图片裁切 + * - 支持批量图片压缩 + * - 支持对图片进行压缩 + * - 支持对图片进行裁剪 + * - 支持对裁剪及压缩参数自定义 + * - 提供自带裁剪工具(可选) + * - 支持智能选取及裁剪异常处理 + * - 支持因拍照Activity被回收后的自动恢复 * Author: crazycodeboy * Date: 2016/9/21 0007 20:10 * Version:4.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 SimpleFragment extends TakePhotoFragment { private CustomHelper customHelper; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -45,22 +46,25 @@ public void onCreate(Bundle savedInstanceState) { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view=inflater.inflate(R.layout.common_layout,null); - customHelper=CustomHelper.of(view); + View view = inflater.inflate(R.layout.common_layout, null); + customHelper = CustomHelper.of(view); return view; } public void onClick(View view) { - customHelper.onClick(view,getTakePhoto()); + customHelper.onClick(view, getTakePhoto()); } + @Override public void takeCancel() { super.takeCancel(); } + @Override - public void takeFail(TResult result,String msg) { - super.takeFail(result,msg); + public void takeFail(TResult result, String msg) { + super.takeFail(result, msg); } + @Override public void takeSuccess(TResult result) { super.takeSuccess(result); @@ -68,8 +72,8 @@ public void takeSuccess(TResult result) { } private void showImg(ArrayList images) { - Intent intent=new Intent(getContext(),ResultActivity.class); - intent.putExtra("images",images); + Intent intent = new Intent(getContext(), ResultActivity.class); + intent.putExtra("images", images); startActivity(intent); } } diff --git a/simple/src/main/java/org/devio/simple/SimpleFragmentActivity.java b/simple/src/main/java/org/devio/simple/SimpleFragmentActivity.java new file mode 100644 index 00000000..f5a3bd48 --- /dev/null +++ b/simple/src/main/java/org/devio/simple/SimpleFragmentActivity.java @@ -0,0 +1,45 @@ +package org.devio.simple; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentTransaction; +import android.view.View; + + +/** + * - 支持通过相机拍照获取图片 + * - 支持从相册选择图片 + * - 支持从文件选择图片 + * - 支持多图选择 + * - 支持批量图片裁切 + * - 支持批量图片压缩 + * - 支持对图片进行压缩 + * - 支持对图片进行裁剪 + * - 支持对裁剪及压缩参数自定义 + * - 提供自带裁剪工具(可选) + * - 支持智能选取及裁剪异常处理 + * - 支持因拍照Activity被回收后的自动恢复 + * Author: crazycodeboy + * Date: 2016/9/21 0007 20:10 + * Version:4.0.0 + * 技术博文:http://www.devio.org + * GitHub:https://github.com/crazycodeboy + * Email:crazycodeboy@gmail.com + */ +public class SimpleFragmentActivity extends FragmentActivity { + SimpleFragment fragment; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.simple_fragment_layout); + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.add(R.id.fragment1, fragment = new SimpleFragment(), "test"); + transaction.commit(); + } + + public void onClick(View v) { + fragment.onClick(v); + } +} diff --git a/simple/src/main/res/layout/common_layout.xml b/simple/src/main/res/layout/common_layout.xml index a4408a83..6caa3756 100644 --- a/simple/src/main/res/layout/common_layout.xml +++ b/simple/src/main/res/layout/common_layout.xml @@ -515,7 +515,7 @@ + android:text="拍照压缩后是否保存原图:" /> + package="org.devio.takephoto"> + - + + 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/com/jph/takephoto/compress/CompressImageUtil.java b/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImageUtil.java deleted file mode 100644 index 07ec2185..00000000 --- a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImageUtil.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.jph.takephoto.compress; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.BitmapFactory; -import android.os.Handler; - -import com.jph.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); - } - } - /** - * 多线程压缩图片的质量 - * @author JPH - * @param bitmap 内存中的图片 - * @param imgPath 图片的保存路径 - * @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(); - } - /** - * 按比例缩小图片的像素以达到压缩的目的 - * @author JPH - * @param imgPath - * @return - * @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/com/jph/takephoto/compress/CompressWithLuBan.java b/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressWithLuBan.java deleted file mode 100644 index b8533504..00000000 --- a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressWithLuBan.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.jph.takephoto.compress; - -import android.content.Context; -import com.jph.takephoto.model.LubanOptions; -import com.jph.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 - * Eamil: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.get(context).putGear(options.getGear()) - .load(files.get(0)) - .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.get(context).putGear(options.getGear()) - .load(files) - .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/MultipleCrop.java b/takephoto_library/src/main/java/com/jph/takephoto/model/MultipleCrop.java deleted file mode 100644 index fd94276d..00000000 --- a/takephoto_library/src/main/java/com/jph/takephoto/model/MultipleCrop.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.jph.takephoto.model; - -import android.app.Activity; -import android.net.Uri; -import com.jph.takephoto.uitl.TImageFiles; -import com.jph.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 ArrayListtImages; - 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,ArrayListoutUris, TImage.FromType fromType){ - return new MultipleCrop(uris,outUris, fromType); - } - private MultipleCrop(ArrayList uris,Activity activity, TImage.FromType fromType) throws TException { - this.uris=uris; - ArrayListoutUris=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,ArrayListoutUris, 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/TExceptionType.java b/takephoto_library/src/main/java/com/jph/takephoto/model/TExceptionType.java deleted file mode 100644 index 36988c65..00000000 --- a/takephoto_library/src/main/java/com/jph/takephoto/model/TExceptionType.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.jph.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/permission/PermissionManager.java b/takephoto_library/src/main/java/com/jph/takephoto/permission/PermissionManager.java deleted file mode 100644 index c00d29e3..00000000 --- a/takephoto_library/src/main/java/com/jph/takephoto/permission/PermissionManager.java +++ /dev/null @@ -1,153 +0,0 @@ -package com.jph.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 com.jph.takephoto.R; -import com.jph.takephoto.app.TakePhoto; -import com.jph.takephoto.model.InvokeParam; -import com.jph.takephoto.model.TContextWrap; -import com.jph.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 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(R.string.tip_permission_camera_storage)); - break; - case ONLY_CAMERA_DENIED: - listener.takeFail(null,tip=activity.getResources().getString(R.string.tip_permission_camera)); - break; - case ONLY_STORAGE_DENIED: - listener.takeFail(null,tip=activity.getResources().getString(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(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/uitl/TUriParse.java b/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUriParse.java deleted file mode 100644 index f958fa1b..00000000 --- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUriParse.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.jph.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 com.jph.takephoto.model.TException; -import com.jph.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 getUriForFile(Context context, File file) { - return FileProvider.getUriForFile(context,TConstant.getFileProviderName(context), file); - } - - /** - * 获取一个临时的Uri ,(FileProvider) - * @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); - } - - /** - * 将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/com/jph/takephoto/uitl/TUtils.java b/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUtils.java deleted file mode 100644 index 71e501fe..00000000 --- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUtils.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.jph.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 com.jph.takephoto.R; -import com.jph.takephoto.model.CropOptions; -import com.jph.takephoto.model.TContextWrap; -import com.jph.takephoto.model.TException; -import com.jph.takephoto.model.TExceptionType; -import com.jph.takephoto.model.TImage; -import com.jph.takephoto.model.TIntentWap; -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,ArrayListimages) throws TException { - ArrayListuris=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(ArrayListimages, TImage.FromType fromType){ - ArrayListtImages=new ArrayList(); - for(Image image:images){ - tImages.add(TImage.of(image.path, fromType)); - } - return tImages; - } - /** - * 将Uri集合转换成TImage集合 - * @param uris - * @return - */ - public static ArrayList getTImagesWithUris(ArrayListuris, TImage.FromType fromType){ - ArrayListtImages=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; - } - /** - * 显示圆形进度对话框 - * - * @author JPH - * Date 2014-12-12 下午7:04:09 - * @param activity - * @param progressTitle - * 显示的标题 - * @return - */ - 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/java/com/jph/takephoto/app/TakePhoto.java b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhoto.java similarity index 60% rename from takephoto_library/src/main/java/com/jph/takephoto/app/TakePhoto.java rename to takephoto_library/src/main/java/org/devio/takephoto/app/TakePhoto.java index da94ade0..e60cdd4e 100644 --- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhoto.java +++ b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhoto.java @@ -1,124 +1,149 @@ -package com.jph.takephoto.app; +package org.devio.takephoto.app; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import com.jph.takephoto.compress.CompressConfig; -import com.jph.takephoto.model.CropOptions; -import com.jph.takephoto.model.MultipleCrop; -import com.jph.takephoto.model.TException; -import com.jph.takephoto.model.TResult; -import com.jph.takephoto.model.TakePhotoOptions; -import com.jph.takephoto.permission.PermissionManager; + +import org.devio.takephoto.model.MultipleCrop; +import org.devio.takephoto.model.TException; +import org.devio.takephoto.permission.PermissionManager; +import org.devio.takephoto.compress.CompressConfig; +import org.devio.takephoto.model.CropOptions; +import org.devio.takephoto.model.TResult; +import org.devio.takephoto.model.TakePhotoOptions; /** - - 支持通过相机拍照获取图片 - - 支持从相册选择图片 - - 支持从文件选择图片 - - 支持多图选择 - - 支持批量图片裁切 - - 支持批量图片压缩 - - 支持对图片进行压缩 - - 支持对图片进行裁剪 - - 支持对裁剪及压缩参数自定义 - - 提供自带裁剪工具(可选) - - 支持智能选取及裁剪异常处理 - - 支持因拍照Activity被回收后的自动恢复 + * - 支持通过相机拍照获取图片 + * - 支持从相册选择图片 + * - 支持从文件选择图片 + * - 支持多图选择 + * - 支持批量图片裁切 + * - 支持批量图片压缩 + * - 支持对图片进行压缩 + * - 支持对图片进行裁剪 + * - 支持对裁剪及压缩参数自定义 + * - 提供自带裁剪工具(可选) + * - 支持智能选取及裁剪异常处理 + * - 支持因拍照Activity被回收后的自动恢复 * Author: crazycodeboy * Date: 2016/9/21 0007 20:10 * Version:4.0.0 - * 技术博文:http://www.cboy.me + * 技术博文:http://www.devio.org * GitHub:https://github.com/crazycodeboy - * Eamil:crazycodeboy@gmail.com + * Email:crazycodeboy@gmail.com */ public interface TakePhoto { /** * 图片多选 + * * @param limit 最多选择图片张数的限制 - * */ + */ void onPickMultiple(int limit); + /** * 图片多选,并裁切 - * @param limit 最多选择图片张数的限制 - * @param options 裁剪配置 - * */ + * + * @param limit 最多选择图片张数的限制 + * @param options 裁剪配置 + */ void onPickMultipleWithCrop(int limit, CropOptions options); + /** * 从文件中获取图片(不裁剪) */ void onPickFromDocuments(); + /** * 从文件中获取图片并裁剪 + * * @param outPutUri 图片裁剪之后保存的路径 - * @param options 裁剪配置 + * @param options 裁剪配置 */ void onPickFromDocumentsWithCrop(Uri outPutUri, CropOptions options); + /** * 从相册中获取图片(不裁剪) */ void onPickFromGallery(); + /** * 从相册中获取图片并裁剪 + * * @param outPutUri 图片裁剪之后保存的路径 - * @param options 裁剪配置 + * @param options 裁剪配置 */ void onPickFromGalleryWithCrop(Uri outPutUri, CropOptions options); /** * 从相机获取图片(不裁剪) + * * @param outPutUri 图片保存的路径 */ void onPickFromCapture(Uri outPutUri); + /** * 从相机获取图片并裁剪 + * * @param outPutUri 图片裁剪之后保存的路径 - * @param options 裁剪配置 + * @param options 裁剪配置 */ void onPickFromCaptureWithCrop(Uri outPutUri, CropOptions options); /** * 裁剪图片 - * @param imageUri 要裁剪的图片 + * + * @param imageUri 要裁剪的图片 * @param outPutUri 图片裁剪之后保存的路径 - * @param options 裁剪配置 + * @param options 裁剪配置 */ - void onCrop(Uri imageUri, Uri outPutUri, CropOptions options)throws TException; + void onCrop(Uri imageUri, Uri outPutUri, CropOptions options) throws TException; + /** * 裁剪多张图片 + * * @param multipleCrop 要裁切的图片的路径以及输出路径 - * @param options 裁剪配置 + * @param options 裁剪配置 */ - void onCrop(MultipleCrop multipleCrop, CropOptions options)throws TException; + void onCrop(MultipleCrop multipleCrop, CropOptions options) throws TException; + void permissionNotify(PermissionManager.TPermissionType type); + /** * 启用图片压缩 - * @param config 压缩图片配置 + * + * @param config 压缩图片配置 * @param showCompressDialog 压缩时是否显示进度对话框 */ - void onEnableCompress(CompressConfig config,boolean showCompressDialog); + void onEnableCompress(CompressConfig config, boolean showCompressDialog); /** * 设置TakePhoto相关配置 + * * @param options */ void setTakePhotoOptions(TakePhotoOptions options); + void onCreate(Bundle savedInstanceState); + void onSaveInstanceState(Bundle outState); + /** * 处理拍照或从相册选择的图片或裁剪的结果 + * * @param requestCode * @param resultCode * @param data */ void onActivityResult(int requestCode, int resultCode, Intent data); + /** * 拍照结果监听接口 */ interface TakeResultListener { void takeSuccess(TResult result); - void takeFail(TResult result,String msg); + void takeFail(TResult result, String msg); void takeCancel(); } diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoActivity.java b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoActivity.java similarity index 55% rename from takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoActivity.java rename to takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoActivity.java index 782c9923..8c758215 100644 --- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoActivity.java +++ b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoActivity.java @@ -1,42 +1,44 @@ -package com.jph.takephoto.app; +package org.devio.takephoto.app; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; -import com.jph.takephoto.R; -import com.jph.takephoto.model.InvokeParam; -import com.jph.takephoto.model.TContextWrap; -import com.jph.takephoto.model.TResult; -import com.jph.takephoto.permission.InvokeListener; -import com.jph.takephoto.permission.PermissionManager; -import com.jph.takephoto.permission.PermissionManager.TPermissionType; -import com.jph.takephoto.permission.TakePhotoInvocationHandler; +import org.devio.takephoto.model.InvokeParam; +import org.devio.takephoto.permission.PermissionManager; +import org.devio.takephoto.permission.TakePhotoInvocationHandler; +import org.devio.takephoto.R; +import org.devio.takephoto.model.TContextWrap; +import org.devio.takephoto.model.TResult; +import org.devio.takephoto.permission.InvokeListener; /** * 继承这个类来让Activity获取拍照的能力
* 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 TakePhotoActivity extends Activity implements TakePhoto.TakeResultListener,InvokeListener{ +public class TakePhotoActivity extends Activity implements TakePhoto.TakeResultListener, InvokeListener { private static final String TAG = TakePhotoActivity.class.getName(); private TakePhoto takePhoto; private InvokeParam invokeParam; + @Override protected void onCreate(Bundle savedInstanceState) { getTakePhoto().onCreate(savedInstanceState); super.onCreate(savedInstanceState); } + @Override protected void onSaveInstanceState(Bundle outState) { getTakePhoto().onSaveInstanceState(outState); super.onSaveInstanceState(outState); } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { getTakePhoto().onActivityResult(requestCode, resultCode, data); @@ -46,38 +48,42 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,permissions,grantResults); - PermissionManager.handlePermissionsResult(this,type,invokeParam,this); + PermissionManager.TPermissionType type = PermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults); + PermissionManager.handlePermissionsResult(this, type, invokeParam, this); } /** - * 获取TakePhoto实例 + * 获取TakePhoto实例 + * * @return */ - public TakePhoto getTakePhoto(){ - if (takePhoto==null){ - takePhoto= (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this,this)); + public TakePhoto getTakePhoto() { + if (takePhoto == null) { + takePhoto = (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this, this)); } return takePhoto; } + @Override public void takeSuccess(TResult result) { - Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath()); + Log.i(TAG, "takeSuccess:" + result.getImage().getCompressPath()); } + @Override - public void takeFail(TResult result,String msg) { + public void takeFail(TResult result, String msg) { Log.i(TAG, "takeFail:" + msg); } + @Override public void takeCancel() { Log.i(TAG, getResources().getString(R.string.msg_operation_canceled)); } @Override - public TPermissionType invoke(InvokeParam invokeParam) { - TPermissionType type=PermissionManager.checkPermission(TContextWrap.of(this),invokeParam.getMethod()); - if(TPermissionType.WAIT.equals(type)){ - this.invokeParam=invokeParam; + public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) { + PermissionManager.TPermissionType type = PermissionManager.checkPermission(TContextWrap.of(this), invokeParam.getMethod()); + if (PermissionManager.TPermissionType.WAIT.equals(type)) { + this.invokeParam = invokeParam; } return type; } diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragment.java b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoFragment.java similarity index 58% rename from takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragment.java rename to takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoFragment.java index 8d054a62..2fd540ea 100644 --- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragment.java +++ b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoFragment.java @@ -1,28 +1,27 @@ -package com.jph.takephoto.app; +package org.devio.takephoto.app; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; -import com.jph.takephoto.R; -import com.jph.takephoto.model.InvokeParam; -import com.jph.takephoto.model.TContextWrap; -import com.jph.takephoto.model.TResult; -import com.jph.takephoto.permission.InvokeListener; -import com.jph.takephoto.permission.PermissionManager; -import com.jph.takephoto.permission.TakePhotoInvocationHandler; +import org.devio.takephoto.permission.PermissionManager; +import org.devio.takephoto.permission.TakePhotoInvocationHandler; +import org.devio.takephoto.model.InvokeParam; +import org.devio.takephoto.model.TContextWrap; +import org.devio.takephoto.model.TResult; +import org.devio.takephoto.permission.InvokeListener; /** * 继承这个类来让Fragment获取拍照的能力
* 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 TakePhotoFragment extends Fragment implements TakePhoto.TakeResultListener,InvokeListener { +public class TakePhotoFragment extends Fragment implements TakePhoto.TakeResultListener, InvokeListener { private static final String TAG = TakePhotoFragment.class.getName(); private InvokeParam invokeParam; private TakePhoto takePhoto; @@ -32,49 +31,58 @@ public void onCreate(Bundle savedInstanceState) { getTakePhoto().onCreate(savedInstanceState); super.onCreate(savedInstanceState); } + @Override public void onSaveInstanceState(Bundle outState) { getTakePhoto().onSaveInstanceState(outState); super.onSaveInstanceState(outState); } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { getTakePhoto().onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data); } + @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - PermissionManager.TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,permissions,grantResults); - PermissionManager.handlePermissionsResult(getActivity(),type,invokeParam,this); + PermissionManager.TPermissionType type = PermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults); + PermissionManager.handlePermissionsResult(getActivity(), type, invokeParam, this); } + /** - * 获取TakePhoto实例 + * 获取TakePhoto实例 + * * @return */ - public TakePhoto getTakePhoto(){ - if (takePhoto==null){ - takePhoto= (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this,this)); + public TakePhoto getTakePhoto() { + if (takePhoto == null) { + takePhoto = (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this, this)); } return takePhoto; } + @Override public void takeSuccess(TResult result) { - Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath()); + Log.i(TAG, "takeSuccess:" + result.getImage().getCompressPath()); } + @Override - public void takeFail(TResult result,String msg) { + public void takeFail(TResult result, String msg) { Log.i(TAG, "takeFail:" + msg); } + @Override public void takeCancel() { - Log.i(TAG, getResources().getString(R.string.msg_operation_canceled)); + Log.i(TAG, getResources().getString(org.devio.takephoto.R.string.msg_operation_canceled)); } + @Override public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) { - PermissionManager.TPermissionType type=PermissionManager.checkPermission(TContextWrap.of(this),invokeParam.getMethod()); - if(PermissionManager.TPermissionType.WAIT.equals(type)){ - this.invokeParam=invokeParam; + PermissionManager.TPermissionType type = PermissionManager.checkPermission(TContextWrap.of(this), invokeParam.getMethod()); + if (PermissionManager.TPermissionType.WAIT.equals(type)) { + this.invokeParam = invokeParam; } return type; } diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragmentActivity.java b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoFragmentActivity.java similarity index 56% rename from takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragmentActivity.java rename to takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoFragmentActivity.java index 95756679..9bced23b 100644 --- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragmentActivity.java +++ b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoFragmentActivity.java @@ -1,79 +1,88 @@ -package com.jph.takephoto.app; +package org.devio.takephoto.app; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.util.Log; -import com.jph.takephoto.R; -import com.jph.takephoto.model.InvokeParam; -import com.jph.takephoto.model.TContextWrap; -import com.jph.takephoto.model.TResult; -import com.jph.takephoto.permission.InvokeListener; -import com.jph.takephoto.permission.PermissionManager; -import com.jph.takephoto.permission.TakePhotoInvocationHandler; +import org.devio.takephoto.permission.PermissionManager; +import org.devio.takephoto.model.InvokeParam; +import org.devio.takephoto.model.TContextWrap; +import org.devio.takephoto.model.TResult; +import org.devio.takephoto.permission.InvokeListener; +import org.devio.takephoto.permission.TakePhotoInvocationHandler; /** * 继承这个类来让Activity获取拍照的能力
* 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 TakePhotoFragmentActivity extends FragmentActivity implements TakePhoto.TakeResultListener,InvokeListener { +public class TakePhotoFragmentActivity extends FragmentActivity implements TakePhoto.TakeResultListener, InvokeListener { private static final String TAG = TakePhotoFragmentActivity.class.getName(); private TakePhoto takePhoto; private InvokeParam invokeParam; + @Override protected void onCreate(Bundle savedInstanceState) { getTakePhoto().onCreate(savedInstanceState); super.onCreate(savedInstanceState); } + @Override protected void onSaveInstanceState(Bundle outState) { getTakePhoto().onSaveInstanceState(outState); super.onSaveInstanceState(outState); } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { getTakePhoto().onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data); } + @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - PermissionManager.TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,permissions,grantResults); - PermissionManager.handlePermissionsResult(this,type,invokeParam,this); + PermissionManager.TPermissionType type = PermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults); + PermissionManager.handlePermissionsResult(this, type, invokeParam, this); } + /** - * 获取TakePhoto实例 + * 获取TakePhoto实例 + * * @return */ - public TakePhoto getTakePhoto(){ - if (takePhoto==null){ - takePhoto= (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this,this)); + public TakePhoto getTakePhoto() { + if (takePhoto == null) { + takePhoto = (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this, this)); } return takePhoto; } + @Override public void takeSuccess(TResult result) { - Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath()); + Log.i(TAG, "takeSuccess:" + result.getImage().getCompressPath()); } + @Override - public void takeFail(TResult result,String msg) { + public void takeFail(TResult result, String msg) { Log.i(TAG, "takeFail:" + msg); } + @Override public void takeCancel() { - Log.i(TAG, getResources().getString(R.string.msg_operation_canceled)); + Log.i(TAG, getResources().getString(org.devio.takephoto.R.string.msg_operation_canceled)); } + @Override public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) { - PermissionManager.TPermissionType type=PermissionManager.checkPermission(TContextWrap.of(this),invokeParam.getMethod()); - if(PermissionManager.TPermissionType.WAIT.equals(type)){ - this.invokeParam=invokeParam; + PermissionManager.TPermissionType type = PermissionManager.checkPermission(TContextWrap.of(this), invokeParam.getMethod()); + if (PermissionManager.TPermissionType.WAIT.equals(type)) { + this.invokeParam = invokeParam; } return type; } diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoImpl.java b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoImpl.java similarity index 80% rename from takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoImpl.java rename to takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoImpl.java index 34eb034f..73ab1090 100644 --- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoImpl.java +++ b/takephoto_library/src/main/java/org/devio/takephoto/app/TakePhotoImpl.java @@ -1,4 +1,4 @@ -package com.jph.takephoto.app; +package org.devio.takephoto.app; import android.app.Activity; import android.app.ProgressDialog; @@ -12,27 +12,26 @@ import com.darsh.multipleimageselect.helpers.Constants; import com.darsh.multipleimageselect.models.Image; -import com.jph.takephoto.R; -import com.jph.takephoto.compress.CompressConfig; -import com.jph.takephoto.compress.CompressImage; -import com.jph.takephoto.compress.CompressImageImpl; -import com.jph.takephoto.model.CropOptions; -import com.jph.takephoto.model.MultipleCrop; -import com.jph.takephoto.model.TContextWrap; -import com.jph.takephoto.model.TExceptionType; -import com.jph.takephoto.model.TImage; -import com.jph.takephoto.model.TIntentWap; -import com.jph.takephoto.model.TResult; -import com.jph.takephoto.model.TakePhotoOptions; -import com.jph.takephoto.permission.PermissionManager; -import com.jph.takephoto.uitl.ImageRotateUtil; -import com.jph.takephoto.uitl.IntentUtils; -import com.jph.takephoto.uitl.TConstant; -import com.jph.takephoto.model.TException; -import com.jph.takephoto.uitl.TFileUtils; -import com.jph.takephoto.uitl.TImageFiles; -import com.jph.takephoto.uitl.TUriParse; -import com.jph.takephoto.uitl.TUtils; +import org.devio.takephoto.compress.CompressImage; +import org.devio.takephoto.compress.CompressImageImpl; +import org.devio.takephoto.model.MultipleCrop; +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.permission.PermissionManager; +import org.devio.takephoto.uitl.TUriParse; +import org.devio.takephoto.compress.CompressConfig; +import org.devio.takephoto.model.CropOptions; +import org.devio.takephoto.model.TContextWrap; +import org.devio.takephoto.model.TResult; +import org.devio.takephoto.model.TakePhotoOptions; +import org.devio.takephoto.uitl.ImageRotateUtil; +import org.devio.takephoto.uitl.IntentUtils; +import org.devio.takephoto.uitl.TConstant; +import org.devio.takephoto.uitl.TFileUtils; +import org.devio.takephoto.uitl.TImageFiles; +import org.devio.takephoto.uitl.TUtils; import com.soundcloud.android.crop.Crop; import java.io.File; @@ -54,9 +53,9 @@ * - 支持因拍照Activity被回收后的自动恢复 * Date: 2016/9/21 0007 20:10 * Version:4.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 TakePhotoImpl implements TakePhoto { private static final String TAG = IntentUtils.class.getName(); @@ -126,7 +125,8 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { case TConstant.RC_PICK_PICTURE_FROM_GALLERY_ORIGINAL://从相册选择照片不裁剪 if (resultCode == Activity.RESULT_OK) { try { - takeResult(TResult.of(TImage.of(TUriParse.getFilePathWithUri(data.getData(), contextWrap.getActivity()), fromType))); + takeResult( + TResult.of(TImage.of(TUriParse.getFilePathWithUri(data.getData(), contextWrap.getActivity()), fromType))); } catch (TException e) { takeResult(TResult.of(TImage.of(data.getData(), fromType)), e.getDetailMessage()); e.printStackTrace(); @@ -138,7 +138,8 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { case TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_ORIGINAL://从文件选择照片不裁剪 if (resultCode == Activity.RESULT_OK) { try { - takeResult(TResult.of(TImage.of(TUriParse.getFilePathWithDocumentsUri(data.getData(), contextWrap.getActivity()), fromType))); + takeResult(TResult.of( + TImage.of(TUriParse.getFilePathWithDocumentsUri(data.getData(), contextWrap.getActivity()), fromType))); } catch (TException e) { takeResult(TResult.of(TImage.of(outPutUri, fromType)), e.getDetailMessage()); e.printStackTrace(); @@ -161,7 +162,9 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { break; case TConstant.RC_PICK_PICTURE_FROM_CAPTURE_CROP://拍取照片,并裁剪 if (resultCode == Activity.RESULT_OK) { - if(takePhotoOptions!=null&&takePhotoOptions.isCorrectImage())ImageRotateUtil.of().correctImage(contextWrap.getActivity(), tempUri); + if (takePhotoOptions != null && takePhotoOptions.isCorrectImage()) { + ImageRotateUtil.of().correctImage(contextWrap.getActivity(), tempUri); + } try { onCrop(tempUri, Uri.fromFile(new File(TUriParse.parseOwnUri(contextWrap.getActivity(), outPutUri))), cropOptions); } catch (TException e) { @@ -174,7 +177,9 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { break; case TConstant.RC_PICK_PICTURE_FROM_CAPTURE://拍取照片 if (resultCode == Activity.RESULT_OK) { - if(takePhotoOptions!=null&&takePhotoOptions.isCorrectImage())ImageRotateUtil.of().correctImage(contextWrap.getActivity(), outPutUri); + if (takePhotoOptions != null && takePhotoOptions.isCorrectImage()) { + ImageRotateUtil.of().correctImage(contextWrap.getActivity(), outPutUri); + } try { takeResult(TResult.of(TImage.of(TUriParse.getFilePathWithUri(outPutUri, contextWrap.getActivity()), fromType))); } catch (TException e) { @@ -234,7 +239,8 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { ArrayList images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES); if (cropOptions != null) { try { - onCrop(MultipleCrop.of(TUtils.convertImageToUri(contextWrap.getActivity(), images), contextWrap.getActivity(), fromType), cropOptions); + onCrop(MultipleCrop.of(TUtils.convertImageToUri(contextWrap.getActivity(), images), contextWrap.getActivity(), + fromType), cropOptions); } catch (TException e) { cropContinue(false); e.printStackTrace(); @@ -254,9 +260,11 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { @Override public void onPickMultiple(int limit) { - this.fromType = TImage.FromType.OTHER; - if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return; - TUtils.startActivityForResult(contextWrap, new TIntentWap(IntentUtils.getPickMultipleIntent(contextWrap, limit), TConstant.RC_PICK_MULTIPLE)); + if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) { + return; + } + TUtils.startActivityForResult(contextWrap, + new TIntentWap(IntentUtils.getPickMultipleIntent(contextWrap, limit), TConstant.RC_PICK_MULTIPLE)); } @Override @@ -271,10 +279,13 @@ public void onPickMultipleWithCrop(int limit, CropOptions options) { **/ @Override public void onCrop(Uri imageUri, Uri outPutUri, CropOptions options) throws TException { - if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return; + if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) { + return; + } this.outPutUri = outPutUri; if (!TImageFiles.checkMimeType(contextWrap.getActivity(), TImageFiles.getMimeType(contextWrap.getActivity(), imageUri))) { - Toast.makeText(contextWrap.getActivity(), contextWrap.getActivity().getResources().getText(R.string.tip_type_not_image), Toast.LENGTH_SHORT).show(); + Toast.makeText(contextWrap.getActivity(), contextWrap.getActivity().getResources().getText(org.devio.takephoto.R.string.tip_type_not_image), + Toast.LENGTH_SHORT).show(); throw new TException(TExceptionType.TYPE_NOT_IMAGE); } cropWithNonException(imageUri, outPutUri, options); @@ -304,7 +315,8 @@ private void cropContinue(boolean preSuccess) { if (preSuccess) { takeResult(TResult.of(multipleCrop.gettImages())); } else { - takeResult(TResult.of(multipleCrop.gettImages()), outPutUri.getPath() + contextWrap.getActivity().getResources().getString(R.string.msg_crop_canceled)); + takeResult(TResult.of(multipleCrop.gettImages()), + outPutUri.getPath() + contextWrap.getActivity().getResources().getString(org.devio.takephoto.R.string.msg_crop_canceled)); } } else { cropWithNonException(multipleCrop.getUris().get(index + 1), multipleCrop.getOutUris().get(index + 1), cropOptions); @@ -322,14 +334,19 @@ public void onPickFromGallery() { } private void selectPicture(int defaultIndex, boolean isCrop) { + this.fromType = TImage.FromType.OTHER; if (takePhotoOptions != null && takePhotoOptions.isWithOwnGallery()) { onPickMultiple(1); return; } - if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return; + if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) { + return; + } ArrayList intentWapList = new ArrayList<>(); - intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithDocuments(), isCrop ? TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_CROP : TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_ORIGINAL)); - intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithGallery(), isCrop ? TConstant.RC_PICK_PICTURE_FROM_GALLERY_CROP : TConstant.RC_PICK_PICTURE_FROM_GALLERY_ORIGINAL)); + intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithDocuments(), + isCrop ? TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_CROP : TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_ORIGINAL)); + intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithGallery(), + isCrop ? TConstant.RC_PICK_PICTURE_FROM_GALLERY_CROP : TConstant.RC_PICK_PICTURE_FROM_GALLERY_ORIGINAL)); try { TUtils.sendIntentBySafely(contextWrap, intentWapList, defaultIndex, isCrop); } catch (TException e) { @@ -355,7 +372,9 @@ public void onPickFromDocumentsWithCrop(Uri outPutUri, CropOptions options) { @Override public void onPickFromCapture(Uri outPutUri) { this.fromType = TImage.FromType.CAMERA; - if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return; + if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) { + return; + } if (Build.VERSION.SDK_INT >= 23) { this.outPutUri = TUriParse.convertFileUriToFileProviderUri(contextWrap.getActivity(), outPutUri); } else { @@ -363,7 +382,8 @@ public void onPickFromCapture(Uri outPutUri) { } try { - TUtils.captureBySafely(contextWrap, new TIntentWap(IntentUtils.getCaptureIntent(this.outPutUri), TConstant.RC_PICK_PICTURE_FROM_CAPTURE)); + TUtils.captureBySafely(contextWrap, + new TIntentWap(IntentUtils.getCaptureIntent(this.outPutUri), TConstant.RC_PICK_PICTURE_FROM_CAPTURE)); } catch (TException e) { takeResult(TResult.of(TImage.of("", fromType)), e.getDetailMessage()); e.printStackTrace(); @@ -373,7 +393,9 @@ public void onPickFromCapture(Uri outPutUri) { @Override public void onPickFromCaptureWithCrop(Uri outPutUri, CropOptions options) { this.fromType = TImage.FromType.CAMERA; - if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return; + if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) { + return; + } this.cropOptions = options; this.outPutUri = outPutUri; if (Build.VERSION.SDK_INT >= 23) { @@ -383,7 +405,8 @@ public void onPickFromCaptureWithCrop(Uri outPutUri, CropOptions options) { } try { - TUtils.captureBySafely(contextWrap, new TIntentWap(IntentUtils.getCaptureIntent(this.tempUri), TConstant.RC_PICK_PICTURE_FROM_CAPTURE_CROP)); + TUtils.captureBySafely(contextWrap, + new TIntentWap(IntentUtils.getCaptureIntent(this.tempUri), TConstant.RC_PICK_PICTURE_FROM_CAPTURE_CROP)); } catch (TException e) { takeResult(TResult.of(TImage.of("", fromType)), e.getDetailMessage()); e.printStackTrace(); @@ -410,36 +433,42 @@ private void takeResult(final TResult result, final String... message) { if (null == compressConfig) { handleTakeCallBack(result, message); } else { - if (showCompressDialog) - wailLoadDialog = TUtils.showProgressDialog(contextWrap.getActivity(), contextWrap.getActivity().getResources().getString(R.string.tip_compress)); + if (showCompressDialog) { + wailLoadDialog = TUtils.showProgressDialog(contextWrap.getActivity(), + contextWrap.getActivity().getResources().getString(org.devio.takephoto.R.string.tip_compress)); + } CompressImageImpl.of(contextWrap.getActivity(), compressConfig, result.getImages(), new CompressImage.CompressListener() { @Override public void onCompressSuccess(ArrayList images) { - if(!compressConfig.isEnableReserveRaw()) { + if (!compressConfig.isEnableReserveRaw()) { deleteRawFile(images); } handleTakeCallBack(result); - if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing()) + if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing()) { wailLoadDialog.dismiss(); + } } @Override public void onCompressFailed(ArrayList images, String msg) { - if(!compressConfig.isEnableReserveRaw()) { + if (!compressConfig.isEnableReserveRaw()) { deleteRawFile(images); } - handleTakeCallBack(TResult.of(images), String.format(contextWrap.getActivity().getResources().getString(R.string.tip_compress_failed), message.length > 0 ? message[0] : "", msg, result.getImage().getCompressPath())); - if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing()) + handleTakeCallBack(TResult.of(images), + String.format(contextWrap.getActivity().getResources().getString(org.devio.takephoto.R.string.tip_compress_failed), + message.length > 0 ? message[0] : "", msg, result.getImage().getCompressPath())); + if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing()) { wailLoadDialog.dismiss(); + } } }).compress(); } } private void deleteRawFile(ArrayList 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