Register now for Android Dev Summit 2019!

Android 6.0 변경 사항

Android 6.0(API 레벨 23)에는 새로운 기능 및 특징과 더불어 다양한 시스템 변경 사항 및 API 동작 변경 사항이 포함되어 있습니다. 이 문서에서는 여러분이 앱에서 숙지하고 고려해야 하는 몇 가지 주요 변경 사항을 소개하겠습니다.

이전에 Android용 앱을 게시한 적이 있는 경우, 이와 같은 플랫폼 변경으로 인해 앱이 영향을 받는다는 점을 유의하세요.

런타임 권한

이 릴리스에서는 새 권한 모델을 소개합니다. 여기에서는 이제 사용자가 런타임에 직접 앱 권한을 관리할 수 있게 됩니다. 이 모델을 사용하면 사용자에게 개선된 가시성과 권한에 대한 제어권을 부여하는 한편 앱 개발자에게는 설치와 자동 업데이트 과정을 간소화해 줍니다. 사용자는 설치된 여러 앱에 대해 개별적으로 권한을 허용하거나 취소할 수 있습니다.

Android 6.0(API 레벨 23) 이상을 대상으로 하는 앱의 경우, 권한 확인과 요청은 런타임에 해야 합니다. 앱에 어떤 권한이 허용되었는지 판단하려면, 새 checkSelfPermission()메서드를 호출합니다. 권한을 요청하려면 새 requestPermissions() 메서드를 호출합니다. 앱이 Android 6.0(API 레벨 23)을 대상으로 하지 않더라도, 앱을 새 권한 모델에서 테스트해 보는 것이 좋습니다.

앱에서 새 권한 모델을 지원하는 방법에 대한 자세한 내용은 시스템 권한 작업을 참조하세요. 앱에 미치는 영향을 평가하는 방법에 대한 팁은 권한 모범 사례를 참조하세요.

잠자기 및 앱 대기 모드

이 릴리스에는 유휴 상태의 기기 및 앱에 대한 새로운 절전 최적화 기능이 새롭게 추가되었습니다. 이 기능은 새로운 모드에서 앱을 테스트할 수 있도록 모든 앱에 영향을 미칩니다.

  • 잠자기 모드: 사용자가 기기의 플러그를 뽑고 화면이 꺼진 채로 일정 시간 동안 변화 없는 상태로 유지되면, 잠자기 모드로 들어갑니다. 이 모드에서는 기기가 시스템을 절전 모드 상태로 유지하려 시도합니다. 이 모드에서 기기는 정기적으로 잠시 동안 정상 작동을 재개하여 앱 동기화가 일어날 수 있도록 하고 보류된 작업이 있으면 시스템이 이를 수행할 수 있도록 합니다.
  • 앱 대기 모드: 앱 대기 모드는 사용자가 활발하게 사용하지 않는 경우, 시스템이 앱의 유휴 상태를 결정하게 합니다. 시스템은 사용자가 일정 시간 앱을 터치하지 않으면 이 결정을 내립니다. 기기의 플러그가 뽑혀 있다면 시스템이 네트워크 액세스를 비활성화하고 앱이 유휴로 간주될 경우 동기화와 작업을 중단합니다.

이 절전 변경 사항에 관한 자세한 정보는 Doze 및 앱 대기 모드 최적화를 참조하세요.

Apache HTTP 클라이언트 제거

이 Android 6.0 릴리스에서는 Apache HTTP 클라이언트에 대한 지원이 제거되었습니다. 앱이 이 클라이언트를 사용하고 Android 2.3(API 레벨 9) 이상을 대상으로 하는 경우, HttpURLConnection 클래스를 대신 사용하세요. 이는 투명한 압축과 응답 캐싱을 통해 네트워크 사용량을 줄이고 전력 소모를 최소화하기 때문에 API가 더 효율적입니다. Apache HTTP API를 계속 사용하려면 우선 다음과 같은 컴파일-시간 종속성을 build.gradle 파일에서 선언해야 합니다.

android {
    useLibrary 'org.apache.http.legacy'
}

BoringSSL

Android에서는 OpenSSL에서 BoringSSL 라이브러리로 전환 중에 있습니다. 앱에서 Android NDK를 사용하는 경우, NDK API의 일부분이 아닌 암호화 라이브러리에 대해 링크를 연결하지 마십시오(예: libcrypto.solibssl.so). 이러한 라이브러리는 공개 API가 아니며, 여러 릴리스와 기기에 걸쳐 통보 없이 변경되거나 중단될 수 있습니다. 또한 스스로를 보안 취약점에 노출시킬 수도 있습니다. 대신에 원래 코드를 수정하여 JNI를 통해 Java 암호화 API를 호출하도록 하거나, 직접 선택한 암호화 라이브러리에 대해 정적으로 연결하도록 하세요.

하드웨어 식별자 액세스

사용자에게 강화된 데이터 보호를 제공하기 위해 이 릴리스에서부터 Android는 Wi-Fi와 Bluetooth API를 사용하는 앱에서 기기의 로컬 하드웨어 식별자에 대한 프로그램 액세스를 제거합니다. 이제 WifiInfo.getMacAddress()BluetoothAdapter.getAddress() 메서드는 02:00:00:00:00:00의 상수 값을 반환합니다.

블루투스와 Wi-Fi 스캔으로 근처 외부 기기의 하드웨어 식별자에 액세스하려면 앱에 ACCESS_FINE_LOCATION 또는 ACCESS_COARSE_LOCATION 권한이 있어야 합니다.

참고: Android 6.0(API 레벨 23)이 실행되는 기기가 백그라운드 Wi-Fi 또는 블루투스 스캔을 시작하면 이 작업은 외장 기기에서 무작위 MAC 주소에서 발생하는 것으로 나타납니다.

알림

이 릴리스에서는 Notification.setLatestEventInfo() 메서드가 제거되었습니다. 대신 Notification.Builder 클래스를 사용하여 알림을 구성해야 합니다. 알림을 반복적으로 업데이트하려면 Notification.Builder 인스턴스를 재사용합니다. build() 메서드를 호출하여 업데이트된 Notification 인스턴스를 가져옵니다.

이제 adb shell dumpsys notification 명령은 알림 텍스트를 출력하지 않습니다. 대신 adb shell dumpsys notification --noredact 명령을 사용하여 알림 객체에서 텍스트를 출력합니다.

AudioManager 변경 사항

볼륨을 직접 설정하거나 특정 스트림을 AudioManager 클래스를 통해 음소거하는 것은 이제 더 이상 지원되지 않습니다. setStreamSolo() 메서드는 사용이 중단되었으며, 그 대신 requestAudioFocus() 메서드를 호출해야 합니다. 이와 마찬가지로, setStreamMute() 메서드도 지원이 중단되었습니다. 그 대신 adjustStreamVolume() 메서드를 호출하고 방향 값 ADJUST_MUTE 또는 ADJUST_UNMUTE에서 전달해야 합니다.

텍스트 선택

사용자가 앱에서 텍스트를 선택하면 이제 텍스트 선택 작업을 표시할 수 있습니다. 예를 들어 잘라내기, 복사붙여넣기부동 툴바로 표시할 수 있습니다. 이 사용자 상호작용 구현은 상황별 액션 바에 대한 구현과 비슷합니다. 이 내용은 각각의 뷰에 대한 상황별 작업 모드의 활성화에 설명되어 있습니다.

텍스트 선택을 위해 부동 툴바를 구현하려면 기존 앱에 다음과 같은 변경을 적용하면 됩니다.

  1. View 또는 Activity 객체에서 ActionMode 호출을 startActionMode(Callback)에서 startActionMode(Callback, ActionMode.TYPE_FLOATING)로 변경합니다.
  2. 기존 ActionMode.Callback 구현을 가져와서, 대신 ActionMode.Callback2로 확장합니다.
  3. onGetContentRect() 메서드를 재정의하여 보기에서 콘텐츠 Rect 객체(예: 텍스트 선택 직사각형)의 좌표를 제공합니다.
  4. 직사각형 위치 지정이 더 이상 유효하지 않고, 무효화할 요소가 이것뿐인 경우 invalidateContentRect() 메서드를 호출합니다.

Android 지원 라이브러리 수정 버전 22.2를 사용하는 경우, 부동 툴바는 이전 버전과 호환되지 않으며 AppCompat이 기본적으로 ActionMode 객체의 제어권을 넘겨받는다는 점을 유의하세요. 이 경우, 부동 툴바가 표시되지 않도록 차단됩니다. AppCompatActivity에서 ActionMode 지원을 활성화하려면, getDelegate()를 호출한 다음 반환된 AppCompatDelegate 객체에서 setHandleNativeActionModesEnabled()를 호출하고 입력 매개변수를 false로 설정합니다. 이 호출은 ActionMode 객체의 제어권을 프레임워크에 돌려줍니다. Android 6.0(API 레벨 23)을 실행하는 기기에서 이렇게 하면 프레임워크가 ActionBar 또는 부동 툴바 모드를 지원할 수 있고, 한편 Android 5.1(API 레벨 22) 이전 기기에서는 ActionBar 모드만 지원됩니다.

브라우저 책갈피 변경 사항

이 릴리스에서는 전역 책갈피 지원이 제거되었습니다. android.provider.Browser.getAllBookmarks()android.provider.Browser.saveBookmark() 메서드는 이제 제거되었습니다. 마찬가지로 READ_HISTORY_BOOKMARKSWRITE_HISTORY_BOOKMARKS 권한도 제거되었습니다. 앱이 Android 6.0(API 레벨 23) 이상을 대상으로 하면 전역 제공자에서 책갈피에 액세스하거나 책갈피 권한을 사용하지 마십시오. 대신 앱은 내부에서 책갈피 데이터를 저장해야 합니다.

Android Keystore 변경 사항

이 릴리스에서는 Android Keystore 제공자가 더 이상 DSA를 지원하지 않습니다. ECDSA는 여전히 지원됩니다.

휴식 중일 때 암호화가 필요하지 않은 키도 보안 잠금 화면이 비활성화되거나 재설정될 때(예: 사용자가 또는 기기 관리자가 재설정) 더 이상 삭제되지 않습니다. 휴식 중일 때 암호화가 필요한 키는 이러한 이벤트 중에 삭제됩니다.

Wi-Fi 및 네트워킹 변경 사항

이 릴리스에서는 Wi-Fi와 네트워킹 API에 다음과 같은 동작 변경 사항이 추가되었습니다.

  • 이제 앱은 개발자가 WifiConfiguration 객체를 생성한 경우에만 이러한 객체의 상태를 변경할 수 있습니다. 사용자 또는 다른 앱이 생성한 WifiConfiguration 객체는 개발자가 수정하거나 삭제할 권한이 없습니다.
  • 이전에는 앱이 기기에 강제로 특정 Wi-Fi 네트워크에 연결하도록 하는 경우, 즉 enableNetwork()disableAllOthers=true 설정으로 사용하면 기기가 셀룰러 데이터와 같은 다른 네트워크에서는 연결을 해제했습니다. 이 릴리스에서는 기기가 그러한 다른 네트워크에서 더 이상 연결을 해제하지 않습니다. 앱의 targetSdkVersion“20” 이하인 경우, 선택한 Wi-Fi 네트워크에 고정됩니다. 앱의 targetSdkVersion“21” 이상인 경우, 멀티네트워크 API를 사용합니다(예: openConnection(), bindSocket() 및 새 bindProcessToNetwork() 메서드). 이렇게 하면 네트워크 트래픽이 선택한 네트워크에서 전송되도록 보장할 수 있습니다.

카메라 서비스 변경 사항

이 릴리스에서는 카메라 서비스에서 공유된 리소스에 액세스하는 모델이 이전의 "선착순" 액세스 모델에서 바뀌어 우선 순위가 높은 프로세스를 선호하는 액세스 모델로 변경되었습니다. 서비스 동작에 대한 변경 사항은 다음과 같습니다.

  • 카메라 하위 시스템 리소스(카메라 기기 열기 및 구성 포함)에 대한 액세스 권한은 클라이언트 애플리케이션 프로세스의 "우선 순위"를 기반으로 부여됩니다. 대개는 사용자에게 표시되는 액티비티 또는 포그라운드 액티비티가 있는 애플리케이션 프로세스에 높은 우선 순위가 부여되어 카메라 리소스 획득과 사용에 좀 더 신뢰감을 더합니다.
  • 우선 순위가 낮은 앱에 대한 활성 카메라 클라이언트는 우선 순위가 더 높은 애플리케이션이 카메라를 사용하려 시도하면 "제거"될 수 있습니다. 사용이 중단된 Camera API의 경우, 이 때문에 onError()가 제거된 클라이언트에 대해 호출되는 결과를 초래합니다. Camera2 API에서는 제거된 클라이언트에 대해 onDisconnected()가 호출됩니다.
  • 적절한 카메라 하드웨어를 갖춘 기기에서는 별도의 애플리케이션 프로세스가 각자 따로따로 열려 동시에 각기 다른 카메라 기기를 사용할 수 있습니다. 하지만 여러 프로세스를 사용하는 경우 동시에 액세스하면 열려 있는 카메라 기기 모두의 성능 또는 기능이 대폭 저하되는 결과를 유발했었는데, 이런 경우도 이제 카메라 서비스가 감지하여 허용하지 않게 됩니다. 이러한 변경으로 인해, 같은 카메라 기기에 직접 액세스하려 시도하는 앱이 없는 경우에도 우선 순위가 낮은 클라이언트를 "제거"하는 결과를 초래할 수도 있습니다.
  • 현재 사용자를 변경하면 앱 내에서 이전 사용자 계정이 소유하는 활성 카메라 클라이언트를 제거하는 결과를 유발할 수 있습니다. 카메라에 대한 액세스는 현재 기기 사용자가 소유한 사용자 프로필로만 제한됩니다. 이것은 실제로 예를 들면, 사용자가 다른 계정으로 전환하면 "Guest" 계정은 카메라 시스템을 사용하는 실행 중인 프로세스에서 나갈 수 없게 된다는 뜻입니다.

런타임

이제 ART 런타임이 newInstance() 메서드에 대한 액세스 규칙을 제대로 구현할 수 있습니다. 이 변경 덕분에 이전 버전에서는 Dalvik이 액세스 규칙을 잘못 확인하던 문제를 해결했습니다. 앱이 newInstance() 메서드를 사용하고 액세스 확인을 재정의하고자 하는 경우, setAccessible() 메서드를 호출하되 입력 매개변수를 true로 설정한 상태로 사용합니다. 앱이 v7 AppCompat 라이브러리 또는 v7 RecyclerView 라이브러리를 사용하는 경우, 앱을 업데이트하여 이러한 라이브러리의 최신 버전을 사용하도록 해야 합니다. 그렇지 않으면, XML에서 참조되는 모든 사용자 지정 클래스가 업데이트되도록 확인하여 그 클래스 생성자에 액세스할 수 있도록 해야 합니다.

이 릴리스에서는 동적 링커의 동작을 업데이트합니다. 동적 링커는 이제 라이브러리의 soname과 그 경로(공개 버그 6670) 사이의 차이점을 숙지하고 있으며, 이제 soname 기준 검색도 구현되었습니다. 이전에 작동한 앱 중에서 DT_NEEDED 항목이 있는 경우(주로 빌드 머신의 파일 시스템에 있는 절대 경로) 로드할 때 실패할 수 있습니다.

이제 dlopen(3) RTLD_LOCAL 플래그가 올바로 구현되었습니다. RTLD_LOCAL이 기본값이므로 RTLD_LOCAL을 명시적으로 사용하지 않는 dlopen(3)에 대한 호출은 영향을 받을 수 있다는 점을 유의하세요(단, 앱이 명시적으로 RTLD_GLOBAL을 사용한 경우는 예외). RTLD_LOCAL의 경우, 나중에 dlopen(3) 호출로 로드되는 라이브러리에서는 기호를 이용할 수 없게 됩니다(DT_NEEDED 항목에 의해 참조되는 것과는 반대).

Android의 이전 버전에서 앱이 시스템에 텍스트 재배치와 함께 공유 라이브러리를 로드하도록 요청하면 시스템은 경고를 표시하되 라이브러리 로드는 허용했습니다. 이 릴리스부터 앱이 SDK 버전 23 이상을 대상으로 하면 시스템이 이 라이브러리를 거부합니다. 라이브러리 로드가 실패했는지 확인할 수 있도록 앱은 dlopen(3) 실패를 기록하고 dlerror(3) 호출이 반환하는 문제 설명 텍스트를 포함합니다. 텍스트 재배치 처리에 관한 자세한 정보는 이 가이드를 참조하세요.

APK 유효성 검사

이제 플랫폼이 APK에 대해 좀 더 엄격한 유효성 검사를 수행합니다. APK는 파일이 매니페스트에서는 선언되었지만 APK 자체에는 없는 경우 손상된 것으로 간주됩니다. 콘텐츠가 하나라도 제거되면 APK를 다시 서명해야 합니다.

USB 연결

이제 USB 포트를 통한 기기 연결은 기본적으로 충전 전용 모드로 설정됩니다. USB 연결을 통해 기기와 콘텐츠에 액세스하려면 사용자가 그러한 상호작용에 명시적으로 권한을 부여해야 합니다. 앱이 USB 포트를 통한 기기와의 상호작용을 지원한다면 이 상호작용이 명시적으로 활성화되어야 한다는 것을 고려하세요.

Android for Work 변경 사항

이 릴리스에는 Android for Work에 대해 다음과 같은 동작 변경 사항이 포함되어 있습니다.

  • 업무용 연락처를 개인적인 맥락에서 이용. 이제 Google 다이얼러 통화 기록에 사용자가 과거 호출을 볼 때 작업 연락처가 표시됩니다. setCrossProfileCallerIdDisabled()true로 설정하면 Google 다이얼러 통화 기록의 작업 프로필 연락처를 숨길 수 있습니다. setBluetoothContactSharingDisabled()false로 설정했을 때에만 블루투스를 통해 기기에 업무용 연락처를 개인용 연락처와 함께 표시합니다. 이것은 기본적으로 true로 설정되어 있습니다.
  • WiFi 구성 제거: 프로필 소유자가 추가한 Wi-Fi 구성(예를 들어 addNetwork() 메서드 호출을 통해)은 이제 해당 작업 프로필이 삭제되면 함께 제거됩니다.
  • WiFi 구성 잠금: WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN이 0이 아니라면 이제 사용자는 활성 기기 소유자가 생성한 Wi-Fi 구성을 수정 또는 삭제할 수 없습니다. 사용자는 여전히 본인의 Wi-Fi 구성을 생성하고 수정할 수 있습니다. 활성 기기 소유자는 자신이 생성하지 않은 것을 비롯한 모든 Wi-Fi 구성을 편집하거나 삭제할 수 있는 권한이 있습니다.
  • Google 계정 추가를 통해 기기 정책 컨트롤러 다운로드: 작업 정책 컨트롤러(WPC) 앱을 통해 관리해야 하는 Google 계정이 관리된 맥락을 벗어나 기기에 추가되는 경우, 이제 추가 계정 흐름이 사용자에게 메시지를 표시하여 적절한 WPC를 설치하도록 합니다. 이 동작은 최초 기기 설정 마법사의 Settings > Accounts를 통해서 추가되는 계정에도 적용됩니다.
  • 특정 DevicePolicyManager API 동작 변경 사항:
    • setCameraDisabled() 메서드를 호출하면 호출한 사용자에 대한 카메라에만 영향을 미칩니다. 이 메서드를 관리된 프로필에서 호출하면 기본 사용자에서 실행 중인 카메라 앱에 영향을 미치지 않습니다.
    • 또한, 이제 setKeyguardDisabledFeatures() 메서드를 기기 소유자뿐만 아니라 프로필 소유자에 대해서도 이용할 수 있습니다.
    • 프로필 소유자는 다음과 같은 키가드 제한 사항을 설정할 수 있습니다.
    • DevicePolicyManager.createAndInitializeUser()DevicePolicyManager.createUser() 메서드는 사용이 중단되었습니다.
    • setScreenCaptureDisabled() 메서드도 특정 사용자의 앱이 포그라운드에 있으면 지원 구조를 차단합니다.
    • EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM 기본값은 SHA-256입니다. SHA-1은 여전히 이전 버전과 호환되지만 향후 제거될 예정입니다. EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM은 이제 SHA-256만 허용합니다.
    • 이제 Android 6.0(API 레벨 23)에 있던 기기 이니셜라이저 API가 제거되었습니다.
    • EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS가 제거되었으므로 NFC 범프 프로비저닝을 통해 프로그래밍 방식으로 공장 재설정 보호 기기의 잠금을 해제할 수 없습니다.
    • 이제 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE 엑스트라를 사용하여 관리되는 기기가 NFC 프로비저닝을 할 때 기기 소유자 앱에 데이터를 전달할 수 있습니다.
    • Android for Work API는 Work 프로필 지원 레이어 등을 포함한 M 런타임 권한에 최적화되어 있습니다. 새로운 DevicePolicyManager 권한 API는 M 이전 앱에 영향을 미치지 않습니다.
    • 사용자가 ACTION_PROVISION_MANAGED_PROFILE 또는 ACTION_PROVISION_MANAGED_DEVICE 인텐트를 통해 시작된 설정 흐름의 동기화 부분에서 나가면, 이제 시스템이 RESULT_CANCELED 결과 코드를 반환합니다.
  • 기타 API 변경 사항:
    • 데이터 사용량: android.app.usage.NetworkUsageStats 클래스는 NetworkStats로 이름이 변경되었습니다.
  • 전역 설정 변경 사항: