Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

LwkCoder/ImagePicker

Open more actions menu

Repository files navigation

ImagePicker

【不再维护,如有bug、需求,请自行clone源码修改】

Android10以上的注意事项

在Android10以上由于新增了作用域外部存储的访问限制,所以在设置ImagePicker的缓存路径时(拍照、裁剪),不可使用非App作用域的以外的存储路径当作缓存目录,比如以下路径就不能使用:

//不可设置这样的缓存路径
Environment.getExternalStorageDirectory().getAbsolutePath()+"/mycache/"

否则会发生错误:

java.io.FileNotFoundException: /storage/emulated/0/mycache/IMG_1586834402947.jpg: open failed: ENOENT (No such file or directory)

进而导致在Activity的onActivityResult()中无法获取返回数据,引起崩溃:

2020-04-14 11:20:09.844 13553-13553/com.lwkandroid.imagepicker E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.lwkandroid.imagepicker, PID: 13553
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=111, result=-1, data=Intent { (has extras) }} to activity {com.lwkandroid.imagepicker/com.lwkandroid.imagepickerdemo.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.lwkandroid.imagepicker.data.ImageBean.toString()' on a null object reference
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5097)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5138)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7811)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.lwkandroid.imagepicker.data.ImageBean.toString()' on a null object reference
        at com.lwkandroid.imagepickerdemo.MainActivity.onActivityResult(MainActivity.java:91)
        at android.app.Activity.dispatchActivityResult(Activity.java:8292)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5090)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5138) 
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:7811) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076) 

解决方案:

1.AndroidManifest中添加android:requestLegacyExternalStorage="true"

ImagePicker在1.4.5的版本中已经在AndroidManifest中添加了android:requestLegacyExternalStorage="true",但这是一种临时解决方案。

2.使用App专属的缓存路径

ImagePicker在1.4.6中将原来默认的缓存路径改为context.getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath(),并且希望大家在使用的时候,如果要自定义缓存路径,请尽量使用作用域内的地址。



希望了解该项目的朋友可参考下面的博客
http://blog.csdn.net/lwk520136/article/details/65647033
http://www.jianshu.com/p/46b5918976e1

效果图:





使用方法:

1.添加Gradle依赖:

最新的版本号以这里为准

  #your-version是指的你自己项目里引用的版本号
  #last-version请查看上面的最新版本号

  #AndroidStudio3.0以下
  //在自己项目里添加Glide的引用(Glide要求4.0版本以上)
  compile("com.github.bumptech.glide:glide:your-version") {
      exclude(group: 'com.android.support', module: 'support-v4')
  }
  //在自己项目里添加support-V4的引用
  compile "com.android.support:support-v4:your-version"
  //添加该库引用,并去除自带的support-V4、Glide引用,防止版本冲突
  compile("com.lwkandroid:ImagePicker:last-verison") {
      exclude(group: 'com.android.support', module: 'support-v4')
      exclude(group: 'com.github.bumptech.glide', module: 'glide')
  }

  #AndroidStudio3.0以上
  //在自己项目里添加Glide的引用(Glide要求4.0版本以上)
  implementation("com.github.bumptech.glide:glide:your-version") {
      exclude(group: 'com.android.support', module: 'support-v4')
  }
  //在自己项目里添加support-V4的引用
  implementation "com.android.support:support-v4:your-version"
  //添加该库引用,并去除自带的support-V4、Glide引用,防止版本冲突
  implementation("com.lwkandroid:ImagePicker:last-verison") {
      exclude(group: 'com.android.support', module: 'support-v4')
      exclude(group: 'com.github.bumptech.glide', module: 'glide')
  }
  • 注意:如果自己项目里的Glide版本低于4.0,那么需要实现接口IImagePickerDisplayer,调用的时候传进去:
//代码中实现IImagePickerDisplayer接口
public class YourDisplayer implements IImagePickerDisplayer
{
    @Override
    public void display(Context context, String url, ImageView imageView, int maxWidth, int maxHeight)
    {
        //TODO 实现加载图片的方法
    }

    @Override
    public void display(Context context, String url, ImageView imageView, int placeHolder, int errorHolder, int maxWidth, int maxHeight)
    {
        //TODO 实现加载图片的方法
    }
}

//调用的时候手动添加.displayer()
    new ImagePicker()
        ... //省略配置参数
        .displayer(new YourDisplayer()) //改为自定义图片加载器,必须调用!!!
        .start(this, REQUEST_CODE); //自定义RequestCode

2.代码中使用:

    //发起图片选择
    new ImagePicker()
        .pickType(ImagePickType.MUTIL) //设置选取类型(拍照ONLY_CAMERA、单选SINGLE、多选MUTIL)
        .maxNum(9) //设置最大选择数量(此选项只对多选生效,拍照和单选都是1,修改后也无效)
        .needCamera(true) //是否需要在界面中显示相机入口(类似微信那样)
        .cachePath(cachePath) //自定义缓存路径(拍照和裁剪都需要用到缓存)
        .doCrop(1,1,300,300) //裁剪功能需要调用这个方法,多选模式下无效,参数:aspectX,aspectY,outputX,outputY
        .displayer(new GlideImagePickerDisplayer()) //自定义图片加载器,默认是Glide实现的,可自定义图片加载器
        .start(this, REQUEST_CODE); //自定义RequestCode

    //重写Activity或Fragment中OnActivityResult()
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null)
        {
            //获取选择的图片数据
            List<ImageBean> resultList = data.getParcelableArrayListExtra(ImagePicker.INTENT_RESULT_DATA);
        }
    }

混淆配置

-dontwarn com.lwkandroid.imagepicker.**
-keep class com.lwkandroid.imagepicker.**{*;}

注意事项

最新版本采用了自定义FileProvider的策略,故不用再修改清单文件。
参考博客:http://www.cnblogs.com/liushilin/p/6602364.html

感谢

项目中裁剪模块修改自开源项目:https://github.com/oginotihiro/cropview
感谢所有为开源做出贡献的人!

About

Android自定义图片选择器,图片选择类似微信样式,自带裁剪功能

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.