안녕하세요?


연속된 포스팅에서 만족스럽지 않은 결과가 나왔지만, 이제는 그런데로 만족스러운 결과가 나와서 오늘 포스팅에 그 내용을 올리고자 합니다.


우선 들어가기 전에 저는 다음과 같은 기능을 구현하는 데 성공하였습니다.

[버튼을 누르면 권한을 획득하기 위한 대화상자가 나오고, 허용을 하면 원하는 메세지가 출력되도록 한다.]

아직까지는 버튼을 누르자 마자 권한을 획득하고, 권한을 획득하자 마자 바로 전화걸기 기능을 실행시키기는 무리지만, 그래도 여기까지 오는 것만 해도 머리에 쥐가 날 지경입니다. 



우선 기본적인 코딩은 위 스크린샷과 같습니다. ActivityCompat.requestPermissions() 라는 메서드 바로 다음줄에 Intent를 실행시키기 위한 StartActivity()를 놓으면, 다음과 같은 에러가 떠서 도저히 안되었습니다.


제 의도는 분명히 전화걸기라는 버튼을 누르면 바로 권한을 요청하고, 권한을 요청하자 마자 바로 전화를 걸도록 할 예정이었습니다. 하지만 권한을 획득하자 마자 바로 걸리라는 전화는 안 걸리고 앱이 무슨 오류라도 일으켰는지 바로 종료가 되어 버렸습니다.


물론, 이미 한번 권한을 획득하였다면, 그 때부터는 [전화걸기]버튼을 누르면 정상적으로 전화를 걸 수 있었습니다. 


하지만, 이런 에러가 계속 뜨는 상황에서는 무언가 않좋아 보이는 상황입니다. 그래서 처음에는 방향을 어떻게 해야 버튼을 누르자 마자 권한을 획득하고, 권한을 획득하자 마자 최초로 전화걸기 기능을 실행시킬 수 있는지를 두고서 다른 사람이 했는 코드를 계속 찾아보기 시작했습니다.


그런데 이렇게 코드를 찾던 와중에 한가지 이상한 것을 발견할 수 있었습니다. 일단 저는 안드로이드 스튜디오의 자바 코드에 대해서 잘은 모르지만, 대다수의 사람들이 경고창을 띄우도록 하고, 여기서 Positive 메세지를 띄고 있는 버튼을 눌렀을 경우에 권한을 요청하도록 되어 있었습니다.


하지만 저는 제가 하고 있는 앱에서는 따로 권한을 획득하기 위한 경고창을 코딩하지 않았는 데도 뜨는 것을 아래의 스크린샷과 같이 볼 수 있었습니다.



그래서 다른 사람이 이미 자기가 안드로이드6.0이상의 버젼에서 권한을 획득하기 위해 짜 놓았다는 코드를 읽어 보고서는 버튼을 누르자마자 실행시키지 않고, 대다수의 사람들이 대화상자를 띄우는 것을 하고 있다는 것을 알 수 있었습니다. 그래서 저는 [전화걸기]버튼을 누르자 마자 전화거는 기능으로 구현하지 않고, 허용을 누르면 [다시 버튼을 눌러야 합니다]라는 메세지가 뜨는 쪽으로 방향을 바꾸었습니다.



우선 권한을 요청하는 코드 바로 아래에다가 Toast.makeText()라는 메서드를 추가해서, 버튼을 눌러서, 권한을 사용자가 허용을 하면 [전화걸기 권한 획득, 버튼을 다시 누르시오]라는 메세지가 뜨도록 바꾸었습니다. 저는 이 상태에서 실험을 해보기 위해서 USB 케이블로 스마트폰을 연결한 다음, 앱을 실행시켜 보았습니다.



하지만 제 의도와는 다르게, 전화를 걸기위한 권한을 사용자가 허락하는 여부와 관계없이 메세지가 뜨는 문제점이 발생하였습니다. 그래서 여기서는 이렇게 권한을 요청해서는 안되고 다른 방법을 써야 겠다는 생각을 하게 되었습니다.


우선 onRequestPermissionsResult()라는 메서드가 있었는데, 이 메서드가 바로 권한을 획득한 다음, 획득된 권한을 다시 불러오는 메서드라는 것을 알 수 있었습니다. 


하지만, 이렇다는 것을 아는 것과 실제로 사용하는 것에는 많은 시행착오가 있어서, 일단은 다음과 같이 사용을 하게 되었습니다.


위 스크린샷에서 보이는 것과 같이 먼저 다음과 같이 코딩을 시작합니다.


public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {


여기서 이 메서드안에 있는 변수들이 무엇을 써야 하는지 처음에는 몰라서 수 많은 시행착오와 머리에서 쥐가 나는 과정을 겪었습니다만, 나중에 알고보니 어떤 변형도 없이 그냥 있는 그대로 public으로 시작해서 사용하는 것이었습니다.


super.onRequestPermissionResult(requestCode, permissions, grantResults);


여기서 먼저 super라는 것은 자기에게 있는 클래스 안에서 메서드나 필드를 찾지 말고, 부모 클래스에서 메서드나 필드를 찾으라는 명령어입니다. 즉, 이미 public void onRequestPermissionsResult 라고 해서 새로운 클래스가 시작되었으니, 여기서 권한 요청에 대한 값을 찾지 말고, 이미 이전 위에서 했던 클래스에서 권한요청값을 찾아 가지고 오라는 의미로 저는 이해를 하였습니다.


if(requestCode == 1000){

  Toast.makeText(getApplicationContext(),"전화걸기 권한 획득, 전화 걸기 버튼을 다시 누르시오",Toast.LENGTH_LONG).show();}

else { return;}


여기 코딩의 이믠느 권한을 획득했으면, 지정한 메세지를 띄우라는 의미가 됩니다. 그래서 위와 같은 식으로 코딩을 완성한 다음, 다시 USB에 연결된 스마트폰을 이용해서 시험을 해 보았습니다. 하지만 이번에도 허락 여부와는 관계없이 전화걸기 권한을 획득해서 다시 버튼을 누르라는 메세지가 뜨는 것을 확인하였습니다.


이 에러가 어디에서 생겼나 했더니, 다른 사람들이 일반적으로 코딩을 할때 다음과 같은 식으로 되어 있는 것을 볼 수 있었습니다.


if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {


즉, 코딩을 하면서 이미 권한을 요청하는 메서드에서 requestCode는 1000이라는 숫자를 주기는 주었습니다. 하지만 이것만 가지고는 그 결과를 가져오라는 의미가 되지 못합니다. 그래서 grantResults 라고 해서 권한 획득의 결과값을 가지고 와서, 이 값에 따라 반응을 하는 if문을 만드는 것이 상당히 중요했습니다.



위 스크린샷에 붉은색 박스로 표시가 된 곳처럼 코딩을 한 다음에, USB에 연결이 된 스마트폰을 통해서 실험을 해 본 결과, 제대로 작동을 하는 것을 확인할 수 있었습니다. 실제로 제가 허용을 하고 난 뒤에야 지정한 메세지가 제대로 뜨는 것을 볼 수 있었습니다.

+ Recent posts