权限在应用程序相机中不起作用,导致崩溃,由权限拒绝引起

Permissions not working in app Camera, causes crash ,caused bypermission denial

在我的应用程序中,我正在为文档扫描仪导入一个库, 现在我的问题是当我尝试在库中启动扫描仪时,出现此错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.smartpractice.smartpracticesmartapp/com.scanlibrary.ScanActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.huawei.camera/.ThirdCamera clip={text/uri-list U:content://com.scanlibrary.provider/external_files/scanSample/IMG_20200922_115551.jpg} (has extras) } from ProcessRecord{fc4f03f 19801:com.smartpractice.smartpracticesmartapp/u0a384} (pid=19801, uid=10384) with revoked permission android.permission.CAMERA

现在问题是在应用程序的清单和库清单中声明了权限,例如

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我已经尝试将 android:exported="true" 添加到清单中的 activity 中,按照此处关于 SO 的另一个问题的建议,我还绑定了通常的 Clean Project、Rebuild 等

这里是完整的 logcat 如果你需要它

Process: com.smartpractice.smartpracticesmartapp, PID: 19801
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.smartpractice.smartpracticesmartapp/com.scanlibrary.ScanActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.huawei.camera/.ThirdCamera clip={text/uri-list U:content://com.scanlibrary.provider/external_files/scanSample/IMG_20200922_115551.jpg} (has extras) } from ProcessRecord{fc4f03f 19801:com.smartpractice.smartpracticesmartapp/u0a384} (pid=19801, uid=10384) with revoked permission android.permission.CAMERA
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3430)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
        at android.os.Handler.dispatchMessage(Handler.java:112)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7625)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
     Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.huawei.camera/.ThirdCamera clip={text/uri-list U:content://com.scanlibrary.provider/external_files/scanSample/IMG_20200922_115551.jpg} (has extras) } from ProcessRecord{fc4f03f 19801:com.smartpractice.smartpracticesmartapp/u0a384} (pid=19801, uid=10384) with revoked permission android.permission.CAMERA
        at android.os.Parcel.createException(Parcel.java:1953)
        at android.os.Parcel.readException(Parcel.java:1921)
        at android.os.Parcel.readException(Parcel.java:1871)
        at android.app.IActivityManager$Stub$Proxy.startActivity(IActivityManager.java:3733)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1900)
        at android.app.Activity.startActivityForResult(Activity.java:5573)
        at android.app.Activity.startActivityFromFragment(Activity.java:5538)
        at android.app.Activity$HostCallbacks.onStartActivityFromFragment(Activity.java:8277)
        at android.app.Fragment.startActivityForResult(Fragment.java:1115)
        at android.app.Fragment.startActivityForResult(Fragment.java:1104)
        at com.scanlibrary.PickImageFragment.openCamera(PickImageFragment.java:129)
        at com.scanlibrary.PickImageFragment.handleIntentPreference(PickImageFragment.java:77)
        at com.scanlibrary.PickImageFragment.init(PickImageFragment.java:58)
        at com.scanlibrary.PickImageFragment.onCreateView(PickImageFragment.java:48)
        at android.app.Fragment.performCreateView(Fragment.java:2537)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1301)
        at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2433)
        at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2212)
        at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2168)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2069)
        at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3059)
        at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3006)
        at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:182)
        at android.app.Activity.performCreate(Activity.java:7465)
        at android.app.Activity.performCreate(Activity.java:7448)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 
        at android.os.Handler.dispatchMessage(Handler.java:112) 
        at android.os.Looper.loop(Looper.java:216) 
        at android.app.ActivityThread.main(ActivityThread.java:7625) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 
    Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.am.ActivityStackSupervisor.checkStartAnyActivityPermission(ActivityStackSupervisor.java:2028)
        at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:923)
        at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:656)
        at com.android.server.am.HwActivityStarter.startActivity(HwActivityStarter.java:222)
        at com.android.server.am.ActivityStarter.startActivityMayWait(ActivityStarter.java:1483)

这是 logcat

中显示的 PickImageFragment 的代码
package com.scanlibrary;

import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import androidx.core.content.FileProvider;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by jhansi on 04/04/15.
 */
public class PickImageFragment extends Fragment {

    private View view;
    private ImageButton cameraButton;
    private ImageButton galleryButton;
    private Uri fileUri;
    private IScanner scanner;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (!(activity instanceof IScanner)) {
            throw new ClassCastException("Activity must implement IScanner");
        }
        this.scanner = (IScanner) activity;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.pick_image_fragment, null);
        init();
        return view;
    }

    private void init() {
        cameraButton = (ImageButton) view.findViewById(R.id.cameraButton);
        cameraButton.setOnClickListener(new CameraButtonClickListener());
        galleryButton = (ImageButton) view.findViewById(R.id.selectButton);
        galleryButton.setOnClickListener(new GalleryClickListener());
        if (isIntentPreferenceSet()) {
            handleIntentPreference();
        } else {
            getActivity().finish();
        }
    }

    private void clearTempImages() {
        try {
            File tempFolder = new File(ScanConstants.IMAGE_PATH);
            for (File f : tempFolder.listFiles())
                f.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void handleIntentPreference() {
        int preference = getIntentPreference();
        if (preference == ScanConstants.OPEN_CAMERA) {
            openCamera();
        } else if (preference == ScanConstants.OPEN_MEDIA) {
            openMediaContent();
        }
    }

    private boolean isIntentPreferenceSet() {
        int preference = getArguments().getInt(ScanConstants.OPEN_INTENT_PREFERENCE, 0);
        return preference != 0;
    }

    private int getIntentPreference() {
        int preference = getArguments().getInt(ScanConstants.OPEN_INTENT_PREFERENCE, 0);
        return preference;
    }


    private class CameraButtonClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            openCamera();
        }
    }

    private class GalleryClickListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            openMediaContent();
        }
    }

    public void openMediaContent() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        startActivityForResult(intent, ScanConstants.PICKFILE_REQUEST_CODE);
    }

    public void openCamera() {
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        File file = createImageFile();
        boolean isDirectoryCreated = file.getParentFile().mkdirs();
        Log.d("", "openCamera: isDirectoryCreated: " + isDirectoryCreated);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri tempFileUri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
                    "com.scanlibrary.provider", // As defined in Manifest
                    file);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
        } else {
            Uri tempFileUri = Uri.fromFile(file);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
        }
        startActivityForResult(cameraIntent, ScanConstants.START_CAMERA_REQUEST_CODE);
    }

    private File createImageFile() {
        clearTempImages();
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new
                Date());
        File file = new File(ScanConstants.IMAGE_PATH, "IMG_" + timeStamp +
                ".jpg");
        fileUri = Uri.fromFile(file);
        return file;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d("", "onActivityResult" + resultCode);
        Bitmap bitmap = null;
        if (resultCode == Activity.RESULT_OK) {
            try {
                switch (requestCode) {
                    case ScanConstants.START_CAMERA_REQUEST_CODE:
                        bitmap = getBitmap(fileUri);
                        break;

                    case ScanConstants.PICKFILE_REQUEST_CODE:
                        bitmap = getBitmap(data.getData());
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            getActivity().finish();
        }
        if (bitmap != null) {
            postImagePick(bitmap);
        }
    }

    protected void postImagePick(Bitmap bitmap) {
        Uri uri = Utils.getUri(getActivity(), bitmap);
        bitmap.recycle();
        scanner.onBitmapSelect(uri);
    }

    private Bitmap getBitmap(Uri selectedimg) throws IOException {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 3;
        AssetFileDescriptor fileDescriptor = null;
        fileDescriptor =
                getActivity().getContentResolver().openAssetFileDescriptor(selectedimg, "r");
        Bitmap original
                = BitmapFactory.decodeFileDescriptor(
                fileDescriptor.getFileDescriptor(), null, options);
        return original;
    }
}

先检查是否有权限

if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_DENIED){
// Permission not granted
            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, 0);
        }else {
           //Permission granted
        }

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_DENIED){
    // Permission not granted
                ActivityCompat.requestPermissions(Draw.this, new String[]{android.Manifest
                    .permission
                    .WRITE_EXTERNAL_STORAGE}, 1);
            }else {
               //Permission granted
            }

然后覆盖这个方法:

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 0){
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //permission granted
            }else {
               //Cancelled
            }
        }else if (requestCode == 1){
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //permission granted
            }else {
               //Cancelled
            }
        }
    }