Android

[안드로이드]퍼미션 콜백 오류 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;문을 빼먹었다.

Leave a Reply

error: Content is protected !!