英文:
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[] permissions
和int[] 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论