请求运行时权限时java.lang.StackOverflowError

时间:2018-06-07 10:27:52

标签: java android runtime-permissions

我创建了一个公共类PermissionManager,用于管理来自单个地方的所有权限,但通常它工作正常但在上传后显示有关崩溃分析的错误报告我无法重现,详细信息以下是提及

Fatal Exception: java.lang.StackOverflowError: stack size 8MB
       at android.content.res.Resources.getText(Resources.java:308)
       at android.content.res.Resources.getString(Resources.java:400)
       at android.content.Context.getString(Context.java:409)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onRequestPermissionsResult(SplashActivity.java:98)
       at android.app.Activity.requestPermissions(Activity.java:3857)
       at android.support.v4.app.ActivityCompat.requestPermissions(ActivityCompat.java:507)
       at com.mypackage.permission.PermissionManager.requestPermission(PermissionManager.java:105)
       at com.mypackage.permission.PermissionManager.checkPermission(PermissionManager.java:69)
       at com.mypackage.permission.PermissionManager.checkLocationPermission(PermissionManager.java:46)
       at com.mypackage.activities.SplashActivity.onCreate(SplashActivity.java:53)
       at android.app.Activity.performCreate(Activity.java:6285)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
       at android.app.ActivityThread.access$900(ActivityThread.java:150)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:171)
       at android.app.ActivityThread.main(ActivityThread.java:5417)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

SplashActivity.java

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (PermissionManager.checkLocationPermission(this)) {

              // do the task
            }
    }

     @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case PermissionManager.MY_PERMISSIONS_REQUEST_LOCATION_ACCESS: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // do the task
                } else {
//                    Toast.makeText(getApplicationContext(), "For find better result,enable GPS permission from setting", Toast.LENGTH_LONG).show();
                    if (!PermissionManager.MY_REQUESTED_DIALOG) {
                        PermissionManager.checkLocationPermission(this);
                    } else {
                        startNextActivity(0);
                    }
                }


            }
        }
    }

PermissionManager.java

public class PermissionManager {

    public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 101;
    public static final int MY_PERMISSIONS_REQUEST_LOCATION_ACCESS = 102;
    public static final int MY_PERMISSIONS_REQUEST_CAMERA = 103;
    public static final int MY_PERMISSIONS_REQUEST_CALL = 104;
    public static final int MY_PERMISSIONS_REQUEST_AUDIO = 105;

    public static boolean MY_REQUESTED_DIALOG = false;


    private static String[] storagePermission = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private static String[] cameraPermission = new String[]{Manifest.permission.CAMERA};
    private static String[] locationPermission = new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
    private static String[] phoneCallPermission = new String[]{Manifest.permission.CALL_PHONE};
    private static String[] recordAudioCallPermission = new String[]{Manifest.permission.RECORD_AUDIO};


    public static boolean checkPhoneCallPermission(final Activity context) {
        return checkPermission(context, phoneCallPermission, "Permission necessary", "Allow call permission", MY_PERMISSIONS_REQUEST_CALL);
    }


    public static boolean checkStoragePermission(final Activity context) {
        return checkPermission(context, storagePermission, "", context.getString(R.string.storage_permission_rejected), MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
    }

    public static boolean checkLocationPermission(final Activity context) {
        return checkPermission(context, locationPermission, "", context.getString(R.string.location_permission_rejected), MY_PERMISSIONS_REQUEST_LOCATION_ACCESS);
    }

    public static boolean checkRecordAudioPermission(final Activity context) {
        return checkPermission(context, recordAudioCallPermission, "", context.getString(R.string.audio_permission_rejected), MY_PERMISSIONS_REQUEST_AUDIO);
    }


    /*
     *
     * Check the permission
     *
     * */

    private static boolean checkPermission(final Activity context, String[] permission, String messageTitle, String messageDetails, int requestCode) {

        MY_REQUESTED_DIALOG = false;
        if (checkAPIVersion()) {
            if (checkPermissionStatus(context, permission)) {
                if (shouldShowRequestPermission(context, permission)) {
                    MY_REQUESTED_DIALOG = true;
                    showDialogForPermission(context, messageTitle, messageDetails, permission, requestCode);
                } else {
                    requestPermission(context, permission, requestCode);
                }
                return false;
            } else {
                return true;
            }
        }
        return true;

    }

    /*
     *
     * Show dialog for why ,this permission is needed
     *
     * */
    private static void showDialogForPermission(final Activity context, String title, String message, final String[] requestedPermission, final int requestCode) {
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
        alertBuilder.setCancelable(false);
        alertBuilder.setTitle(title);
        alertBuilder.setMessage(message);
        alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                requestPermission(context, requestedPermission, requestCode);
            }
        });
        AlertDialog alert = alertBuilder.create();
        alert.show();
    }

    /*
     *
     * Request for permission
     *
     * */
    private static void requestPermission(Activity context, String[] requestedPermission, int requestCode) {
        ActivityCompat.requestPermissions(context, requestedPermission, requestCode);
    }

    /*
     *
     * Check need to display dialog for permission access
     * executed when first time user decline the permission
     *
     * */
    private static boolean shouldShowRequestPermission(Activity context, String[] permissionCheck) {
        for (String permission : permissionCheck) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(context, permission))
                return true;
        }

        return false;
    }

    /*
     *
     * Check list of permission is granted or not
     * if not requested for permission
     *
     * */
    private static boolean checkPermissionStatus(Activity context, String[] permissionCheck) {
        for (String permission : permissionCheck) {
            if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
                return true;
        }
        return false;
    }

    /*
     *
     * Check API version
     * if it's >=M need to check run time permission
     * */
    private static boolean checkAPIVersion() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
    }

}

任何人都可以帮忙解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

你有一个无限循环,我猜是由某人拒绝位置权限,并选择“永不问agan”复选框:

enter image description here

这将自动拒绝对“位置”权限的任何进一步请求。在您的情况下,这会成为一个大问题,因为double findtime(int Px, int Py, int Pz, int Ex, int Ey, int Ez, int Vx, int Vy, int Vz, int Cx, int Cy, int Cz, int R) { double a = (Ex*Ex+ Ey* Ey + Ez * Ez); double b = (2 * Ex*Vx + 2 * Ey*Vy + 2 * Ez*Vz); double g = Vx * Vx + Vy * Vy + Vz * Vz; double e= Ex * Px - Ex * Cx + Ey * Py - Ey * Cy + Ez * Pz - Ez * Cz; double o= Vx * Px - Vx * Cx + Vy * Py - Vy * Cy + Vz * Pz - Vz * Cz; double d= (Px - Cx)*(Px - Cx) + (Py - Cy)*(Py - Cy) + (Pz - Cz)*(Pz - Cz) - R * R; double A = o* o- g* d; double B = 2 * e*o- b* d; double C = e* e- d* a; if (A != 0) { double D = B * B - 4 *A*C; double rootD = sqrt(D); double t1 = (-1*B + rootD) / (2 * A); double t2 = (-1*B - rootD) / (2 * A); if (t1 <= 0 && t2 > 0) { return t2; } else if (t2 <= 0 && t1 > 0) { return t1; } else { return min(t1, t2); } } else { double ans = -C / B; return ans; } } 会使用PermissionManager::checkPermission()提示您使用权限对话框,该对话框会自动被拒绝,而后者会调用showDialogForPermission()

onRequestPermissionsResult()

由于if (shouldShowRequestPermission(context, permission)) { MY_REQUESTED_DIALOG = true; showDialogForPermission(context, messageTitle, messageDetails, permission, requestCode); } else { /* THIS LINE IS STARTING THE INFINITE LOOP */ requestPermission(context, permission, requestCode); } 正在返回shouldShowRequestPermission(context, permission)false永远不会设置为MY_REQUESTED_DIALOG,并且流程会一遍又一遍地循环。如果trueshouldShowRequestPermission() == false 您的权限被拒绝,我的建议是退出权限流程。

onRequestPermissionsResult()

答案 1 :(得分:0)

堆栈跟踪是无限循环的症状。