本文介绍图片选择框架Matisse的使用,实现图片的选择及使用相机进行拍摄,最后将选择或拍摄的照片显示在activity中。

这里仅做使用介绍,不做深入研究。

主要涉及处理安卓6.0权限的动态获取,这里使用rxpermissions

本文目录

1、github地址

2、项目结构

3、使用效果

4、使用准备

1)项目依赖

2)AndroidManifest.xml文件

3)filepaths.xml文件

4)添加Glide引擎

5、MainActivity中使用

6、参考

1、github地址

2、项目结构

74b92703e941

项目结构

3、使用效果

74b92703e941

获取权限

74b92703e941

照片选择

4、使用准备

1)项目依赖

根目录build.gradle添加

maven { url 'https://jitpack.io' }

app的build.gradle添加

implementation 'com.zhihu.android:matisse:0.5.2-beta4'

implementation 'com.github.bumptech.glide:glide:4.9.0'

annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

implementation 'com.github.tbruyelle:rxpermissions:0.10.2'

2)AndroidManifest.xml文件

注意添加的权限及provider

xmlns:tools="http://schemas.android.com/tools"

package="com.jsf.piccompresstest">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:roundIcon="@mipmap/ic_launcher_round"

android:supportsRtl="true"

android:theme="@style/AppTheme"

>

android:name="android.support.v4.content.FileProvider"

android:authorities="com.jsf.piccompresstest"

android:exported="false"

android:grantUriPermissions="true">

android:name="android.support.FILE_PROVIDER_PATHS"

android:resource="@xml/filepaths"/>

注意:

android:authorities="com.jsf.piccompresstest"

的值要与MainActivity中使用的值一致,不一定要包名。

.capture(true) // 使用相机,和 captureStrategy 一起使用

.captureStrategy(new CaptureStrategy(true, "com.jsf.piccompresstest"))

3)filepaths.xml文件

AndroidManifest.xml中android:resource="@xml/filepaths"主要是拍摄照片后的路径的设置,需要在res文件夹下添加xml文件夹,然后添加 filepaths.xml

4)添加Glide引擎

import android.content.Context;

import android.graphics.drawable.Drawable;

import android.net.Uri;

import android.widget.ImageView;

import com.bumptech.glide.Glide;

import com.bumptech.glide.Priority;

import com.bumptech.glide.request.RequestOptions;

import com.zhihu.matisse.engine.ImageEngine;

public class GlideLoadEngine implements ImageEngine {

/**

* Load thumbnail of a static image resource.

*

* @param context Context

* @param resize Desired size of the origin image

* @param placeholder Placeholder drawable when image is not loaded yet

* @param imageView ImageView widget

* @param uri Uri of the loaded image

*/

@Override

public void loadThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri) {

Glide.with(context)

.asBitmap() // some .jpeg files are actually gif

.load(uri)

.apply(new RequestOptions()

.override(resize, resize)

.placeholder(placeholder)

.centerCrop())

.into(imageView);

}

@Override

public void loadGifThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView,

Uri uri) {

Glide.with(context)

.asBitmap() // some .jpeg files are actually gif

.load(uri)

.apply(new RequestOptions()

.override(resize, resize)

.placeholder(placeholder)

.centerCrop())

.into(imageView);

}

@Override

public void loadImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {

Glide.with(context)

.load(uri)

.apply(new RequestOptions()

.override(resizeX, resizeY)

.priority(Priority.HIGH)

.fitCenter())

.into(imageView);

}

@Override

public void loadGifImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {

Glide.with(context)

.asGif()

.load(uri)

.apply(new RequestOptions()

.override(resizeX, resizeY)

.priority(Priority.HIGH)

.fitCenter())

.into(imageView);

}

@Override

public boolean supportAnimatedGif() {

return true;

}

}

5、MainActivity中使用

import android.Manifest;

import android.content.Context;

import android.content.Intent;

import android.content.pm.ActivityInfo;

import android.graphics.BitmapFactory;

import android.net.Uri;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.ImageView;

import android.widget.Toast;

import com.bumptech.glide.Glide;

import com.tbruyelle.rxpermissions2.RxPermissions;

import com.zhihu.matisse.Matisse;

import com.zhihu.matisse.MimeType;

import com.zhihu.matisse.filter.Filter;

import com.zhihu.matisse.internal.entity.CaptureStrategy;

import com.zhihu.matisse.internal.entity.IncapableCause;

import com.zhihu.matisse.internal.entity.Item;

import java.io.FileNotFoundException;

import java.io.InputStream;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

import io.reactivex.functions.Consumer;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

private ImageView mView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

findViewById(R.id.btn_select_pic).setOnClickListener(this);

mView = findViewById(R.id.iv_photo);

initPermission();

}

private void initPermission()

{

RxPermissions rxPermissions=new RxPermissions(this);

rxPermissions.request(

Manifest.permission.CAMERA

,Manifest.permission.WRITE_EXTERNAL_STORAGE

,Manifest.permission.READ_EXTERNAL_STORAGE

).subscribe(new Consumer() {

@Override

public void accept(Boolean aBoolean) throws Exception {

if (aBoolean){

//申请的权限全部允许

Toast.makeText(MainActivity.this, "允许了权限!", Toast.LENGTH_SHORT).show();

}else{

//只要有一个权限被拒绝,就会执行

Toast.makeText(MainActivity.this, "未授权权限,部分功能不能使用", Toast.LENGTH_SHORT).show();

}

}

});

}

@Override

public void onClick(View view) {

switch (view.getId())

{

case R.id.btn_select_pic:

selectPic();

break;

}

}

private final int REQUEST_CODE_CHOOSE_PHOTO_ALBUM = 1;

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == REQUEST_CODE_CHOOSE_PHOTO_ALBUM && resultCode == RESULT_OK)

{

//图片路径 同样视频地址也是这个 根据requestCode

List pathList = Matisse.obtainResult(data);

for (Uri _Uri : pathList)

{

Glide.with(this).load(_Uri).into(mView);

System.out.println(_Uri.getPath());

}

}

}

void selectPic()

{

Matisse.from(this)

.choose(MimeType.ofImage(), false)

.capture(true) // 使用相机,和 captureStrategy 一起使用

.captureStrategy(new CaptureStrategy(true, "com.jsf.piccompresstest"))

// R.style.Matisse_Zhihu (light mode)

// R.style.Matisse_Dracula (dark mode)

.theme(R.style.Matisse_Dracula)

.countable(true)

.maxSelectable(1)

.addFilter(new Filter() {

@Override

protected Set constraintTypes() {

return new HashSet() {{

add(MimeType.PNG);

}};

}

@Override

public IncapableCause filter(Context context, Item item) {

try {

InputStream inputStream = getContentResolver().openInputStream(item.getContentUri());

BitmapFactory.Options options = new BitmapFactory.Options();

options.inJustDecodeBounds = true;

BitmapFactory.decodeStream(inputStream, null, options);

int width = options.outWidth;

int height = options.outHeight;

// if (width >= 500)

// return new IncapableCause("宽度超过500px");

} catch (FileNotFoundException e) {

e.printStackTrace();

}

return null;

}

})

// .gridExpectedSize((int) getResources().getDimension(R.dimen.imageSelectDimen))

.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)

.thumbnailScale(0.87f)

.imageEngine(new GlideLoadEngine())

.forResult(REQUEST_CODE_CHOOSE_PHOTO_ALBUM);

}

}

activity_main.xml

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity"

android:orientation="vertical">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="选择图片"

android:id="@+id/btn_select_pic"/>

android:id="@+id/iv_photo"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

6、参考

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐