我正在开发一个应用,其中我们使用意图从相机或画廊中选择图像,并将其设置为 ImageView 。摄像头按钮功能正常工作。 问题是,当我第一次单击“图库”按钮时,当我允许该应用程序崩溃但图库打开时,它会询问权限。然后,当我第二次打开应用程序并再次单击“图库”按钮时,效果很好。 这是我的代码: WRITE_EXTERNAL_STORAGE 权限用于从相机意图拍摄图像和从Galley意图拍摄图像,这可能是导致问题的原因。但是我是android开发的新手,所以不知道如何解决它。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blogspot.atifsoftwares.myapplication">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageIv"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_launcher_background" />
<Button
android:id="@+id/galleryBtn"
android:text="Gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/cameraBtn"
android:text="Camera"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.java
package com.blogspot.atifsoftwares.myapplication;
import android.Manifest;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int IMAGE_PICK_GALLERY_CODE = 1000;
private static final int IMAGE_PICK_CAMERA_CODE = 1001;
private static final int PERMISSION_WRITE_STORAGE_CODE = 1002;
private static final int PERMISSION_CAMERA_CODE = 1003;
Uri image_uri;
ImageView mImageView;
Button mGalleryBtn, mCameraBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageIv);
mGalleryBtn = findViewById(R.id.galleryBtn);
mCameraBtn = findViewById(R.id.cameraBtn);
//Gallery button click listener to pick image from gallery
mGalleryBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
//System OS is Marshmallow or above
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED){
//permission not granted, request it.
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//show popup for runtime permission
requestPermissions(permissions, PERMISSION_WRITE_STORAGE_CODE);
}
else {
//permission already granted
pickGallery();
}
}
else {
//System OS is less then Marshmallow
pickGallery();
}
}
});
//Camera button click listener to pick image from gallery
mCameraBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
//System OS is Marshmallow or above
if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED ||
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
//permission not granted, request it.
String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
//show popup for runtime permission
requestPermissions(permissions, PERMISSION_CAMERA_CODE);
}
else {
//permission already granted
pickCamera();
}
}
else {
//System OS is less than Marshmallow
pickCamera();
}
}
});
}
public void pickCamera(){
//take image from default camera
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
public void pickGallery(){
//pick image from gallery
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK_GALLERY_CODE);
}
//handle result of runtime permission
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case PERMISSION_WRITE_STORAGE_CODE:{
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//permission was granted
Toast.makeText(this, "Gallery Granted", Toast.LENGTH_SHORT).show();
pickGallery();
}
else {
//permission was denied
Toast.makeText(this, "Permission denied...!", Toast.LENGTH_SHORT).show();
}
}
case PERMISSION_CAMERA_CODE:{
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//permission was granted
Toast.makeText(this, "Camera Granted", Toast.LENGTH_SHORT).show();
pickCamera();
}
else {
//permission was denied
Toast.makeText(this, "Permission denied...!", Toast.LENGTH_SHORT).show();
}
}
}
}
//handle result of picked image
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK){
if (requestCode == IMAGE_PICK_GALLERY_CODE){
//set image to image view
mImageView.setImageURI(data.getData());
}
if (requestCode == IMAGE_PICK_CAMERA_CODE){
//set image to image view
mImageView.setImageURI(image_uri);
}
}
}
}
这是logcat报告:
FATAL EXCEPTION: main
Process: com.blogspot.atifsoftwares.myapplication, PID: 24672
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1002, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.blogspot.atifsoftwares.myapplication/com.blogspot.atifsoftwares.myapplication.MainActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.oppo.camera/.Camera clip={text/uri-list U:content://media/external/images/media/58337} (has extras) } from ProcessRecord{f4a4aee 24672:com.blogspot.atifsoftwares.myapplication/u0a427} (pid=24672, uid=10427) with revoked permission android.permission.CAMERA
at android.app.ActivityThread.deliverResults(ActivityThread.java:4339)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4382)
at android.app.ActivityThread.-wrap20(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1679)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:186)
at android.app.ActivityThread.main(ActivityThread.java:6509)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:804)
Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.oppo.camera/.Camera clip={text/uri-list U:content://media/external/images/media/58337} (has extras) } from ProcessRecord{f4a4aee 24672:com.blogspot.atifsoftwares.myapplication/u0a427} (pid=24672, uid=10427) with revoked permission android.permission.CAMERA
at android.os.Parcel.readException(Parcel.java:1702)
at android.os.Parcel.readException(Parcel.java:1655)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3229)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1520)
at android.app.Activity.startActivityForResult(Activity.java:4434)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
at android.app.Activity.startActivityForResult(Activity.java:4369)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
at com.blogspot.atifsoftwares.myapplication.MainActivity.pickCamera(MainActivity.java:98)
at com.blogspot.atifsoftwares.myapplication.MainActivity.onRequestPermissionsResult(MainActivity.java:128)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7404)
at android.app.Activity.dispatchActivityResult(Activity.java:7256)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4335)
答案 0 :(得分:0)
当我们单击“相机”按钮时,您的应用程序崩溃了,它要求获得相机许可和存储许可。并且我们允许相机权限,但拒绝存储权限。发生崩溃的原因是:我们允许相机权限来捕获图像,但是我们还必须授予存储该图像的权限。否则会崩溃..
我试图重写代码以有效地获得许可。尝试这段代码,告诉我是否可行。
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final int CAMERA_REQUEST_CODE = 200;
public static final int STORAGE_REQUEST_CODE = 400;
private static final int IMAGE_PICK_GALLERY_CODE = 1000;
private static final int IMAGE_PICK_CAMERA_CODE = 1001;
Uri image_uri;
ImageView mImageView;
Button mGalleryBtn, mCameraBtn;
String cameraPermission[];
String storagePermission[];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageIv);
mGalleryBtn = findViewById(R.id.galleryBtn);
mCameraBtn = findViewById(R.id.cameraBtn);
cameraPermission = new String [] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
storagePermission = new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//Gallery button click listener to pick image from gallery
mGalleryBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!checkStoragePermission()) {
requestStoragePermission();
} else {
pickGallery();
}
}
});
//Camera button click listener to pick image from gallery
mCameraBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!checkCameraPermission()) {
requestCameraPermission();
} else {
pickCamera();
}
}
});
}
public void pickCamera() {
//take image from default camera
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
public void pickGallery() {
//pick image from gallery
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK_GALLERY_CODE);
}
public boolean checkStoragePermission() {
boolean result = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
return result;
}
public void requestStoragePermission() {
ActivityCompat.requestPermissions(this, storagePermission, STORAGE_REQUEST_CODE);
}
public boolean checkCameraPermission() {
boolean result = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA) == (PackageManager.PERMISSION_GRANTED);
boolean result1 = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
return result && result1;
}
public void requestCameraPermission() {
ActivityCompat.requestPermissions(this,cameraPermission, CAMERA_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case CAMERA_REQUEST_CODE:
if (grantResults.length > 0) {
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean writeStorageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (cameraAccepted && writeStorageAccepted) {
Toast.makeText(this, "Thank you", Toast.LENGTH_SHORT).show();
pickCamera();
}
else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
showMessageOkCancel("You need to allow storage permissions.",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(cameraPermission, CAMERA_REQUEST_CODE);
}
}
});
return;
}
}
}
}
break;
case STORAGE_REQUEST_CODE:
if (grantResults.length > 0) {
boolean writeStorageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (writeStorageAccepted) {
Toast.makeText(this, "Thank you", Toast.LENGTH_SHORT).show();
pickGallery();
}
else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showMessageOkCancel("You need to allow storage permissions.",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(storagePermission, STORAGE_REQUEST_CODE);
}
}
});
return;
}
}
}
}
break;
}
}
private void showMessageOkCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this).setMessage(message).setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null).create().show();
}
//handle result of picked image
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == IMAGE_PICK_GALLERY_CODE) {
//set image to image view
mImageView.setImageURI(data.getData());
}
if (requestCode == IMAGE_PICK_CAMERA_CODE) {
//set image to image view
mImageView.setImageURI(image_uri);
}
}
}
}
希望应用程序这次可以运行! 现在,每当您单击图库按钮时,应用程序都会请求存储权限,而当您单击摄像头按钮时,应用程序将同时请求摄像头和存储权限。