Google Play 서비스 및 런타임 권한

Android 6.0 Marshmallow 이후로 Android는 권한 모델을 간소화하여 자동으로 업데이트 프로세스를 실행할 수 있습니다 권한은 이전이 아닌 런타임에 요청됩니다. 앱 설치 또한 사용자는 특정 권한을 거부하도록 선택할 수 있습니다. 사용자에게 이러한 유연성을 제공하려면 앱이 특정 권한을 사용 또는 사용 중지할 때 예상되는 동작입니다.

Google Play 서비스에는 사용자가 직접 선택할 수 있는 런타임 권한이 있습니다. Google에서 구체적으로 요청한 권한과 별도로 애플리케이션입니다. Google Play 서비스는 필요한 모든 권한을 자동으로 획득합니다. API를 지원할 수 있습니다 그러나 앱은 여전히 런타임을 확인하고 요청해야 합니다. 필요에 따라 권한을 부여하고 사용자가 문제를 해결할 수 없는 경우 앱에서 사용하는 API에 필요한 권한을 Google Play 서비스가 거부했습니다.

특정 권한을 설정할 때 사용자의 기대치를 관리하는 것이 필요에 따라 다릅니다 다음 권장사항을 따르면 문제를 해결하는 데 도움이 됩니다

기본 요건

AndroidManifest.xml 파일에서 권한을 선언해야 합니다. 예를 들면 다음과 같습니다.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

가이드라인

API 호출 전에 권한 확인

API에서 사용할 API를 선언한 후에는 AndroidManifest.xml 파일에 필요한 권한이 있는지 확인하세요. API를 호출하기 전에 확인할 수 있습니다. 이 작업은 checkSelfPermission 메서드를 사용하여 실행할 수 있습니다. ActivityCompat 또는 ContextCompat의 값을 갖습니다.

호출이 false를 반환하면 권한이 부여되지 않았으며 requestPermissions를 사용하여 요청해야 합니다. 이에 대한 응답은 다음 단계에서 확인할 수 있습니다.

예를 들면 다음과 같습니다.

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
  // Check Permissions Now
  ActivityCompat.requestPermissions(this,
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
      REQUEST_LOCATION);
} else {
  // permission has been granted, continue as usual
  Task<Location> locationResult = LocationServices
      .getFusedLocationProviderClient(this /** Context */)
      .getLastLocation();
}

요청 권한 콜백 구현

앱에 필요한 권한을 사용자가 부여하지 않은 경우 requestPermissions 메서드를 호출하여 사용자에게 권한을 부여할 수 있습니다. 사용자의 응답은 onRequestPermissionsResult 콜백에 전달됩니다. 앱은 다음과 같아야 합니다. 요청이 호출될 수 있으므로 항상 반환 값을 취소 또는 거부될 수 있습니다. 다음 페이지에서 여러 권한을 요청하고 확인할 수도 있습니다. 한 번입니다. 다음 샘플은 단일 권한만 확인합니다.

public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions,
                                       int[] grantResults) {
    if (requestCode == REQUEST_LOCATION) {
        if(grantResults.length == 1
           && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // We can now safely use the API we requested access to
            Task<Location> locationResult = LocationServices
                .getFusedLocationProviderClient(this /** Context */)
                .getLastLocation();
        } else {
            // Permission was denied or request was cancelled
        }
    }
}

권한 근거 표시

앱이 요청하는 권한이 앱의 핵심 기능에 필요한 경우 사용자가 이전에 권한 요청을 거부한 경우 앱이 추가 설명을 표시할 수 있습니다. 사용자 수 권한이 부여된 이유를 이해할 때 권한을 부여할 가능성이 더 높습니다. 즉각적인 혜택을 줄 수 있어야 합니다

이 경우 requestPermissions를 호출하기 전에 다음을 호출해야 합니다. shouldShowRequestPermissionRationale 다음을 반환하는 경우 true를 반환하는 경우에는 UI에 대한 추가 컨텍스트를 표시하는 UI를 만들어야 합니다. 권한을 부여했는지 확인합니다.

예를 들어 코드는 다음과 같을 수 있습니다.

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
    // Check Permissions Now
    private static final int REQUEST_LOCATION = 2;

    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.ACCESS_FINE_LOCATION)) {
        // Display UI and wait for user interaction
    } else {
        ActivityCompat.requestPermissions(
            this, new String[]{Manifest.permission.LOCATION_FINE},
            ACCESS_FINE_LOCATION);
    }
} else {
    // permission has been granted, continue as usual
    Task<Location> locationResult = LocationServices
        .getFusedLocationProviderClient(this /** Context */)
        .getLastLocation();
}

연결 실패 처리

앱에서 지원 중단된 GoogleApiClient를 사용하는 경우 connect()를 사용하도록 설정한 경우 Google Play 서비스는 권한을 부여할 수 있습니다 권한 그룹이 있는 경우 connect()가 실패함 포함되어 있지 않습니다.

connect() 호출이 실패하면 앱이 연결 실패가 올라갑니다. Google Play 서비스가 자체에 권한이 없으면 startResolutionForResult()를 호출하여 사용자 플로우를 시작하여 이를 수정합니다.

예를 들면 다음과 같습니다.

@Override
public void onConnectionFailed(ConnectionResult result) {
    if (mResolvingError) {
        // Already attempting to resolve an error.
        return;
    } else if (result.hasResolution()) {
        try {
            mResolvingError = true;
            result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
        } catch (SendIntentException e) {
            // There was an error with the resolution intent. Try again.
            mGoogleApiClient.connect();
        }
    } else {
        // Show dialog using GooglePlayServicesUtil.getErrorDialog()
        showErrorDialog(result.getErrorCode());
        mResolvingError = true;
    }
}

최신 GoogleApi 기반 API 호출은 대화상자 중 하나를 자동으로 표시합니다( Activity) 또는 작업 표시줄 알림 (인 경우)으로 클라이언트가 인스턴스화됩니다. 클라이언트는 사용자가 탭하여 시작할 수 있는 Context로 인스턴스화됩니다. 권한 확인 인텐트 요청이 발생하면 호출이 대기열에 추가되고 권한이 부여됩니다