这是一个调用摄像头拍照和相册选择设置头像的Android调用摄像头和相册简单示例。
一、调用相机进行拍照
1.创建文件存储相机拍摄的图片
/* 第一个参数是文件目录 第二个参数是文件的名称 应用的关联的缓存目录:就是SD卡中专门用于存放当前应用缓存数据的位置。 getExternalCacheDir()就可以获取到这个目录 /sdcard/Android/data/<package name>/cache Android6.0系统开始,读写SD卡被列为危险权限如果你要使用其他的SD 卡储存位置都需要进行运行时权限处理才行,使用这个目录则可以跳过这个操作 */ //创建一个文件对象,用于储存拍照后的图片 File outputImage = new File(getExternalCacheDir(),"output_image.jpg");
2.为你的图片解析URI
//对运行的设备系统进行判断如果低于Android 7.0 // 就调用Uri。fromFile()将file独享转化为uri对象 if (Build.VERSION.SDK_INT >= 24){ //将file转化为封装过得Uri对象 /* getUriFroFile() 第一个参数是content 第二个参数是任何唯一的字符串 第三个参数是File对象 Android7.0开始意识到直接使用真实地址是不安全的 FileProvider是文件内容提供器, 使用提供与内容提供器相似的机制来实现输几局的保存。 可以选择性的将封装过得Uri共享给外部。 */ imageUri = FileProvider.getUriForFile(MainActivity.this, "com.example.a12068.cameraalumtest.fileprovider", outputImage); }else { imageUri = Uri.fromFile(outputImage); }
3.启动相机程序拍照
//启动相机程序 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //指定图片的输出地址 intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri); startActivityForResult(intent,TAKE_PHOTO);
4.将图片取出显示
//将图片显示出来 Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver(). openInputStream(imageUri)); imageView_picture.setImageBitmap(bitmap);
5.注册内容提供器
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.a12068.cameraalumtest.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider>
6.申请SD卡的读取权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
二、从相册中选取
1.进行运行时权限处理
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1); }else { openAlbum(); }
2.打开相册
Intent intent = new Intent("android.intent.action.GET_CONTENT"); intent.setType("images/*"); startActivityForResult(intent,CHOOSE_PHOTO);//打开相册
3.解析Uri
//判断手机的版本号 if (Build.VERSION.SDK_INT >= 19) { //4.4及以上的系统使用的这个方法处理图片 handleImageOnKitKat(data); }else { //4.4以下的系统使用的图片处理方法 handleImageBeforeKitKat(data);
4.显示图片
Bitmap bitmap = BitmapFactory.decodeFile(imagePath); imageView_picture.setImageBitmap(bitmap);
三、整体程序
public class MainActivity extends AppCompatActivity { private static final int TAKE_PHOTO = 1; private static final int CHOOSE_PHOTO = 2; private Button button_take_photo; private Button button_choose_photo_form_album; private ImageView imageView_picture; private Uri imageUri; @SuppressLint("WrongViewCast") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView_picture = findViewById(R.id.imageView_picture); button_take_photo = findViewById(R.id.button_take_photo); button_choose_photo_form_album = findViewById(R.id.button_choose_from_album); button_take_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { /* 第一个参数是文件目录 第二个参数是文件的名称 应用的关联的缓存目录:就是SD卡中专门用于存放当前应用缓存数据的位置。 getExternalCacheDir()就可以获取到这个目录 /sdcard/Android/data/<package name>/cache Android6.0系统开始,读写SD卡被列为危险权限如果你要使用其他的SD 卡储存位置都需要进行运行时权限处理才行,使用这个目录则可以跳过这个操作 */ //创建一个文件对象,用于储存拍照后的图片 File outputImage = new File(getExternalCacheDir(),"output_image.jpg"); try { if(outputImage.exists()) { outputImage.delete(); } outputImage.canExecute(); } catch (Exception e) { e.printStackTrace(); } //对运行的设备系统进行判断如果低于Android 7.0 // 就调用Uri。fromFile()将file独享转化为uri对象 if (Build.VERSION.SDK_INT >= 24){ //将file转化为封装过得Uri对象 /* getUriFroFile() 第一个参数是content 第二个参数是任何唯一的字符串 第三个参数是File对象 Android7.0开始意识到直接使用真实地址是不安全的 FileProvider是文件内容提供器, 使用提供与内容提供器相似的机制来实现输几局的保存。 可以选择性的将封装过得Uri共享给外部。 */ imageUri = FileProvider.getUriForFile(MainActivity.this, "com.example.a12068.cameraalumtest.fileprovider", outputImage); }else { imageUri = Uri.fromFile(outputImage); } //启动相机程序 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //指定图片的输出地址 intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri); startActivityForResult(intent,TAKE_PHOTO); } }); button_choose_photo_form_album.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1); }else { openAlbum(); } } }); } private void openAlbum() { Intent intent = new Intent("android.intent.action.GET_CONTENT"); intent.setType("images/*"); startActivityForResult(intent,CHOOSE_PHOTO);//打开相册 } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case 1: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { openAlbum(); }else { Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show(); } break; default: } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case TAKE_PHOTO: if (resultCode == RESULT_OK) { try { //将图片显示出来 Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver(). openInputStream(imageUri)); imageView_picture.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; case CHOOSE_PHOTO: if (resultCode == RESULT_OK) { //判断手机的版本号 if (Build.VERSION.SDK_INT >= 19) { //4.4及以上的系统使用的这个方法处理图片 handleImageOnKitKat(data); }else { //4.4以下的系统使用的图片处理方法 handleImageBeforeKitKat(data); } } default: break; } } private void handleImageOnKitKat(Intent data) { String imagePath = null; Uri uri = data.getData(); if (DocumentsContract.isDocumentUri(this,uri)) { //如果document类型的Uri,则通过document id处理 String docId = DocumentsContract.getDocumentId(uri); if ("com.android.providers.media.documents".equals(uri.getAuthority())) { String id = docId.split(":")[1];//解析出数字格式的id String selection = MediaStore.Images.Media._ID+"="+id; imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection); }else if("com.android.providers.downloads.documents".equals(uri.getAuthority())){ 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); imageView_picture.setImageBitmap(bitmap); }else { Toast.makeText(this,"failed to get image",Toast.LENGTH_SHORT).show(); } } private String getImagePath(Uri externalContentUri, String selection) { String path = null; //通过Uri和selection来获取真实的图片路径 Cursor cursor = getContentResolver().query(externalContentUri, null,selection,null,null); if (cursor != null) { if (cursor.moveToFirst()) { path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); } return path; } private void handleImageBeforeKitKat(Intent data) { Uri uri = data.getData(); String imagePath = getImagePath(uri,null); displayImage(imagePath); } }