代码之家  ›  专栏  ›  技术社区  ›  SHIDHIN TS

致命异常:栈溢出:相机权限请求时堆栈大小为8MB

  •  0
  • SHIDHIN TS  · 技术社区  · 6 年前

    我在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 回复  |  直到 6 年前
        1
  •  3
  •   TibiG    6 年前

    因为你在许可证上循环。 你的方法应该是这样的。

    @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,但是您可以创建一个常规的DialogFragment。希望有帮助。

        2
  •  1
  •   Ali shatergholi    6 年前

    您应该检查您的权限是否未被授予禁用该功能,或者在用户请求该功能时询问它。

    @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();
        }
    }}