致命异常:java.lang.StackOverflowError:相机权限请求上的堆栈大小为8MB

时间:2018-08-29 12:13:49

标签: android permissions android-permissions

我在Fabric上收到以下错误日志,

   Fatal Exception: java.lang.StackOverflowError: stack size 8MB
   at android.app.ActivityManagerProxy.checkPermission(ActivityManagerNative.java:5157)
   at android.app.ContextImpl.checkPermission(ContextImpl.java:1610)
   at android.content.ContextWrapper.checkPermission(ContextWrapper.java:665)
   at android.content.ContextWrapper.checkPermission(ContextWrapper.java:665)
   at android.support.v4.content.ContextCompat.checkSelfPermission(ContextCompat.java:430)
   at ts.shidhin.net.LaunchActivity.checkCameraPermissionGranded(LaunchActivity.java:275)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:296)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:299)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestCameraPermission(LaunchActivity.java:289)
   at ts.shidhin.net.LaunchActivity.onRequestPermissionsResult(LaunchActivity.java:304)
   at android.app.Activity.requestPermissions(Activity.java:4178)
   at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:394)
   at ts.shidhin.net.LaunchActivity.requestLocationPermission(LaunchActivity.java:284)
   at ts.shidhin.net.LaunchActivity.onResume(LaunchActivity.java:247)
   at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1287)
   at android.app.Activity.performResume(Activity.java:7015)
   at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4210)
   at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4323)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1865)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:7325)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

这是我的代码

按钮单击

@Override
public void onClick(View view) {
    switch (view.getId()) {
          case R.id.btnTakePhoto:
            if (!checkCameraPermissionGranded())
                requestCameraPermission();
            else 
                 takePicture();
            break;
    }
}

功能 checkCameraPermissionGranded()

private boolean checkCameraPermissionGranded() {
    if (ActivityCompat.checkSelfPermission(LaunchActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(LaunchActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(LaunchActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else
        return false;
}

功能 requestCameraPermission()

    private void requestCameraPermission() {
        ActivityCompat.requestPermissions(LaunchActivity.this, new String[]{android.Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, Constants.CAPTURE_REQUEST_CODE);
    }

功能 onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == Constants.CAPTURE_REQUEST_CODE) {
        if (checkCameraPermissionGranded())
            takePicture();
        else {
            requestCameraPermission();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

这是因为您正在遍历PermissionsPopup。 您的方法应如下所示。

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case Constants.CAPTURE_REQUEST_CODE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                takePicture();
            } else {
                //camera permission denied
                show an explaining message to tell the user why you need that permission
            }
            return;
        }

    }
}

您也可以执行此操作(更完整的方法)

private boolean checkCameraPicturePermissions() {
    canAccessCamera = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    canReadExternal = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    canWriteExternal = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

    List<String> permissionsNeeded = new ArrayList<>();
    if(!canAccessCamera) {
        permissionsNeeded.add(Manifest.permission.CAMERA);
    }
    if(!canReadExternal) {
        permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
    }
    if(!canWriteExternal) {
        permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    if (!permissionsNeeded.isEmpty()) {
        requestPermissions(permissionsNeeded.toArray(new String[permissionsNeeded.size()]), PERMISSION_REQUEST_CAMERA_PICTURE);
        return false;
    }

    return true;
}

btnCameraAction.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            if(checkCameraPicturePermissions()) {
                    onTakePhoto();
            }

        }
    });

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

        case PERMISSION_REQUEST_CAMERA_PICTURE: {
            Map<String, Boolean> permissionsMap = new HashMap<>();
            permissionsMap.put(Manifest.permission.CAMERA, true);
            permissionsMap.put(Manifest.permission.READ_EXTERNAL_STORAGE, true);
            permissionsMap.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, true);

            if (grantResults.length > 0) {
                for (int i = 0; i < grantResults.length; i++) {
                    permissionsMap.put(permissions[i], grantResults[i] == PackageManager.PERMISSION_GRANTED);
                }

                canAccessCamera = permissionsMap.get(Manifest.permission.CAMERA);

                if (permissionsMap.get(Manifest.permission.CAMERA)
                        && permissionsMap.get(Manifest.permission.READ_EXTERNAL_STORAGE)
                        && permissionsMap.get(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                } else {
                    if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)
                            || shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)
                            || shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        rationale(getString(R.string.warning_rationale_permissions));
                    } else {
                        explain(getString(R.string.mandatory_permissions));
                    }
                }
            }

            break;
        }

        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

private void rationale(String value) {
    try {
        InformationPopup informationPopup = InformationPopup.newInstance(getString(R.string.warning_title), value, getString(R.string.action_ok), null);
        informationPopup.mListener = new InformationPopup.InformationActionHandler() {
            @Override
            public void onButtonLeft(InformationPopup dialog) {
                dialog.dismiss();
            }
        };
    } catch (Exception e) {}
}

private void explain(String value) {
    try {
        ConfirmationPopup confirmationPopup = ConfirmationPopup.newInstance(
                getString(R.string.warning_title),
                value,
                getString(R.string.action_no),
                getString(R.string.action_yes), null);
        confirmationPopup.setCancelable(true);
        confirmationPopup.mListener = new ConfirmationPopup.ConfirmationActionHandler() {
            @Override
            public void onButtonLeft(ConfirmationPopup dialog) {
                dialog.dismiss();
            }

            @Override
            public void onButtonRight(ConfirmationPopup dialog) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                Uri uri = Uri.fromParts("package", getContext().getPackageName(), null);
                intent.setData(uri);
                getContext().startActivity(intent);
            }

            @Override
            public void onButtonRight(ConfirmationPopup dialog, Object object) {

            }

            @Override
            public void onButtonRight(ConfirmationPopup dialog, int index) {

            }
        };
        confirmationPopup.show(getFragmentManager(), "RationalePermissionPopup");
    } catch (Exception e) {}
}

ConfirmationPopup和InformationPopup继承了DialogFragment,但是您可以创建一个常规的。希望对您有所帮助。

答案 1 :(得分:1)

由于用户不允许在onRequestPermissionsResult上获得该权限,因此您再次检查并请求权限 您应该检查是否未授予您的许可以禁用该功能,或者在用户请求该功能时询问它。

Android给用户选项,不再询问。

您应该这样更改

@Override
public void onRequestPermissionsResult(int requestCode, String[]permissions, int[] grantResults) {
if (requestCode == Constants.CAPTURE_REQUEST_CODE) {
    if (checkCameraPermissionGranded())
        takePicture();
    else {
        Toast.makeText(this, "you can`t use that feature", Toast.LENGTH_SHORT).show();
    }
}}