Android应用在请求权限时崩溃。

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

Android App crash when ask for permission

问题

我需要为我的应用程序获取2个权限=定位和录音。我检查,如果已经被授予,如果没有,我会请求权限。我请求权限的代码如下=

if (Build.VERSION.SDK_INT >= 23) {

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // 请求定位权限
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    } else {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, locationListener);
    }

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
        // 请求录音权限
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 2);
    }
}

我的onRequestPermissionsResult方法如下=

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

    switch(requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, locationListener);
                }
            }
            break;

        case 2:
            permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
            break;
    }
}

当我在手机上安装apk并切换到需要这两个权限的那个活动时,应用程序会在后台崩溃,但是位置权限的窗口仍然打开,当我授予它并重新打开应用程序,切换到那个活动时,我只需要给予定位权限,一切正常运行。为什么我的应用程序会崩溃?当我只有位置权限时,它可以正常工作,插入录音权限后,它就会关闭。在模拟器上运行时,它不会崩溃。

英文:

I need 2 permissions for my app= Location and Record Audio. I check, if it was granted, if no, I ask for permission. The code, where I ask for permisssion looks like this=

if (Build.VERSION.SDK_INT >= 23) {

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // ask for permission
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    } else {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, locationListener);
    }

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
        // ask for permission
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 2);
    }
}

My onRequestPermissionsResult method looks like this=

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

        switch(requestCode) {
            case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, locationListener);

                }
            }

            case 2:
                permissionToRecordAccepted  = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                break;

        }
    }

When i install the apk on my phone and change to that activity, where I need this 2 permissions, the app crashes in the background, but the permission windows for location is still open,when I grant it and reopen the app, change to that activity, I just have to give Location permission and everything works fine. Why does my app crash? When I only had location permission, it worked fine, after inserting audio record permission, it closes. When I run this on my emulator, it doesnt crash.

答案1

得分: 2

你应该使用一次包含所有所需权限的数组进行requestPermissions请求,并且有两个分开的调用 - 第二个调用将在您的应用程序已经在后台运行时调用(因为位置权限对话框已显示)。

最简单的修复方法是在适当的位置添加return,以检查是否为这种情况(没有异常的堆栈跟踪很难猜测)。

if (Build.VERSION.SDK_INT >= 23) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // 请求权限
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
        return; // 在这里返回
    } else {
        ///... 代码的其余部分
    }
}

更好的方法是总结所有所需的权限,并一次调用requestPermissions

if (Build.VERSION.SDK_INT >= 23) {
    boolean needLocPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED;
    boolean needAudioPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED;

    String[] permsArray = null;
    if (needAudioPerm && needLocPerm) {
        permsArray = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_FINE_LOCATION};
    } else if (needAudioPerm) {
        permsArray = new String[]{Manifest.permission.RECORD_AUDIO};
    } else if (needLocPerm) {
        permsArray = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
    }
    if (permsArray != null && permsArray.length > 0)
        ActivityCompat.requestPermissions(this, permsArray, 123);
    else
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, locationListener);
}

在进行此代码改进后,您应该重构onRequestPermissionsResult方法并检查哪些权限已被授予(检查String[] permissionsint[] grantResults数组)。

除非有异常的堆栈跟踪,否则只能猜测,除了上述问题外,一切看起来都很好,但是有可能您的异常是由另一个方法(例如onPause)中的某个调用引发的。

英文:

you should requestPermissions once with array of all needed permissions and you have two separated calls - second one will be called, when your app is already in background (because dialog with location permission appeared)

easiest fix would be adding return in proper place for checking is this the case (without stacktrace of exception its hard to guess)

if (Build.VERSION.SDK_INT >= 23) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // ask for permission
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
        return; // return in here
    } else {
    ///... rest of code

better approach would be summing up all needed permissions and calling requestPErmissions once

if (Build.VERSION.SDK_INT >= 23) {
    boolean needLocPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED;
    boolean needAudioPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED;

    String[] permsArray = null;
    if(needAudioPerm && needLocPerm ){
        permsArray = new String[]{Manifest.permission.RECORD_AUDIO,
                                 Manifest.permission.ACCESS_FINE_LOCATION};
    }
    else if(needAudioPerm){
        permsArray = new String[]{Manifest.permission.RECORD_AUDIO};
    }
    else if(needLocPerm ){
        permsArray = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
    }
    if(permsArray!=null && permsArray.length>0)
        ActivityCompat.requestPermissions(this, permsArray, 123);
    else locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, locationListener);
}

after this code improvement you should refactor your onRequestPermissionsResult method and check which permissions were granted (inspect String[] permissions and int[] grantResults arrays)

without a stacktrace of exception this is only guess, besides above problem everything looks fine, but there is a chance your exception is fired by some call made in another method, e.g. onPause

huangapple
  • 本文由 发表于 2020年9月9日 20:11:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63811435.html
匿名

发表评论

匿名网友

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

确定