在Project的build.gradle下的repositories 添加
//YancyYe:GalleryPick
maven { url "https://jitpack.io" }
app的build.gradle添加依赖
implementation 'com.github.YancyYe:GalleryPick:1.2.1'
implementation 'com.github.bumptech.glide:glide:4.8.0'
implementation 'top.zibin:Luban:1.1.3'
implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
一些工具类
public class AvatarStudio extends DialogFragment implements View.OnClickListener {
public static final String EXTRA_NEEDCROP = "needcrop";
public static final String EXTRA_TEXT_CAMERA = "text_camera";
public static final String EXTRA_TEXT_GALLERY = "text_gallery";
public static final String EXTRA_TEXT_CANCEL = "text_cancel";
public static final String BAOMING = "baoming";
public static final boolean DEFAULT_NEEDCROP = false;
private static final int CAMAER_REQUEST_STORAGE_WRITE_ACCESS_PERMISSION = 110;
private static final int GALLERY_REQUEST_STORAGE_WRITE_ACCESS_PERMISSION = 111;
private boolean mNeedCrop;
private boolean mDimEnabled;
private String cameraText;
private String galleryText;
private String cancelText;
private String baoming;
private GalleryConfig galleryConfig;
private List<String> path = new ArrayList<>();
private IHandlerCallBack iHandlerCallBack;
public static final String TAG = "哈哈";
private final int PERMISSIONS_REQUEST_READ_CONTACTS = 8;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNeedCrop = getArguments().getBoolean(EXTRA_NEEDCROP, DEFAULT_NEEDCROP);
cameraText = getArguments().getString(EXTRA_TEXT_CAMERA, "相机");
galleryText = getArguments().getString(EXTRA_TEXT_GALLERY, "图库");
cancelText = getArguments().getString(EXTRA_TEXT_CANCEL, "取消");
baoming = getArguments().getString(BAOMING, "");
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new Dialog(getActivity(),
mDimEnabled ? R.style.BottomDialogDim : R.style.BottomDialog);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_layout);
dialog.setCanceledOnTouchOutside(true);
Window window = dialog.getWindow();
if (window != null) {
WindowManager.LayoutParams lp = window.getAttributes();
lp.gravity = Gravity.BOTTOM;
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
window.setAttributes(lp);
}
initView(dialog);
return dialog;
}
private void initView(Dialog dialog) {
TextView camera = dialog.findViewById(R.id.camera);
camera.setText(cameraText);
camera.setOnClickListener(this);
TextView gallery = dialog.findViewById(R.id.gallery);
gallery.setText(galleryText);
gallery.setOnClickListener(this);
TextView cancel = dialog.findViewById(R.id.cancel);
cancel.setText(cancelText);
cancel.setOnClickListener(this);
initGallery();
galleryConfig = new GalleryConfig.Builder()
.imageLoader(new GlideImageLoader()) // ImageLoader 加载框架(必填)
.iHandlerCallBack(iHandlerCallBack) // 监听接口(必填)
.provider(baoming) // provider(必填)
.pathList(path) // 记录已选的图片
.multiSelect(false) // 是否多选 默认:false
.multiSelect(false, 9) // 配置是否多选的同时 配置多选数量 默认:false , 9
.maxSize(9) // 配置多选时 的多选数量。 默认:9
.crop(mNeedCrop) // 快捷开启裁剪功能,仅当单选 或直接开启相机时有效
.crop(mNeedCrop, 1, 1, 500, 500) // 配置裁剪功能的参数, 默认裁剪比例 1:1
.isShowCamera(true) // 是否现实相机按钮 默认:false
.filePath("/Gallery/Pictures") // 图片存放路径
.build();
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.camera) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
"需要您提供写/读存储权限",
CAMAER_REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
} else {
GalleryPick.getInstance().setGalleryConfig(galleryConfig).openCamera(mActivity);
dismiss();
}
} else if (id == R.id.gallery) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
"需要您提供写/读存储权限",
CAMAER_REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
} else {
galleryConfig.getBuilder().isOpenCamera(false).build();
GalleryPick.getInstance().setGalleryConfig(galleryConfig).open(mActivity);
dismiss();
}
} else if (id == R.id.cancel) {
dismiss();
}
}
private CallBack mCallBack;
public interface CallBack {
void callback(String uri);
}
private static FragmentActivity mActivity;
public static class Builder {
AvatarStudio mAvatarStudio;
public Builder(FragmentActivity activity) {
mActivity = activity;
mAvatarStudio = new AvatarStudio();
}
public Builder needCrop(boolean crop) {
mAvatarStudio.mNeedCrop = crop;
return this;
}
public Builder setText(String camera, String gallery, String cancel, String baoming) {
mAvatarStudio.cameraText = camera;
mAvatarStudio.galleryText = gallery;
mAvatarStudio.cancelText = cancel;
mAvatarStudio.baoming = baoming;
return this;
}
public AvatarStudio show(CallBack callBack) {
mAvatarStudio.mCallBack = callBack;
Bundle bundle = new Bundle();
bundle.putBoolean(EXTRA_NEEDCROP, mAvatarStudio.mNeedCrop);
bundle.putString(EXTRA_TEXT_CAMERA, mAvatarStudio.cameraText);
bundle.putString(EXTRA_TEXT_GALLERY, mAvatarStudio.galleryText);
bundle.putString(EXTRA_TEXT_CANCEL, mAvatarStudio.cancelText);
bundle.putString(BAOMING, mAvatarStudio.baoming);
mAvatarStudio.setArguments(bundle);
FragmentManager fm = mActivity.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment fragment = fm.findFragmentByTag("avatarStudio");
if (fragment != null) {
ft.remove(fragment);
}
ft.addToBackStack(null);
mAvatarStudio.show(ft, "avatarStudio");
return mAvatarStudio;
}
}
private void initGallery() {
iHandlerCallBack = new IHandlerCallBack() {
@Override
public void onStart() {
Log.i(TAG, "onStart: 开启");
}
@Override
public void onSuccess(List<String> photoList) {
Log.i(TAG, "onSuccess: 返回数据");
path.clear();
for (String s : photoList) {
Log.i(TAG, s);
path.add(s);
compressWithLs(s);
}
}
@Override
public void onCancel() {
Log.i(TAG, "onCancel: 取消");
}
@Override
public void onFinish() {
Log.i(TAG, "onFinish: 结束");
}
@Override
public void onError() {
Log.i(TAG, "onError: 出错");
}
};
}
/**
* 鲁班压缩
*/
private void compressWithLs(final String photos) {
Luban.with(mActivity)
.load(photos) // 传入需要压缩的图片列表
.ignoreBy(100) // 忽略不压缩图片的大小
.setTargetDir(getPath()) // 设置压缩后文件存储的路径
.setCompressListener(new OnCompressListener() { // 设置回调
@Override
public void onStart() {
//TODO 压缩前开始调用 ,可以在方法内启动
}
@Override
public void onSuccess(File file) {
// TODO 压缩成功后调用,返回压缩后的图片文件
//把压缩后的图片传给后台
if (mCallBack != null) {
mCallBack.callback(file.getAbsolutePath());
}
}
@Override
public void onError(Throwable e) {
// TODO 压缩过程中出现问题时调用
}
}).launch();
}
private String getPath() {
String path = Environment.getExternalStorageDirectory() + "/Luban/image/";
File file = new File(path);
if (file.mkdirs()) {
return path;
}
return path;
}
private void requestPermission(final String permission, String rationale, final int requestCode) {
if (shouldShowRequestPermissionRationale(permission)) {
new AlertDialog.Builder(getContext())
.setTitle("权限拒绝")
.setMessage(rationale)
.setPositiveButton("好", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{permission}, requestCode);
}
})
.setNegativeButton("拒绝", null)
.show();
} else {
requestPermissions(new String[]{permission}, requestCode);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults) {
if (requestCode == CAMAER_REQUEST_STORAGE_WRITE_ACCESS_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
GalleryPick.getInstance().setGalleryConfig(galleryConfig).openCamera(mActivity);
dismiss();
}
} else if (requestCode == GALLERY_REQUEST_STORAGE_WRITE_ACCESS_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
galleryConfig.getBuilder().isOpenCamera(false).build();
GalleryPick.getInstance().setGalleryConfig(galleryConfig).open(mActivity);
dismiss();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
public class GlideImageLoader implements ImageLoader {
private final static String TAG = "GlideImageLoader";
@Override
public void displayImage(Activity activity, Context context, String path, GalleryImageView galleryImageView, int width, int height) {
Glide.with(context)
.load(path)
.into(galleryImageView);
}
@Override
public void clearMemoryCache() {
}
}
public class Util {
private volatile static Util util = null;
private Util() {
}
public static Util getmInstance() {
if (util == null) {
synchronized (Util.class) {
if (util == null) {
util = new Util();
}
}
}
return util;
}
OkHttpClient httpClient = new OkHttpClient.Builder().
addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
public Testserivce getnetjson(String uri) {
Retrofit retrofit = new Retrofit.Builder().baseUrl(uri)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(httpClient)
.build();
Testserivce testservive = retrofit.create(Testserivce.class);
return testservive;
}
}
public interface Testserivce {
//第二种方式上传头像
@POST("mymessage/OCRapi")
@Multipart
Observable<Mymode> upload2(@Part() List<MultipartBody.Part> files);
}
MVP
public class Mypresenter {
private MyView myView;
public Mypresenter(MyView myView) {
this.myView = myView;
}
public void uptouxiang(String Phone, File file) {
MultipartBody multipartBody = filesToMultipartBody(file, Phone);
Observable<Mymode> uptouxiangObservable = Util.getmInstance().getnetjson(你的端口号).upload2(multipartBody.parts());
uptouxiangObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Mymode>() {
@Override
public void accept(Mymode mymode) throws Exception {
if (mymode.getReturnCode().equals("0")) {
myView.getDataSuccess(mymode);
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
myView.getDataFail(throwable.getMessage());
}
});
}
public MultipartBody filesToMultipartBody(File files, String Phone) {
MultipartBody.Builder builder = new MultipartBody.Builder();
// TODO: 16-4-2 这里为了简单起见,没有判断file的类型
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), files);
//给后台提交的图片名字
builder.addFormDataPart("file", files.getName(), requestBody);
builder.setType(MultipartBody.FORM);
//添加给后台提交所需要的参数
builder.addFormDataPart("Phone", Phone);
MultipartBody multipartBody = builder.build();
return multipartBody;
}
}
mymode=后台返回数据类
public interface MyView {
void getDataSuccess(Mymode mymode);
void getDataFail(String msg);
}
MainActivity
public class MainActivity extends AppCompatActivity implements MyView {
private AvatarStudio.Builder builder;
private ImageView iv;
Mypresenter mypresenter = new Mypresenter(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
builder = new AvatarStudio.Builder(MainActivity.this).needCrop(true)
//第三个参数为包名.fileprovider 必填
.setText("打开相机", "从相册中选取", "取消", "com.example.touxiang.fileprovider");
iv = findViewById(R.id.iv);
findViewById(R.id.bt).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
builder.show(new AvatarStudio.CallBack() {
@Override
public void callback(String uri) {
final Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(new FileInputStream(uri));
iv.setImageBitmap(bitmap);
//给后台上传图片和参数
mypresenter.uptouxiang(你要传的参数, new File(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
});
}
});
}
//上传成功
@Override
public void getDataSuccess(Mymode mymode) {
if (mymode.getReturnCode().equals("0")) {
Toast.makeText(this, mymode.getMessage(), Toast.LENGTH_LONG).show();
}
}
//上传失败
@Override
public void getDataFail(String msg) {
Log.i("msg", msg);
}
}