android打开相机拍照和从相册选择图像遇见的坑,记录一下
环境:
Android71.2
API25
Android Studi 4.2.1
首先是在manifest声明权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testproject">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic = "true"
android:requestLegacyExternalStorage="true"
android:theme="@style/Theme.TestProject">
<activity android:name=".MainActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.testproject.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE"/>
</intent>
</queries>
</manifest>
其中file_paths文件为xml文件,在res目录下的xml文件夹新建一个file_paths.xml文件,里面内容为
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path
name="root"
path=""/>
<files-path
name="files"
path="/zlyt"/>
</paths>
下面是请求相机的示例代码
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int REQUEST_PHOTO_IMAGE_CAPTURE = 2;
private void requestCameraPermission() {
//申请权限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
Snackbar.make(findViewById(android.R.id.content), "Camera permission is needed to take pictures", Snackbar.LENGTH_INDEFINITE).setAction("OK", view -> ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 2)).show();
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 2);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
}
Intent intent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager())!=null){
startActivityForResult(intent,REQUEST_IMAGE_CAPTURE);
}
else{
Toast.makeText(this, "无法打开相机应用", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
showImage.setImageBitmap(imageBitmap);
}
else if(requestCode == REQUEST_PHOTO_IMAGE_CAPTURE && resultCode == RESULT_OK){
Uri photoUri = data.getData();
String filePath = getRealPathFromURI(this.context,photoUri);
Log.d("tag","图像路径="+filePath);
upload(filePath);
showImage.setImageURI(photoUri);
}
}
//打开相册
private void dispatchTakePhotoPictureIntent(){
Intent photoIntent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(photoIntent, REQUEST_PHOTO_IMAGE_CAPTURE);
}
遇见的问题:
1、相机打开拍完照以后闪退,resultCode不为-1等问题
需要查看manifest里面权限是否给够
2、data返回为null的问题
对于拍照的图像,一种是提前新建Uri文件,使用的时候可以直接使用Uri值,如下所示
//拍照存放路径
File fileDir = new File(Environment.getExternalStorageDirectory(),"Pictures") ;
if (!fileDir.exists()){
fileDir.getParentFile().mkdir();
}
mFilePath = fileDir.getAbsolutePath()+"/IMG_"+System.currentTimeMillis() + ".jpg";
Intent intent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager())!=null){
mFileUri = FileProvider.getUriForFile(this.context,"com.example.testproject.provider",new File(mFilePath));
intent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);
startActivityForResult(intent,REQUEST_IMAGE_CAPTURE);
}
else{
Toast.makeText(this, "无法打开相机应用", Toast.LENGTH_SHORT).show();
}
另一种是在onActivityResult中处理图像,如下所示
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
showImage.setImageBitmap(imageBitmap);
}
切记,两种方法不可同时出现,否则会冲突,导致data为null
3、不能获取到拍照的数据可能是权限不够,可以在打开相机之前进行判断,下面是两种申请的方法,可以选择其中一个
//申请权限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA}, 1);
Snackbar.make(findViewById(android.R.id.content), "Camera permission is needed to take pictures", Snackbar.LENGTH_INDEFINITE).setAction("OK", view -> ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 2)).show();
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 2);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
}
本文讲述了在Android应用中使用相机拍照和从相册选择图片时遇到的权限设置、闪退问题及解决方案,包括正确声明和请求相机、存储权限,以及处理拍照数据的方式。

被折叠的 条评论
为什么被折叠?



