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

huangapple go评论73阅读模式
英文:

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",如在 Stack Overflow 的另一个问题中建议的,我还尝试了清理项目、重新构建等。

以下是完整的 Logcat 日志,如果需要的话:

(此处省略了完整的 Logcat 日志)

以下是在 Logcat 中显示的 PickImageFragment 的代码:

package com.scanlibrary;

// ... 省略了导入语句和部分代码 ...

public class PickImageFragment extends Fragment {

    // ... 省略了类中的方法和成员变量 ...

    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() {
        // 打开媒体内容的代码
    }

    public void openCamera() {
        // 打开相机的代码
    }

    private File createImageFile() {
        // 创建图像文件的代码
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 在活动结果返回时的处理代码
    }

    protected void postImagePick(Bitmap bitmap) {
        // 处理图像选择后的代码
    }

    private Bitmap getBitmap(Uri selectedimg) throws IOException {
        // 获取位图的代码
    }
}

请注意,上述内容是对您提供的代码片段的翻译。如果您有任何进一步的问题或需要进一步的帮助,请随时提问。

英文:

In My app I am importing a library for a document scanner,
Now my problem is when I try to launch the scanner in the library, I get this error

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

Now the thing is the premissions are declared in the manifests for the app and in the libraries manifest like

&lt;uses-permission android:name=&quot;android.permission.CAMERA&quot;/&gt;
&lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;

I have tried adding android:exported=&quot;true&quot; to the activity in the manifest as suggested on another question here on SO, I also tied the usual Clean Project, Rebuild etc.

here is the full logcat if you need it

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)&#160;
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)&#160;
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)&#160;
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)&#160;
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)&#160;
        at android.os.Handler.dispatchMessage(Handler.java:112)&#160;
        at android.os.Looper.loop(Looper.java:216)&#160;
        at android.app.ActivityThread.main(ActivityThread.java:7625)&#160;
        at java.lang.reflect.Method.invoke(Native Method)&#160;
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)&#160;
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)&#160;
    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)

Here is the code for PickImageFragment shown in the logcat

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(&quot;Activity must implement IScanner&quot;);
        }
        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(&quot;image/*&quot;);
        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(&quot;&quot;, &quot;openCamera: isDirectoryCreated: &quot; + isDirectoryCreated);
        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.N) {
            Uri tempFileUri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
                    &quot;com.scanlibrary.provider&quot;, // 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(&quot;yyyyMMdd_HHmmss&quot;).format(new
                Date());
        File file = new File(ScanConstants.IMAGE_PATH, &quot;IMG_&quot; + timeStamp +
                &quot;.jpg&quot;);
        fileUri = Uri.fromFile(file);
        return file;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(&quot;&quot;, &quot;onActivityResult&quot; + 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, &quot;r&quot;);
        Bitmap original
                = BitmapFactory.decodeFileDescriptor(
                fileDescriptor.getFileDescriptor(), null, options);
        return original;
    }
}

答案1

得分: 1

检查是否已授予权限。

if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
        == PackageManager.PERMISSION_DENIED){
    // 未授予权限
    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, 0);
} else {
   // 已授予权限
}

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        == PackageManager.PERMISSION_DENIED){
    // 未授予权限
    ActivityCompat.requestPermissions(Draw.this, new String[]{android.Manifest.permission
        .WRITE_EXTERNAL_STORAGE}, 1);
} else {
   // 已授予权限
}

然后重写此方法:

@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){
            // 权限已授予
        } else {
           // 已取消
        }
    } else if (requestCode == 1){
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
            // 权限已授予
        } else {
           // 已取消
        }
    }
}
英文:

Check if permission is granted or not first.

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
            }

Then override this method :

@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
            }
        }
    }

huangapple
  • 本文由 发表于 2020年9月22日 18:12:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/64007582.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定