700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android调用相机与相册的方法 手把手教你:android调用系统相机 相册功能 适配6.0

android调用相机与相册的方法 手把手教你:android调用系统相机 相册功能 适配6.0

时间:2022-07-21 16:18:25

相关推荐

android调用相机与相册的方法 手把手教你:android调用系统相机 相册功能 适配6.0

Android中调用系统相机来拍摄照片的代码,以下:html

一、首先设置Uri获取判断以及相机请求Codejava

public final int TYPE_TAKE_PHOTO = 1;//Uri获取类型判断

public final int CODE_TAKE_PHOTO = 1;//相机RequestCode

二、调起系统相机android

Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Uri photoUri = getMediaFileUri(TYPE_TAKE_PHOTO);

takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);

startActivityForResult(takeIntent, CODE_TAKE_PHOTO);

三、封装获取Uri代码

public Uri getMediaFileUri(int type){

File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "相册名字");

if (!mediaStorageDir.exists()) {

if (!mediaStorageDir.mkdirs()) {

return null;

}

}

//建立Media File

String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

File mediaFile;

if (type == TYPE_TAKE_PHOTO) {

mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");

} else {

return null;

}

return Uri.fromFile(mediaFile);

}

四、相机拍照完毕后获取返回数据,并在页面显示照片api

@Override

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

super.onActivityResult(requestCode, resultCode, data);

switch (requestCode) {

case CODE_TAKE_PHOTO:

if (resultCode == RESULT_OK) {

if (data != null) {

if (data.hasExtra("data")) {

Log.i("URI", "data is not null");

Bitmap bitmap = data.getParcelableExtra("data");

imageView.setImageBitmap(bitmap);//imageView即为当前页面须要展现照片的控件,可替换

}

} else {

Log.i("URI", "Data is null");

Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath());

imageView.setImageBitmap(bitmap);//imageView即为当前页面须要展现照片的控件,可替换

}

}

break;

}

}

特殊:

通常状况,以上代码在Android7.0如下,也就是api<24时,运行是没有任何问题的。但是当targetSdkVersion变成24及其以上而且在android7.0(及以上版本)系统运行时,会抛出异常:FileUriExposedException。缓存

权限:ide

因为已经写过一篇文章对android6.0后权限设置和6.0之前权限设置进行过讲述,在此就再也不赘述如何配置权限了,对于6.0后权限设置不了解的,能够看看:通俗易懂,手把手教会你android 6.0后(兼容6.0以前版本)申请危险权限的方法。ui

Android7.0及以上版本调用系统相机this

一、为何会报FileUriExposedException异常spa

android N之后收回了访问文件的权限,按照android N的要求,若在应用间共享文件,须要发送Content://Uri,而再也不是File://Uri,而且须要对此Uri进行临时访问受权。.net

二、解决办法:

使用FileProvider,FileProvider是V4包下的类,继承自ContentProvider。

三、使用步骤:

①、首先在清单文件中进行FileProvider注册(与activity同级,四大组件没啥说的):

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

android:authorities="项目包名.fileprovider"

android:exported="false"

android:grantUriPermissions="true">

android:name="android.support.FILE_PROVIDER_PATHS"

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

补充:android:exported="false" 表示对其余应用不可用

android:grantUriPermissions="true" 授予临时权限

②、在res目录下新建xml文件夹,即res/xml,在xml中新建一个provider_path文件,以下:

补充:下通常经常使用如下子节点:

:Context.getFilesDir()——指向内部存储要共享的目录

:Context.getCacheDir()——指向缓存要共享的目录

:Environment.getExternalStorageDirectory()——指向外部存储要共享的目录

:还没有发现官方对其的说明,知道的童鞋欢迎补充。根据字面理解,为整个存储的根路径,针对诸如查找不到照片地址的Bug。

name为自定义的名字,path为目录,path=""指的是所有目录|path="."即为当前的根目录

③、只用更改上面贴出来的getMediaFileUri()方法,由于牵涉多版本调用相机,因此再封装一个适用于7.0以上获取Uri的方法get24MediaFileUri(),代码以下:

/**

* 版本24以上

*/

public Uri get24MediaFileUri(int type) {

File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "相册名字");

if (!mediaStorageDir.exists()) {

if (!mediaStorageDir.mkdirs()) {

return null;

}

}

//建立Media File

String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

File mediaFile;

if (type == TYPE_TAKE_PHOTO) {

mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");

} else {

return null;

}

return FileProvider.getUriForFile(this, getPackageName()+".fileprovider", mediaFile);

}

注意:get24MediaFileUri()与getMediaFileUri()惟一的不一样为:api24如下,使用的是Uri.fromFile(File)获取的Uri,api24及以上必须使用FileProvider,调用FileProvider.getUriForFile(this, getPackageName()+".fileprovider", File)来获取Uri。

④、7.0以上调用系统相机,以下:

Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Uri photoUri = get24MediaFileUri(TYPE_TAKE_PHOTO);

takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);

startActivityForResult(takeIntent, CODE_TAKE_PHOTO);

只是将Uri获取的途径由getMediaFileUri()改成了get24MediaFileUri()。

⑤、多版本适配

二、在权限获取后,判断SDK版本,而后进行相应操做,以下:

if (Build.VERSION.SDK_INT >= 24) {

Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Uri photoUri = get24MediaFileUri(TYPE_TAKE_PHOTO);

takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);

startActivityForResult(takeIntent, CODE_TAKE_PHOTO);

} else {

Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Uri photoUri = getMediaFileUri(TYPE_TAKE_PHOTO);

takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);

startActivityForResult(takeIntent, CODE_TAKE_PHOTO);

}

⑥、拍照完毕后,获取返回数据显示照片,api24之后,须要转换输入流来获取Bitmap,而输入流的获取须要经过getContentResolvrer.openInputStream()来获取,具体代码以下:

@Override

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

super.onActivityResult(requestCode, resultCode, data);

switch (requestCode) {

case CODE_TAKE_PHOTO:

if (resultCode == RESULT_OK) {

if (data != null) {

if (data.hasExtra("data")) {

Log.i("URI", "data is not null");

Bitmap bitmap = data.getParcelableExtra("data");

imageView.setImageBitmap(bitmap);//imageView即为当前页面须要展现照片的控件,可替换

}

} else {

Log.i("URI", "Data is null");

if (Build.VERSION.SDK_INT >= 24){

Bitmap bitmap = null;

try {

bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(photoUri));

} catch (FileNotFoundException e) {

e.printStackTrace();

}

imageView.setImageBitmap(bitmap);

}else {

Bitmap bitmap = BitmapFactory.decodeFile(photoUri.getPath());

imageView.setImageBitmap(bitmap);

}

}

}

break;

}

}

经过以上步骤,便可在多版本系统中调用系统相机并显示了。

系统相册选择图片

一、设置相册请求Code

public final int CODE_SELECT_IMAGE = 2;//相册RequestCode

二、调用系统相册

Intent albumIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

startActivityForResult(albumIntent, CODE_SELECT_IMAGE);

注意:相册在6.0后会用到访问存储设备这个危险权限,因此也得作权限适配

三、选择图片后,获取返回数据,并显示图片

@Override

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

super.onActivityResult(requestCode, resultCode, data);

switch (requestCode) {

case CODE_SELECT_IMAGE:

if (resultCode == RESULT_OK) {

selectPic(data);

}

break;

}

}

//选择照片

private void selectPic(Intent intent) {

Uri selectImageUri = intent.getData();

String[] filePathColumn = {MediaStore.Images.Media.DATA};

Cursor cursor = getContentResolver().query(selectImageUri, filePathColumn, null, null, null);

cursor.moveToFirst();

int columnIndex = cursor.getColumnIndex(filePathColumn[0]);

String picturePath = cursor.getString(columnIndex);

cursor.close();

imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));

}

以上便可调用系统相册选择照片,并显示。

android调用相机与相册的方法 手把手教你:android调用系统相机 相册功能 适配6.0权限获取以及7.0之后获取URI(兼容多版本)...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。