[안드로이드]퍼미션 콜백 오류 onRequestPermissionsResult ….java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 왜?
파이어베이스에서 “2021-04-08 동안 발생 빈도가 높아진 안정성 문제” 라는 제목으로 메일이 도착했다. 앱 업데이트 후 오류가 대거 발생하는 경우 날라오는 메일이다. 오늘 앱 업데이트 후 문제가 생긴것이 틀림없다. 파이어베이스에 로그인 후 오류를 확인했다.
발생한 오류 내용
Fatal Exception: java.lang.RuntimeException:
Failure delivering result ResultInfo{
who=@android:requestPermissions:, request=1008, result=-1
, data=Intent
{ act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }
} to activity {com.sample.SettingActivity}:
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at android.app.ActivityThread.deliverResults(ActivityThread.java:5594)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5635)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2458)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8387)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
보통은 java.lang.ArrayIndexOutOfBoundsException: length=0; index=0;인 경우의 오류가 발생하기에 이러한 케이스에 대한 처리는 하였다. 그런데 뜬금없이 length=1; index=1이 터졌다. 무려 62개의 핸드폰에서 오류가 발생했고, 대부분 안드로이드 10, 또는 안드로이드 11 버전의 운영체제를 사용하는 휴대폰에서 발생했다.
안드로이드 P 보다 높은 운영체제가 설치된 휴대폰에서는 저장소(사진/미디어) 권한을 요청할 때 WRITE권한을 요청할 수 없도록 구글 정책이 변경되었다. 그렇기에 분기하여 처리하였다.
오류가 발생한 소스 코드 살펴보기
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
public static final int MY_PERMISSION_REQUEST_STORAGE = 1004;
public static final int MY_PERMISSION_REQUEST_STORAGE2 = 1008;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
if (ActivityCompat.checkSelfPermission(SettingActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //권한 허용상태인지 체크
ActivityCompat.requestPermissions(SettingActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSION_REQUEST_STORAGE2);
}
}else{
if (ActivityCompat.checkSelfPermission(SettingActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(SettingActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
) { //권한 허용상태인지 체크
ActivityCompat.requestPermissions(SettingActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSION_REQUEST_STORAGE);
}
}
퍼미션 콜백함수
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode != -1 ) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_STORAGE2:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
CallMusicListActivity();
} else {
this.callGuideDialogUsingTimer(getResources().getString(R.string.info_info_text), getResources().getString(R.string.info_auth_text), 7000);
//Snackbar.make(mLayout,getResources().getString(R.string.info_auth_text), Snackbar.LENGTH_LONG).show();
}
case MY_PERMISSION_REQUEST_STORAGE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
// 허용
CallMusicListActivity();
} else {
//비허용
//Toast.makeText(this, R.string.info_auth_text, Toast.LENGTH_LONG).show();
//this.callGuideDialogUsingTimer(getResources().getString(R.string.info_info_text), getResources().getString(R.string.info_auth_text), 7000);
checkPermissions();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
콜백함수 처리 부분의 코드에는 문제가 없다. 문제는 다른곳에 있다. 바로 requestCode가 문제이다.
public static final int MY_PERMISSION_REQUEST_STORAGE = 1004;
public static final int MY_PERMISSION_REQUEST_STORAGE2 = 1008;
아래와 같이 사용중인 또 다른 앱에서는 오류가 발생하지 않고 있다. 코드는 동일한데 말이다.
public static final int MY_PERMISSION_REQUEST_STORAGE = 1004;
public static final int MY_PERMISSION_REQUEST_STORAGE2 = 2048;
왜 이런 현상이 발생하는지 원인을 찾기 위해 디버깅을 해보았다. 그리고 원인을 찾았다.
case문에 break;문을 빼먹었다.