引言
权限设置与基本流程
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
从相机/相册获取图片
调用相机拍照
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
打开相册选取图片
Intent pickImageIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickImageIntent, REQUEST_IMAGE_PICK);
处理返回的URI
在onActivityResult
方法中,我们会收到一个URI数组。处理这些URI时,需要注意不同Android版本的差异。
Android 4.4(KitKat)及以下版本
在这些版本中,URI通常是文件路径的形式,可以直接使用。
if (requestCode == REQUEST_IMAGE_PICK && resultCode == RESULT_OK && data != null) {
Uri uri = data.getData();
String imagePath = getPath(this, uri);
// 处理图片
}
Android 4.4(KitKat)及以上版本
从Android 4.4开始,URI的形式发生了变化,需要特殊处理。
@SuppressLint("NewApi")
public String getPath(Context context, Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// 其他类型的URI处理
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
高效处理URI数组
AsyncTask<Uri, Void, List<String>> processImagesTask = new AsyncTask<Uri, Void, List<String>>() {
@Override
protected List<String> doInBackground(Uri... uris) {
List<String> imagePaths = new ArrayList<>();
for (Uri uri : uris) {
String imagePath = getPath(getApplicationContext(), uri);
imagePaths.add(imagePath);
}
return imagePaths;
}
@Override
protected void onPostExecute(List<String> imagePaths) {
// 处理图片路径
}
};
processImagesTask.execute(uris);
使用Glide优化图片加载
集成Glide
在build.gradle
中添加依赖:
implementation 'com.github.bumptech.glide:glide:4.x'
annotationProcessor 'com.github.bumptech.glide:compiler:4.x'
使用Glide加载图片
Glide.with(context)
.load(imagePath)
.into(imageView);
内存与磁盘缓存策略
Glide提供了强大的缓存机制,包括内存缓存和磁盘缓存。
内存缓存
Glide默认使用LruCache作为内存缓存策略,可以根据需要自定义缓存大小。
GlideBuilder builder = new GlideBuilder();
builder.setMemoryCache(new LruResourceCache(yourCacheSize));
Glide.init(context, builder);
磁盘缓存
Glide也支持磁盘缓存,可以通过配置来优化缓存策略。
Glide.with(context)
.load(imagePath)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);