android 8.0 调用相机 打开相册
16lz
2021-01-25
- 添加依赖
//动态权限 implementation 'pub.devrel:easypermissions:2.0.1'
- 添加权限
在清单文件中注册内容提供器, android:authorities 属性的值要和FileProvider.getUriForFile(MainActivity.this,VERA_FILEPROVIDER,outputImage)中第二个参数的值一样
创建@xml/file_paths
<?xml version="1.0" encoding="utf-8"?>
申请权限的代码:
String[] perms={ Manifest.permission.CAMERA,Manifest.permission.INTERNET,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE }; if (EasyPermissions.hasPermissions(this,perms)){ init(); }else{ EasyPermissions.requestPermissions(this,getString(R.string.permission),RC_CEMERA_AND_LOCATION,perms); }
- 调用相机 拍照并保存到相册
private void takePhoto() {// 创建file对象,用于存储拍照后的对象 File outputImage=new File(getExternalCacheDir(),"output_image.jpg"); try{ if (outputImage.exists())outputImage.delete(); outputImage.createNewFile(); } catch (IOException e) { e.printStackTrace(); } if (Build.VERSION.SDK_INT>=24){// FileProvider是一种特殊的内容提供器,使用了和内容提供器类似的机制来保护数据,可以选择性的将封装过的Uri共享给外部,从而提高应用的安全性。 mImageUri= FileProvider.getUriForFile(MainActivity.this,VERA_FILEPROVIDER,outputImage); }else{ mImageUri=Uri.fromFile(outputImage); }// 启动相机程序 Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 指定调用相机拍照后的照片存储的地址 intent.putExtra(MediaStore.EXTRA_OUTPUT,mImageUri); startActivityForResult(intent,TAKE_PHOTO_RC); }
- 打开相册 显示选中的图片
private void choosePhoto() { Intent intent=new Intent("android.intent.action.GET_CONTENT"); intent.setType("image/*"); startActivityForResult(intent,CHOOSE_PHOTO); }
在onActivityResult()中处理:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { switch (requestCode){ case TAKE_PHOTO_RC: if (resultCode==RESULT_OK){ try { Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(mImageUri)); mImage.setImageBitmap(bitmap);// 保存到相册 ImgUtil.saveImageToGallery(this,bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; case CHOOSE_PHOTO: if (resultCode==RESULT_OK){ if (Build.VERSION.SDK_INT>=19){ handleImageOn19(data); }else{ handleImageBefore10(data); } } } } private void handleImageBefore10(Intent intent) { Uri uri=intent.getData(); String imagePath=getImagePath(uri,null); displayImage(imagePath); } @TargetApi(19) private void handleImageOn19(Intent intent) { String imagePath=null; Uri uri=intent.getData(); if (DocumentsContract.isDocumentUri(this,uri)){// 如果是document类型的uri,通过document id处理 String docId=DocumentsContract.getDocumentId(uri); if (uri.getAuthority().equals("com.android.providers.media.documents")){ String id=docId.split(":")[1];//解析出数字格式的id String selection=MediaStore.Images.Media._ID+"="+id; imagePath=getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection); }else if (uri.getAuthority().equals("com.android.providers.downloads.documents")){ Uri contentUri= ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId)); imagePath=getImagePath(contentUri,null); } }else if ("content".equalsIgnoreCase(uri.getScheme())){// 如果是content类型的uri,则使用普通方式处理 imagePath=getImagePath(uri,null); }else if ("file".equalsIgnoreCase(uri.getScheme())){// 如果是file类型的uri,直接获取图片路径 imagePath=uri.getPath(); } displayImage(imagePath); } private void displayImage(String imagePath) { if (imagePath!=null){ Bitmap bitmap=BitmapFactory.decodeFile(imagePath); mImage.setImageBitmap(bitmap); }else{ Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show(); } } private String getImagePath(Uri uri, String selection) { String path=null;// 通过Uri和selection来获取真实的图片路径 Cursor cursor=getContentResolver().query(uri,null,selection,null,null); if (cursor!=null){ if (cursor.moveToFirst()){ path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); } return path; }
- 保存图片到相册
public class ImgUtil { public static void saveImageToGallery(Context context, Bitmap bitmap){// 首先保存图片 File appDir = new File(Environment.getExternalStorageDirectory(), "vgmap"); if (!appDir.exists()){ appDir.mkdirs(); } String filename=System.currentTimeMillis()+".jpg"; File file=new File(appDir,filename); try { FileOutputStream fileOutputStream=new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream); fileOutputStream.flush(); fileOutputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }// 其次把文件插入到系统图库 try { MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(),filename,null); } catch (FileNotFoundException e) { e.printStackTrace(); }// 最后通知图库更新 context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(file.getAbsolutePath()))); }}
整个MainActivity的代码:
package com.example.anew;import android.Manifest;import android.annotation.TargetApi;import android.content.ContentUris;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.provider.DocumentsContract;import android.provider.MediaStore;import android.support.annotation.Nullable;import android.support.v4.content.FileProvider;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;import com.example.anew.utils.ImgUtil;import pub.devrel.easypermissions.EasyPermissions;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final int TAKE_PHOTO_RC = 2; private static final int CHOOSE_PHOTO = 3; private Button mBtnTakephoto; private ImageView mImage; private Button mBtnChoosePhoto; private static final int RC_CEMERA_AND_LOCATION = 1; private static final String VERA_FILEPROVIDER = "VERA_FILEPROVIDER";// 照片所在的uri地址 private Uri mImageUri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtnTakephoto = (Button) findViewById(R.id.btn_takephoto); mImage = (ImageView) findViewById(R.id.image); mBtnChoosePhoto = (Button) findViewById(R.id.btn_choose_photo); mBtnTakephoto.setOnClickListener(this); mBtnChoosePhoto.setOnClickListener(this); String[] perms={ Manifest.permission.CAMERA,Manifest.permission.INTERNET,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE }; if (EasyPermissions.hasPermissions(this,perms)){ init(); }else{ EasyPermissions.requestPermissions(this,getString(R.string.permission),RC_CEMERA_AND_LOCATION,perms); } } private void init() { } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_takephoto: takePhoto(); break; case R.id.btn_choose_photo: choosePhoto(); break; } } private void choosePhoto() { Intent intent=new Intent("android.intent.action.GET_CONTENT"); intent.setType("image/*"); startActivityForResult(intent,CHOOSE_PHOTO); } private void takePhoto() {// 创建file对象,用于存储拍照后的对象 File outputImage=new File(getExternalCacheDir(),"output_image.jpg"); try{ if (outputImage.exists())outputImage.delete(); outputImage.createNewFile(); } catch (IOException e) { e.printStackTrace(); } if (Build.VERSION.SDK_INT>=24){// FileProvider是一种特殊的内容提供器,使用了和内容提供器类似的机制来保护数据,可以选择性的将封装过的Uri共享给外部,从而提高应用的安全性。 mImageUri= FileProvider.getUriForFile(MainActivity.this,VERA_FILEPROVIDER,outputImage); }else{ mImageUri=Uri.fromFile(outputImage); }// 启动相机程序 Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 指定调用相机拍照后的照片存储的地址 intent.putExtra(MediaStore.EXTRA_OUTPUT,mImageUri); startActivityForResult(intent,TAKE_PHOTO_RC); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { switch (requestCode){ case TAKE_PHOTO_RC: if (resultCode==RESULT_OK){ try { Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(mImageUri)); mImage.setImageBitmap(bitmap);// 保存到相册 ImgUtil.saveImageToGallery(this,bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; case CHOOSE_PHOTO: if (resultCode==RESULT_OK){ if (Build.VERSION.SDK_INT>=19){ handleImageOn19(data); }else{ handleImageBefore10(data); } } } } private void handleImageBefore10(Intent intent) { Uri uri=intent.getData(); String imagePath=getImagePath(uri,null); displayImage(imagePath); } @TargetApi(19) private void handleImageOn19(Intent intent) { String imagePath=null; Uri uri=intent.getData(); if (DocumentsContract.isDocumentUri(this,uri)){// 如果是document类型的uri,通过document id处理 String docId=DocumentsContract.getDocumentId(uri); if (uri.getAuthority().equals("com.android.providers.media.documents")){ String id=docId.split(":")[1];//解析出数字格式的id String selection=MediaStore.Images.Media._ID+"="+id; imagePath=getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection); }else if (uri.getAuthority().equals("com.android.providers.downloads.documents")){ Uri contentUri= ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId)); imagePath=getImagePath(contentUri,null); } }else if ("content".equalsIgnoreCase(uri.getScheme())){// 如果是content类型的uri,则使用普通方式处理 imagePath=getImagePath(uri,null); }else if ("file".equalsIgnoreCase(uri.getScheme())){// 如果是file类型的uri,直接获取图片路径 imagePath=uri.getPath(); } displayImage(imagePath); } private void displayImage(String imagePath) { if (imagePath!=null){ Bitmap bitmap=BitmapFactory.decodeFile(imagePath); mImage.setImageBitmap(bitmap); }else{ Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show(); } } private String getImagePath(Uri uri, String selection) { String path=null;// 通过Uri和selection来获取真实的图片路径 Cursor cursor=getContentResolver().query(uri,null,selection,null,null); if (cursor!=null){ if (cursor.moveToFirst()){ path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); } return path; }}
更多相关文章
- Android之drawBitmap方法
- Android(安卓)在SQLite中存取二进制图片
- android tween 四种动画
- Android(安卓)ApiDemos示例解析(85):Graphics->Vertices
- Android(安卓)图片切换,ImageSwitcher 学习
- Android调用系统裁剪的实现方法
- android native jni 代码
- android 拍照或从相册获取图片 返回 bitmap
- Android(安卓)WebView如何加载assets下的html文件