从Camera或Gallery导入图像[应用程序崩溃]

时间:2018-09-25 16:06:13

标签: android

我正在开发一个应用,其中我们使用意图从相机画廊中选择图像,并将其设置为 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)

1 个答案:

答案 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);
            }
        }

     }
    }

希望应用程序这次可以运行! 现在,每当您单击图库按钮时,应用程序都会请求存储权限,而当您单击摄像头按钮时,应用程序将同时请求摄像头和存储权限。