Android 4.3 API

API 수준: 18

Android 4.3 (JELLY_BEAN_MR2) 는 사용자와 앱을 위한 새로운 기능을 제공하는 Jelly Bean 출시의 업데이트입니다. 있습니다. 이 문서에서는 Google Cloud Platform을 구성하는 새로운 API를 제공합니다

앱 개발자는 Android 4.3 시스템 이미지를 다운로드해야 합니다. 및 SDK 플랫폼은 SDK Manager의 가능한 한 빨리. Android 4.3을 실행하는 기기가 없을 경우 앱을 테스트하려면 Android 4.3 시스템을 사용하세요. 이미지를 사용하여 Android Emulator에서 앱을 테스트합니다. 그런 다음 Android 4.3 플랫폼을 대상으로 앱을 빌드하여 최신 API를 제공합니다

대상 API 레벨 업데이트

Android 4.3을 실행하는 기기에 대해 앱을 더 잘 최적화하려면, targetSdkVersion"18"를 Android 4.3 시스템 이미지에 설치합니다. 테스트한 후 이 변경사항이 적용된 업데이트를 게시해야 합니다.

Android 4.3에서 API를 사용하는 동시에 실행하기 전에 시스템 API 수준을 확인하는 코드에 대한 조건 minSdkVersion에서 지원되지 않는 API 이전 버전과의 호환성 유지에 관한 자세한 내용은 다양한 애플리케이션 지원 플랫폼 버전.

Android 지원 라이브러리에서도 다양한 API를 제공하며, 이를 통해 API를 구현할 수 있습니다. 이전 버전의 플랫폼에서 새로운 기능을 제공합니다.

API 수준의 작동 방식에 대한 자세한 내용은 API란 무엇인가요? 레벨?

중요한 동작 변경 사항

이전에 Android용 앱을 게시한 적이 있는 경우 영향을 받는다고 가정해 보겠습니다.

앱이 암시적 인텐트를 사용하는 경우...

제한된 프로필 환경에서 앱이 오작동할 수 있습니다.

제한된 프로필 환경의 사용자는 모든 표준 Android 앱을 사용할 수 있습니다. 예를 들어 제한된 프로필에는 웹브라우저 및 카메라 앱이 사용 중지되었습니다. 따라서 앱에서 어떤 앱이 이는 startActivity()을 호출하지 않고 앱이 Intent를 처리할 수 있는지 확인 제한된 프로필에서 앱이 다운될 수 있습니다.

암시적 인텐트를 사용할 때는 resolveActivity() 또는 queryIntentActivities()를 호출하여 앱에서 인텐트를 처리할 수 있는지 항상 확인해야 합니다. 예를 들면 다음과 같습니다.

Kotlin

val intent = Intent(Intent.ACTION_SEND)
...
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show()
}

자바

Intent intent = new Intent(Intent.ACTION_SEND);
...
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
}

앱이 계정을 사용하는 경우...

제한된 프로필 환경에서 앱이 오작동할 수 있습니다.

제한된 프로필 환경 내의 사용자는 기본적으로 사용자 계정에 액세스할 수 없습니다. 앱이 Account에 종속되면 앱이 비정상 종료되거나 동작할 수 있습니다. 예기치 않게 발생하는 오류 메시지가 표시될 수 있습니다.

사용자의 개인 정보가 제한되거나 제한되기 때문에 앱이 민감한 계정 정보에 의존하는 경우 매니페스트의 <application>에서 android:requiredAccountType 속성을 지정합니다. 요소가 포함됩니다.

제한된 프로필이 사용할 수 없는 경우에도 앱을 계속 사용하도록 허용하려는 경우 직접 계정을 만든 다음 계정이 필요한 앱 기능을 사용 중지하거나 또는 제한된 프로필이 기본 사용자가 만든 계정에 액세스하도록 허용합니다. 자세한 내용은 자세히 알아보려면 제한된 프로필에서 계정 지원을 참조하세요.

앱에서 VideoView를 사용하는 경우...

Android 4.3에서는 동영상이 더 작게 표시될 수 있습니다.

이전 버전의 Android에서 VideoView 위젯이 제대로 작동하지 않음 layout_heightlayout_width"wrap_content" 값을 "match_parent"과 동일하게 계산했습니다. 따라서 높이 또는 너비에 "wrap_content"를 사용하는 동안 이전에 원하는 동영상 레이아웃을 제공했을 수 있습니다. 이렇게 하면 Android 4.3 이상에서 동영상이 훨씬 작아질 수 있습니다. 문제를 해결하려면 "match_parent"(으)로 "wrap_content"하고 동영상이 예상대로 표시되는지 확인하세요. 이전 버전 및 Android 4.3

제한된 프로필

이제 Android 태블릿에서 사용자는 기본 사용자를 기반으로 제한된 프로필을 만들 수 있습니다. 제한된 프로필을 만든 사용자는 사용할 수 없습니다. Android 4.3의 새로운 API 세트를 사용하면 제한 설정을 적용할 수 있습니다. 예를 들어 새 API를 사용하면 사용자가 앱에서 실행할 때 앱 내에서 사용할 수 있는 콘텐츠 유형을 제한된 프로필 환경.

개발자가 구축한 제한사항을 사용자가 제어할 수 있는 UI는 시스템의 설정 애플리케이션 앱의 제한 설정을 사용자에게 표시하려면 다음 단계를 따르세요. ACTION_GET_RESTRICTION_ENTRIES 인텐트를 수신하는 BroadcastReceiver를 만들어 앱이 제공하는 제한을 선언해야 합니다. 시스템은 이 인텐트를 호출하여 모든 앱에 사용 가능한 제한 사항을 적용하도록 한 다음 기본 사용자가 각각의 제한된 프로필에 대한 제한을 관리합니다.

다음의 onReceive() 메서드에서 BroadcastReceiver에서는 앱에서 제공하는 각 제한사항에 대해 RestrictionEntry를 만들어야 합니다. 각 RestrictionEntry는 제한 제목, 설명, 다음과 같은 데이터 유형이 있습니다.

  • TYPE_BOOLEAN: true 또는 false입니다.
  • TYPE_CHOICE: 선택할 수 있습니다 (라디오 버튼 선택).
  • TYPE_MULTI_SELECT: 상호 배타적이지 않은 여러 선택 항목 (체크박스 선택)이 있는 경우

그런 다음 모든 RestrictionEntry 객체를 ArrayList에 넣고 broadcast receiver의 결과에 다음과 같은 값으로 넣습니다. 추가 항목 EXTRA_RESTRICTIONS_LIST개.

시스템은 설정 앱에 앱 제한에 대한 UI를 생성하고 각 UI를 저장합니다. 각 RestrictionEntry에 제공한 고유 키로 제한 객체를 지정합니다. 사용자가 앱을 열 때 다음을 실행하여 현재 제한사항을 쿼리할 수 있습니다. getApplicationRestrictions()를 호출합니다. 이렇게 하면 각 제한의 키-값 쌍이 포함된 Bundle가 반환됩니다. RestrictionEntry 객체로 정의했습니다.

부울, 단일 다중 선택 값, 다중 선택 값을 포함하는 경우 사용자가 사용자가 제한 설정에서 해당 활동을 열 수 있도록 허용합니다. broadcast receiver, EXTRA_RESTRICTIONS_INTENT 추가 항목 포함 결과 Bundle에 있습니다. 이 추가 항목은 Intent를 지정해야 합니다. 실행할 Activity 클래스를 나타냅니다( putParcelable() 메서드를 사용하여 인텐트와 함께 EXTRA_RESTRICTIONS_INTENT를 전달합니다. 기본 사용자가 맞춤 제한을 설정하기 위해 활동을 시작하면 그런 다음 활동은 추가에서 제한 값을 포함하는 결과를 EXTRA_RESTRICTIONS_LIST 또는 EXTRA_RESTRICTIONS_BUNDLERestrictionEntry 객체 또는 키-값 쌍입니다.

제한된 프로필에서 계정 지원

기본 사용자에게 추가된 모든 계정은 제한된 프로필에서 사용할 수 있지만 계정은 기본적으로 AccountManager API에서 액세스할 수 없습니다. 제한된 공간에서 AccountManager(으)로 계정을 추가하려고 시도하는 경우 실패하면 실패 결과가 표시됩니다. 이러한 제한으로 인해 다음과 같은 제한사항이 적용됩니다. 3가지 옵션이 있습니다

  • 제한된 프로필에서 소유자 계정에 대한 액세스를 허용합니다.

    제한된 프로필에서 계정에 액세스하려면 <application> 태그에 android:restrictedAccountType 속성을 추가해야 합니다.

    <application ...
        android:restrictedAccountType="com.example.account.type" >
    

    주의: 이 속성을 사용 설정하면 제한된 프로필에서 기본 사용자의 계정에 대한 앱 액세스. 따라서 이 작업은 앱에서 표시하는 정보에서 개인 식별 정보를 공개하지 않는 경우에만 민감한 정보로 간주되는 정보 (PII)를 포함할 수 없습니다. 시스템 설정은 기본 앱에서 제한된 프로필을 자신의 계정에 부여한다는 점을 사용자에게 명확히 알려야 합니다. 계정 액세스가 앱의 기능에 중요함을 확인합니다. 또한 가능한 경우 계정 액세스 수준을 정의하는 기본 사용자에게 적절한 제한 제어 기능 제공 허용됩니다.

  • 계정을 수정할 수 없는 경우 특정 기능을 사용 중지합니다.

    계정을 사용하고 싶지만 앱의 기본 용도에 실제로는 필요하지 않은 경우 계정 사용 가능 여부를 확인하고, 사용할 수 없는 경우 기능을 사용 중지할 수 있습니다. 먼저 사용 가능한 기존 계정이 있는지 확인해야 합니다. 그렇지 않은 경우 getUserRestrictions()를 호출하여 새 계정을 만들고 결과에서 DISALLOW_MODIFY_ACCOUNTS 추가 항목을 확인할 수 있습니다. true인 경우 계정 액세스 권한을 요구하는 앱의 기능은 모두 사용 중지해야 합니다. 예를 들면 다음과 같습니다.

    Kotlin

    val um = context.getSystemService(Context.USER_SERVICE) as UserManager
    val restrictions: Bundle = um.userRestrictions
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    자바

    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    Bundle restrictions = um.getUserRestrictions();
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    참고: 이 시나리오에서는 새 속성을 설정할 수 있습니다

  • 비공개 계정에 액세스할 수 없는 경우 앱을 사용 중지합니다.

    대신 다음과 같은 이유로 제한된 프로필에서 앱을 사용하지 못하게 하는 것이 앱에 있는 민감한 개인 정보가 필요한 경우 현재 새 계정을 추가할 수 없음), 추가 <application> 태그에 android:requiredAccountType 속성을 추가합니다.

    <application ...
        android:requiredAccountType="com.example.account.type" >
    

    예를 들어 Gmail 앱은 이 속성을 사용하여 제한된 프로필에 대해 자체적으로 사용 중지합니다. 소유자의 개인 이메일을 제한된 프로필에서 사용할 수 없기 때문입니다.

  • 무선 및 연결

    저전력 블루투스 (스마트 지원)

    Android는 이제 android.bluetooth의 새 API를 사용하여 저전력 블루투스 (LE)를 지원합니다. 새로운 API를 사용하면 저전력 블루투스와 통신하는 Android 앱을 빌드할 수 있습니다. 심박수 모니터 및 만보계와 같은 주변기기.

    블루투스 LE는 일부 기기에서만 사용할 수 있는 하드웨어 기능이기 때문에 Android 지원 기기의 경우 매니페스트 파일에서 <uses-feature>을 선언해야 합니다. "android.hardware.bluetooth_le"의 요소:

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
    

    이미 Android의 기본 Bluetooth API에 익숙하다면 Bluetooth LE API에는 몇 가지 차이점이 있습니다. 가장 중요한 점은 이제 일부 상위 수준의 작업에 사용해야 하는 BluetoothManager 클래스가 있다는 것입니다. 예를 들어 BluetoothAdapter 가져오기, 연결된 기기 목록 가져오기, 기기 상태 확인 등이 포함됩니다. 예를 들어 BluetoothAdapter:

    Kotlin

    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothAdapter = bluetoothManager.adapter
    

    자바

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();
    

    블루투스 LE 주변기기를 검색하려면 BluetoothAdapter에서 startLeScan()를 호출하여 구현에 전달하세요. BluetoothAdapter.LeScanCallback 인터페이스의 하위 클래스입니다. 블루투스가 어댑터가 블루투스 LE 주변기기를 감지하면 BluetoothAdapter.LeScanCallback 구현이 블루투스 LE 주변기기를 onLeScan() 메서드를 사용하여 지도 가장자리에 패딩을 추가할 수 있습니다. 이 메서드는 개발자가 대상 객체를 나타내는 BluetoothDevice 객체를 제공합니다. RSSI 값, 기기의 RSSI 값을 포함하는 바이트 배열이 광고 기록

    특정 유형의 주변기기만 스캔하려면 대신 startLeScan()를 호출하고 앱에서 지원하는 GATT 서비스를 지정하는 UUID 객체의 배열을 포함하면 됩니다.

    참고: 블루투스 LE 기기만 검색할 수 있습니다. 또는 이전 API를 사용하여 기본 블루투스 기기를 검색합니다. LE와 클래식을 모두 스캔할 수는 없습니다. 블루투스 기기를 모두 지원합니다.

    그런 다음 블루투스 LE 주변기기에 연결하려면 해당하는 기기에서 connectGatt()를 호출합니다. BluetoothDevice 객체를 사용하여 BluetoothGattCallback입니다. BluetoothGattCallback 구현은 연결과 관련된 콜백을 수신합니다. 상태를 기기 및 기타 이벤트와 연결합니다. onConnectionStateChange() 중 메서드가 새 상태로 STATE_CONNECTED를 전달하는 경우 기기와의 통신을 시작할 수 있는 콜백입니다.

    기기에서 블루투스 기능에 액세스하려면 앱에서 블루투스 사용자 권한 자세한 내용은 저전력 블루투스 API 가이드를 참조하세요.

    Wi-Fi 검색 전용 모드

    사용자 위치를 식별하려고 할 때 Android는 Wi-Fi를 사용하여 사용자 위치를 파악할 수 있습니다. 주변 액세스 포인트를 검색하여 위치를 찾습니다. 하지만 사용자는 종종 배터리를 절약하여 위치 데이터의 정확도가 떨어집니다. 이제 Android에는 기기의 Wi-Fi에서 액세스 포인트를 검색하여 위치를 확인할 수 있는 스캔 전용 모드 액세스 포인트에 연결하지 않아도 되므로 배터리 사용량이 크게 줄어듭니다.

    사용자 위치를 가져오고 싶지만 현재 Wi-Fi가 꺼져 있는 경우 사용자가 ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE 작업으로 startActivity()를 호출하여 Wi-Fi 스캔 전용 모드를 사용 설정하도록 하세요.

    Wi-Fi 구성

    새로운 WifiEnterpriseConfig API를 사용하면 엔터프라이즈 중심 서비스에서 다음 작업을 할 수 있습니다. 관리 기기의 Wi-Fi 구성을 자동화합니다.

    수신 전화에 대한 빠른 응답

    Android 4.0부터 '빠른 응답'이라는 기능이 사용자가 수신된 메시지에 응답하도록 전화를 받거나 기기를 잠금 해제할 필요 없이 즉시 문자 메시지로 전화를 걸 수 있습니다. 지금까지는 빠른 메시지가 항상 기본 메시지 앱에서 처리되었습니다. 이제 모든 앱에서 Service를 만들어 이러한 메시지를 처리하는 기능을 선언할 수 있습니다. ACTION_RESPOND_VIA_MESSAGE의 인텐트 필터로 구성됩니다.

    사용자가 빠른 응답으로 수신 전화에 응답하면 전화 앱은 URI가 있는 ACTION_RESPOND_VIA_MESSAGE 인텐트 수신자 (발신자) 및 EXTRA_TEXT 추가 항목 설명 메시지를 보낼 수 있습니다 서비스가 인텐트를 수신하면 즉시 중지됩니다 (앱이 활동을 표시하면 안 됨).

    이 인텐트를 수신하려면 SEND_RESPOND_VIA_MESSAGE 권한을 선언해야 합니다.

    멀티미디어

    MediaExtractor 및 MediaCodec 개선사항

    이제 Android에서 나만의 동적 적응형을 더 쉽게 작성할 수 있습니다 ISO/IEC 23009-1 표준에 따른 HTTP (DASH) 플레이어를 통한 스트리밍 MediaCodecMediaExtractor의 기존 API 사용 이러한 API의 기반이 되는 프레임워크는 분할된 MP4 파일을 파싱하지만 앱에서 MPD 메타데이터를 파싱해야 합니다. 개별 스트림을 MediaExtractor에 전달합니다.

    암호화된 콘텐츠와 함께 DASH를 사용하려면 getSampleCryptoInfo() 메서드가 암호화된 각 미디어의 구조를 설명하는 MediaCodec.CryptoInfo 메타데이터를 반환합니다. 샘플입니다. 또한 getPsshInfo() 메서드가 MediaExtractor: DASH 미디어의 PSSH 메타데이터에 액세스할 수 있습니다. 이 메서드는 UUID 객체를 바이트로 매핑하고 암호화 스키마를 지정하는 UUID 및 데이터 관련 바이트 추가할 수 있습니다.

    미디어 DRM

    새로운 MediaDrm 클래스는 디지털 권리를 위한 모듈식 솔루션을 제공합니다. 관리 (DRM)를 추가할 수 있습니다. 대상 이러한 API 분리를 통해 사용자가 직접 Widevine으로 암호화된 콘텐츠를 Widevine 미디어 형식을 사용해야 합니다 또한 이 DRM 솔루션은 DASH 일반 암호화를 지원하므로 은 스트리밍 콘텐츠에 다양한 DRM 체계를 사용할 수 있습니다.

    MediaDrm를 사용하여 불투명한 키-요청 메시지 및 프로세스를 가져올 수 있습니다. 라이선스 획득 및 프로비저닝을 위한 서버의 키-응답 메시지 현재 앱 상태: 서버와의 네트워크 통신을 처리할 책임이 있습니다. MediaDrm 클래스는 메시지를 생성하고 처리하는 기능만 제공합니다.

    MediaDrm API는 Android 4.1 (API 수준 16)에서 도입된 MediaCodec API 여기에는 콘텐츠를 인코딩 및 디코딩하는 MediaCodec, 암호화된 콘텐츠를 처리하는 MediaCrypto, MediaExtractor가 포함됩니다. 역다중화 작업을 살펴보겠습니다

    먼저 MediaExtractor를 구성하고 MediaCodec 객체. 그런 다음 DRM 스키마 식별 기능에 액세스하여 UUID(일반적으로 콘텐츠의 메타데이터에서 가져옴)이며, 이를 사용하여 생성자가 있는 MediaDrm 객체의 인스턴스입니다.

    노출 영역에서 동영상 인코딩

    Android 4.1 (API 수준 16)에서는 하위 수준용 MediaCodec 클래스를 추가했습니다. 인코딩 및 디코딩을 거치게 됩니다. Android 4.1에서는 동영상을 인코딩할 때 미디어를 ByteBuffer 배열로 지원하지만 이제 Android 4.3에서는 Surface를 인코더에 대한 입력으로 사용할 수 있습니다. 예를 들어 이를 통해 인코더-디코더 아키텍처를 기존 동영상 파일에서 추출하거나 OpenGL ES에서 생성된 프레임을 사용할 수 있습니다.

    인코더에 대한 입력으로 Surface를 사용하려면 먼저 MediaCodecconfigure()를 호출합니다. 그런 다음 createInputSurface()를 호출하여 미디어를 스트리밍할 수 있는 Surface를 수신합니다.

    예를 들어 주어진 Surface를 OpenGL의 창으로 사용할 수 있습니다. 컨텍스트를 전달하여 이 컨텍스트를 eglCreateWindowSurface()에 전달합니다. 그런 다음 노출 영역을 렌더링하는 동안 eglSwapBuffers()를 호출하여 프레임을 MediaCodec에 전달합니다.

    인코딩을 시작하려면 MediaCodec에서 start()를 호출합니다. 완료되면 signalEndOfInputStream()를 호출합니다. 인코딩을 종료하고 release() Surface입니다.

    미디어 다중화

    새로운 MediaMuxer 클래스는 하나의 오디오 스트림 간 멀티플렉싱을 사용 설정합니다. 동영상 스트림이 1개 있습니다. 이러한 API는 MediaExtractor 클래스가 Android 4.2에 역다중화 (역다중화) 미디어용으로 추가되었습니다.

    지원되는 출력 형식은 MediaMuxer.OutputFormat에 정의되어 있습니다. 현재, 지원되는 출력 형식은 MP4뿐이며 MediaMuxer는 현재 지원합니다. 한 번에 하나의 오디오 스트림 또는 동영상 스트림을 하나씩만 설정할 수 있습니다.

    MediaMuxer는 대부분 MediaCodec와 호환되도록 설계되었습니다. 따라서 MediaCodec를 통해 동영상을 처리한 다음 MediaMuxer를 통해 MP4 파일로 출력됩니다. MediaMuxerMediaExtractor를 함께 사용하여 실적을 높일 수도 있습니다. 미디어 편집이 필요하지 않습니다.

    RemoteControlClient의 재생 진행률 및 스크러빙

    Android 4.0 (API 수준 14)에서는 RemoteControlClient이 원격 제어 클라이언트의 미디어 재생 컨트롤(예: 잠금 화면을 탭합니다. Android 4.3은 이제 이러한 컨트롤러가 위치 및 컨트롤을 포함해야 합니다. 리모컨을 사용하도록 설정한 경우 RemoteControlClient API를 사용하여 미디어 앱에 연결된 경우 재생을 허용할 수 있음 두 가지 새로운 인터페이스를 구현하여 스크러빙을 할 수 있습니다

    먼저 FLAG_KEY_MEDIA_POSITION_UPDATE 플래그를 사용 설정하려면 이 플래그를 setTransportControlsFlags()입니다.

    그런 다음 새로운 인터페이스 두 개를 구현합니다.

    RemoteControlClient.OnGetPlaybackPositionListener
    여기에는 현재 위치를 요청하는 onGetPlaybackPosition() 콜백이 포함됩니다. 리모컨의 UI에서 진행률을 업데이트해야 할 때 미디어의 재생 시간을 설정할 수 있습니다.
    RemoteControlClient.OnPlaybackPositionUpdateListener
    여기에는 콜백 onPlaybackPositionUpdate()이 포함됩니다. 사용자가 제어할 수 있습니다.

    새 위치로 재생을 업데이트한 후에는 setPlaybackState()를 호출하여 새로운 재생 상태, 위치, 속도를 설정할 수 있습니다.

    이러한 인터페이스를 정의하면 setOnGetPlaybackPositionListener()를 호출하여 RemoteControlClient에 인터페이스를 설정할 수 있습니다. 각각 setPlaybackPositionUpdateListener()입니다.

    그래픽

    OpenGL ES 3.0 지원

    Android 4.3은 Java 인터페이스와 OpenGL ES 3.0 기본 지원을 추가합니다. 새로운 주요 기능 OpenGL ES 3.0에 제공되는 에는 다음이 포함됩니다.

    • 고급 시각 효과의 가속화
    • 표준 기능으로 제공되는 고품질 ETC2/EAC 텍스처 압축
    • 정수 및 32비트 부동 소수점을 지원하는 GLSL ES 셰이딩 언어의 새 버전
    • 고급 텍스처 렌더링
    • 텍스처 크기 및 렌더링 버퍼 형식의 광범위한 표준화

    Android의 OpenGL ES 3.0용 Java 인터페이스는 GLES30로 제공됩니다. OpenGL ES 3.0을 사용할 때는 매니페스트 파일에서 <uses-feature> 태그 및 android:glEsVersion 속성입니다. 예를 들면 다음과 같습니다.

    <manifest>
        <uses-feature android:glEsVersion="0x00030000" />
        ...
    </manifest>
    

    setEGLContextClientVersion()를 호출하여 OpenGL ES 컨텍스트를 지정해야 합니다. 3을 버전으로 전달합니다.

    기기의 지원 여부 확인 방법을 비롯하여 OpenGL ES 사용에 관한 자세한 내용은 런타임 시 OpenGL ES 버전에 관한 자세한 내용은 OpenGL ES API 가이드를 참고하세요.

    드로어블 밉매핑

    밉맵을 비트맵 또는 드로어블의 소스로 사용하는 것은 간단한 방법입니다. 품질 이미지와 다양한 이미지 척도가 제공되며 이는 애니메이션 도중 배율이 조정될 것입니다.

    Android 4.2 (API 수준 17)는 Bitmap에서 밉맵 지원을 추가했습니다. 클래스 - 작업을 완료하면 Android가 Bitmap의 밉니다. 밉맵 소스를 제공하고 setHasMipMap()를 사용 설정했습니다. 이제 Android 4.3에서 밉맵 애셋과 밉맵 애셋을 제공하여 BitmapDrawable 객체에도 밉맵을 사용 설정할 수 있습니다. 비트맵 리소스 파일에서 android:mipMap 속성을 설정하거나 hasMipMap()를 호출하여

    사용자 인터페이스

    뷰 오버레이

    새로운 ViewOverlay 클래스는 시각적 콘텐츠를 추가할 수 있고View 하위 클래스입니다. getOverlay()를 호출하여 모든 ViewViewOverlay를 가져올 수 있습니다. 오버레이 항상 호스트 뷰 (생성된 뷰)와 크기 및 위치가 동일합니다. 이를 통해 호스트 뷰 앞에 나타나지만 확장할 수 없는 콘텐츠를 추가할 수 있습니다. 호스트 뷰의 경계에 있어야 합니다.

    ViewOverlay를 사용하면 생성하려고 할 때 특히 유용합니다. 컨테이너 외부로 뷰를 슬라이드하거나 화면에서 항목을 이동하는 등의 애니메이션 뷰 계층 구조에 영향을 주지 않고 그러나 오버레이의 사용 가능한 영역이 호스트 뷰와 동일한 영역으로 제한(외부에서 이동하는 뷰를 애니메이션으로 표시하려는 경우) 원하는 경우 원하는 상위 뷰의 오버레이를 사용해야 합니다. 레이아웃 경계.

    Button와 같은 위젯 뷰의 오버레이를 만들 때 다음을 수행합니다. 다음을 호출하여 Drawable 객체를 오버레이에 추가할 수 있습니다. add(Drawable)입니다. RelativeLayout와 같은 레이아웃 뷰에 getOverlay()를 호출하면 반환된 객체는 ViewGroupOverlay입니다. 이 ViewGroupOverlay 클래스가 서브클래스임 View를 추가할 수 있는 ViewOverlay의 비율 객체의 현재 상태를 나타냅니다.add(View)

    참고: 오버레이에 추가하는 모든 드로어블과 뷰 이미지 전용입니다. 포커스나 입력 이벤트는 수신할 수 없습니다.

    예를 들어 다음 코드는 뷰를 배치하여 오른쪽으로 슬라이드하는 애니메이션을 적용합니다. 을 추가한 다음 해당 보기에서 변환 애니메이션을 실행합니다.

    Kotlin

    val view: View? = findViewById(R.id.view_to_remove)
    val container: ViewGroup? = view?.parent as ViewGroup
    
    container?.apply {
        overlay.add(view)
        ObjectAnimator.ofFloat(view, "translationX", right.toFloat())
                .start()
    }
    

    자바

    View view = findViewById(R.id.view_to_remove);
    ViewGroup container = (ViewGroup) view.getParent();
    container.getOverlay().add(view);
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight());
    anim.start();
    

    광학 경계 레이아웃

    나인 패치 배경 이미지가 포함된 뷰의 경우, 이제 나인 패치 배경 이미지가 주변 뷰와 정렬되어야 하며 이때 "광학" 경계선보다 '클립'보다 경계선에 위치할 수 있습니다.

    예를 들어, 그림 1과 그림 2는 각각 동일한 레이아웃을 보여주지만, 그림 1의 버전은 클립 경계를 사용 (기본 동작)하고 그림 2는 광학 경계를 사용합니다. 왜냐하면 버튼 및 디지털 액자에 사용되는 나인 패치 이미지에는 가장자리 주변의 패딩, 클립 경계를 사용할 때 서로 또는 텍스트와 정렬되지 않는 것처럼 보입니다.

    참고: 그림 1 및 그림 2의 스크린샷에는 레이아웃 경계" 개발자 설정이 사용 설정된 상태여야 합니다. 각 보기에서 빨간색 선은 광학 파란색 선은 클립 경계를 나타내며 분홍색은 여백을 나타냅니다.

    그림 1. 클립 경계를 사용하는 레이아웃 (기본값)

    그림 2. 광학 경계를 사용하는 레이아웃

    광학 경계를 기반으로 뷰를 정렬하려면 상위 레이아웃 중 하나에서 android:layoutMode 속성을 "opticalBounds"로 설정합니다. 예를 들면 다음과 같습니다.

    <LinearLayout android:layoutMode="opticalBounds" ... >
    

    그림 3. 홀로 버튼 나인 패치가 표시된 광학 경계입니다.

    이 기능이 작동하려면 뷰의 배경에 적용된 나인 패치 이미지가 나인 패치 파일의 하단과 오른쪽을 따라 빨간색 선을 사용하여 광학 경계( (그림 3 참조) 빨간색 선은 이미지의 광학 경계를 남겨둡니다.

    레이아웃에서 ViewGroup에 광학 경계를 사용 설정하면 하위 뷰는 android:layoutMode"clipBounds"로 설정합니다. 또한 모든 레이아웃 요소는 하위 뷰의 광학 경계, 의 광학 경계에 따라 자체 경계를 조정합니다. 확인할 수 있습니다. 그러나 레이아웃 요소 (ViewGroup의 서브클래스)는 는 현재 자체 배경에 적용된 나인 패치 이미지에 대한 광학 경계를 지원하지 않습니다.

    View, ViewGroup 또는 그 서브클래스를 서브클래스로 분류하여 맞춤 뷰를 만들면 뷰는 이러한 광학 바인딩 동작을 상속합니다.

    참고: Holo 테마에서 지원하는 모든 위젯이 업데이트되었습니다. Button, Spinner, EditText 외 다수 따라서 앱에서 Holo 테마를 적용하는 경우 android:layoutMode 속성을 "opticalBounds"로 설정 (Theme.Holo, Theme.Holo.Light 등)

    9-패치 그리기 도구로 자체 나인 패치 이미지의 광학 경계를 지정하려면 클릭하면 됩니다.

    Rect 값의 애니메이션

    이제 새 RectEvaluator를 사용하여 두 Rect 값 사이에 애니메이션을 적용할 수 있습니다. 이 새 클래스는 ValueAnimator.setEvaluator()에 전달할 수 있는 TypeEvaluator의 구현입니다.

    창 연결 및 포커스 리스너

    이전에는 뷰가 창에 연결/분리된 시점 또는 포커스가 변경되면 View 클래스를 다음과 같이 재정의해야 했습니다. 각각 onAttachedToWindow(), onDetachedFromWindow() 또는 onWindowFocusChanged()를 구현합니다.

    이제 연결 및 분리 이벤트를 수신하려면 대신 ViewTreeObserver.OnWindowAttachListener를 구현하고 다음을 사용하여 뷰에서 설정하면 됩니다. addOnWindowAttachListener()입니다. 포커스 이벤트를 수신하려면 ViewTreeObserver.OnWindowFocusChangeListener를 구현하고 다음을 사용하여 뷰에 설정하면 됩니다. addOnWindowFocusChangeListener()입니다.

    TV 오버스캔 지원

    앱이 모든 TV에서 전체 화면을 채우도록 하려면 이제 오버스캔을 사용 설정하세요. 맞춤설정할 수 있습니다. 오버스캔 모드는 다음과 같은 플랫폼 테마로 사용 설정할 수 있는 FLAG_LAYOUT_IN_OVERSCAN 플래그에 의해 결정됩니다. Theme_DeviceDefault_NoActionBar_Overscan 또는 맞춤 테마의 windowOverscan 스타일

    화면 방향

    <activity> 태그의 screenOrientation 속성이 이제 사용자의 자동 회전 환경설정을 준수하는 추가 값을 지원합니다.

    "userLandscape"
    사용자가 자동 회전을 사용 중지한 경우를 제외하고 "sensorLandscape"와 동일하게 동작합니다. 정상적인 가로 모드 방향으로 고정되고 뒤집히지 않습니다.
    "userPortrait"
    사용자가 자동 회전을 사용 중지한 후 다음 경우를 제외하고 "sensorPortrait"와 동일하게 동작합니다. 정상적인 세로 방향으로 고정되고 뒤집히지 않습니다.
    "fullUser"
    "fullSensor"와 동일하게 작동하며 다음 외에 네 방향으로 모두 회전할 수 있습니다. 사용자가 자동 회전을 사용 중지하면 사용자가 원하는 방향으로 잠깁니다.

    또한 이제 "locked"을 선언하여 앱의 방향을 잠글 수 있습니다. 변경할 수 있습니다.

    회전 애니메이션

    새로운 rotationAnimation 필드 WindowManager를 사용하면 세 가지 애니메이션 중 하나를 선택할 수 있습니다. 지정할 수 있습니다. 세 가지 애니메이션은 다음과 같습니다.

    참고: 이 애니메이션은 활동이 '전체 화면'을 사용하도록 설정한 경우에만 사용할 수 있습니다. 이 모드는 Theme.Holo.NoActionBar.Fullscreen와 같은 테마로 사용 설정할 수 있습니다.

    예를 들어, '크로스페이드'는 애니메이션:

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val params: WindowManager.LayoutParams = window.attributes
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE
        window.attributes = params
        ...
    }
    

    자바

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        getWindow().setAttributes(params);
        ...
    }
    

    사용자 입력

    새 센서 유형

    새로운 TYPE_GAME_ROTATION_VECTOR 센서를 사용하면 자기 간섭에 신경 쓸 필요 없이 기기의 회전을 감지할 수 있습니다. TYPE_ROTATION_VECTOR 센서와 달리 TYPE_GAME_ROTATION_VECTOR는 자북을 기반으로 하지 않습니다.

    새로운 TYPE_GYROSCOPE_UNCALIBRATEDTYPE_MAGNETIC_FIELD_UNCALIBRATED 센서는 소스 코드 없이 원시 센서 데이터를 편향 추정을 위한 고려사항입니다. 즉, 기존 TYPE_GYROSCOPETYPE_MAGNETIC_FIELD 센서는 자이로 드리프트와 강철에서 추정된 편향을 고려한 센서 데이터를 제공합니다. 각각 기기에서 생성됩니다. 반면에 새로운 '미보정' 상태는 이러한 센서의 버전은 대신 추출하고 추정된 편향 값을 별도로 제공합니다. 이러한 센서를 통해 로 예측 편향을 향상함으로써 센서 데이터에 대한 외부 데이터에 액세스할 수 있습니다.

    알림 리스너

    Android 4.3에는 시스템에서 게시하는 새 알림에 관한 정보를 앱이 수신할 수 있도록 새로운 서비스 클래스인 NotificationListenerService가 추가되었습니다.

    앱이 현재 접근성 서비스 API를 사용하여 시스템 알림에 액세스하는 경우, 이러한 API를 대신 사용하도록 앱을 업데이트해야 합니다.

    연락처 제공자

    'contactables' 쿼리

    새로운 연락처 제공자 쿼리 Contactables.CONTENT_URI를 사용하면 지정된 쿼리와 일치하는 모든 연락처에 속한 모든 이메일 주소와 전화번호가 포함된 하나의 Cursor를 효율적으로 가져올 수 있습니다.

    연락처 델타 쿼리

    연락처 데이터에 대한 최근 변경 사항을 효율적으로 쿼리할 수 있도록 연락처 제공자에 새 API를 추가했습니다. 이전에는 연락처 데이터의 무언가가 변경되면 앱에 알림을 받을 수 있었지만 정확히 무엇이 변경되었는지는 알지 못하므로 모든 연락처를 검색한 다음 반복하여 변경사항을 발견해야 했습니다.

    이제 삽입 및 업데이트의 변경사항을 추적하기 위해 선택 항목에 CONTACT_LAST_UPDATED_TIMESTAMP 매개변수를 포함하여 마지막으로 제공자를 쿼리한 후 변경된 연락처만 쿼리할 수 있습니다.

    삭제된 연락처를 추적하기 위해 새 테이블인 ContactsContract.DeletedContacts에서는 삭제된 연락처의 로그를 제공합니다 (하지만 삭제된 각 연락처는 이 표에 제한된 시간 동안 보관됨). CONTACT_LAST_UPDATED_TIMESTAMP와 마찬가지로 새로운 선택 매개변수인 CONTACT_DELETED_TIMESTAMP를 사용하여 마지막으로 제공업체를 쿼리한 후 삭제된 연락처를 확인할 수 있습니다. 이 표에는 로그가 보관될 일수 (밀리초)가 포함된 상수 DAYS_KEPT_MILLISECONDS도 포함되어 있습니다.

    또한 이제 연락처 제공자는 사용자가 CONTACTS_DATABASE_CREATED 작업을 브로드캐스트합니다. 시스템 설정 메뉴를 통해 주소록 저장소를 지워서 연락처 제공자 데이터베이스. 모든 연락을 중단해야 한다고 앱에 알리기 위한 것입니다. 새로운 검색어로 다시 로드할 수 있습니다.

    이러한 API를 사용하여 연락처 변경사항을 확인하는 샘플 코드는 ApiDemos 이 샘플은 SDK 샘플 다운로드에서 확인할 수 있습니다.

    현지화

    양방향 텍스트 지원 개선

    이전 버전의 Android는 오른쪽에서 왼쪽 (RTL) 언어 및 레이아웃을 지원합니다. 때로는 혼합 방향 텍스트를 제대로 처리하지 못할 때도 있습니다 따라서 Android 4.3에는 반대 방향으로 텍스트의 서식을 올바르게 지정할 수 있는 BidiFormatter API가 추가되었습니다. 그대로 유지한 채 망가지지 않도록 조심하세요.

    예를 들어 '이것을 찾으셨나요?'와 같은 문자열 변수로 문장을 만들려면 15 Bay Street, Laurel, CA?"의 경우 일반적으로 현지화된 문자열 리소스와 변수를 String.format():

    Kotlin

    val suggestion = String.format(resources.getString(R.string.did_you_mean), address)
    

    자바

    Resources res = getResources();
    String suggestion = String.format(res.getString(R.string.did_you_mean), address);
    

    그러나 언어가 히브리어인 경우 형식이 지정된 문자열은 다음과 같이 표시됩니다.

    האם התכוונת ל 15 Bay Street, Laurel, CA?

    '15'는 '베이 스트리트' 왼쪽에 있어야 합니다. 해결 방법은 BidiFormatterunicodeWrap() 메서드를 사용하는 것입니다. 예를 들어 위 코드는 다음과 같이 됩니다.

    Kotlin

    val bidiFormatter = BidiFormatter.getInstance()
    val suggestion = String.format(
            resources.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address)
    )
    

    자바

    Resources res = getResources();
    BidiFormatter bidiFormatter = BidiFormatter.getInstance();
    String suggestion = String.format(res.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address));
    

    기본적으로 unicodeWrap()는 다음을 사용합니다. 첫 번째 강력한 방향성 추정 휴리스틱이 텍스트 방향 신호가 콘텐츠 전체에 대한 적절한 방향을 나타내지 않습니다. 필요한 경우 TextDirectionHeuristicsTextDirectionHeuristic 상수 중 하나를 전달하여 다른 휴리스틱을 지정할 수 있습니다. unicodeWrap()에게 전송합니다.

    참고: 이 새 API는 이전 버전에서도 사용할 수 있습니다. Android 지원을 통한 Android의 라이브러리를 사용하며, BidiFormatter 클래스와 관련 API를 함께 사용합니다.

    접근성 서비스

    키 이벤트 처리

    이제 AccessibilityService가 콜백을 수신할 수 있습니다. onKeyEvent() 콜백 메서드를 사용하여 주요 입력 이벤트를 처리합니다. 이렇게 하면 접근성 서비스에서 키 기반 입력 장치를 구성하고 이러한 이벤트를 이전에는 터치 입력이나 기기의 방향 패드로만 가능할 수 있었습니다.

    텍스트 선택 및 복사/붙여넣기

    이제 AccessibilityNodeInfo는 다음을 허용하는 API를 제공합니다. 선택, 잘라내기, 복사, 붙여넣기를 위한 AccessibilityService 읽을 수 있습니다

    접근성 서비스에서 잘라내거나 복사할 텍스트 선택을 지정하려면 새 작업, ACTION_SET_SELECTION, 전달 선택 시작 및 종료 위치가 ACTION_ARGUMENT_SELECTION_START_INTACTION_ARGUMENT_SELECTION_END_INT로 지정되어 있습니다. 또는 기존 작업, ACTION_NEXT_AT_MOVEMENT_GRANULARITY (이전에는 커서 위치 이동에만 사용) ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN 인수를 추가합니다.

    그런 다음 ACTION_CUT로 잘라내거나 복사할 수 있습니다. ACTION_COPY을 선택한 다음 나중에 ACTION_PASTE입니다.

    참고: 이 새 API는 이전 버전에서도 사용할 수 있습니다. Android 지원을 통한 Android의 라이브러리, AccessibilityNodeInfoCompat 포함 클래스에 대해 자세히 알아보세요.

    접근성 기능 선언

    Android 4.3부터 접근성 서비스는 접근성 기능을 선언해야 함 를 메타데이터 파일에 포함해야 합니다. 기능이 사용 설정되지 않은 경우 요청된 경우 기능이 작동하지 않습니다. 서비스의 사용하려면 다양한 지원 도구에 해당하는 XML 속성을 'capability' AccessibilityServiceInfo의 상수 클래스에 대해 자세히 알아보세요.

    예를 들어 서비스가 flagRequestFilterKeyEvents 기능을 요청하지 않는 경우 키 이벤트를 수신하지 않습니다

    테스트 및 디버깅

    자동화된 UI 테스트

    UiAutomation 클래스는 사용자를 시뮬레이션할 수 있는 API를 제공합니다. 테스트 자동화를 위한 작업 플랫폼의 AccessibilityService API를 사용하면 UiAutomation가 API를 사용하면 화면 콘텐츠를 검사하고 임의의 키보드와 터치 이벤트를 삽입할 수 있습니다.

    UiAutomation의 인스턴스를 가져오려면 Instrumentation.getUiAutomation()를 호출합니다. 순서 이 작업을 수행하려면 instrument 명령어와 함께 -w 옵션을 제공해야 합니다. adb shell에서 InstrumentationTestCase 실행 시

    UiAutomation 인스턴스를 사용하면 임의의 이벤트를 실행하여 테스트할 수 있습니다. executeAndWaitForEvent()를 호출하고 실행할 Runnable, 제한 시간을 전달하여 앱을 호출합니다. 기간과 UiAutomation.AccessibilityEventFilter 인터페이스의 구현을 지정해야 합니다. UiAutomation.AccessibilityEventFilter 구현 내에서 전화를 받습니다. 관심 있는 이벤트를 필터링하고, '실패'에 포함됩니다

    테스트 중에 모든 이벤트를 관찰하려면 UiAutomation.OnAccessibilityEventListener 구현을 만들어 setOnAccessibilityEventListener()에 전달합니다. 그러면 리스너 인터페이스에서 onAccessibilityEvent() 호출을 수신합니다. 이벤트가 발생할 때마다 AccessibilityEvent 객체를 수신합니다. 이벤트를 설명합니다.

    UiAutomation API가 노출하는 다른 다양한 작업이 있습니다. uiautomator와 같은 UI 테스트 도구의 개발을 장려하기 위해 매우 낮은 수준에서 구현했습니다. 예를 들면 다음과 같습니다. UiAutomation에서 다음 작업도 할 수 있습니다.

    • 입력 이벤트 삽입
    • 화면 방향 변경
    • 스크린샷 찍기

    그리고 가장 중요하게는 UI 테스트 도구의 경우 UiAutomation API가 애플리케이션 경계를 넘어 Instrumentation

    앱의 Systrace 이벤트

    Android 4.3은 두 개의 정적 메서드가 있는 Trace 클래스를 추가합니다. beginSection()님 및 endSection()님, systrace 보고서에 포함할 코드 블록을 정의할 수 있습니다. 생성 추적 가능한 코드 섹션을 확인하려 할 때 systrace 로그는 앱 내에서 속도 저하가 발생하는 지점 분석

    Systrace 도구 사용에 관한 자세한 내용은 Systrace로 디스플레이 및 성능 분석을 참고하세요.

    보안

    앱-비공개 키용 Android 키 저장소

    이제 Android는 KeyStore에서 맞춤 Java 보안 프로바이더를 제공합니다. 기능을 제공합니다. 이 기능을 사용하면 내 앱에서만 보고 사용할 수 있습니다. Android 키 저장소를 로드하려면 다음을 전달합니다. "AndroidKeyStore"에서 KeyStore.getInstance()(으)로

    Android Key Store에서 앱의 비공개 사용자 인증 정보를 관리하려면 다음을 사용하여 새 키를 생성합니다. KeyPairGeneratorSpec에서 KeyPairGenerator 첫 페이지 getInstance()를 호출하여 KeyPairGenerator의 인스턴스를 가져옵니다. 그런 다음 initialize(): KeyPairGeneratorSpecKeyPairGeneratorSpec.Builder입니다. 마지막으로 generateKeyPair()를 호출하여 KeyPair를 가져옵니다.

    하드웨어 사용자 인증 정보 저장소

    이제 Android에서 KeyChain의 하드웨어 지원 저장소도 지원합니다. 키를 추출할 수 없게 하여 보안을 강화합니다. 즉, 한 번 키는 하드웨어 지원 키 저장소 (Secure Element, TPM 또는 TrustZone)에 저장되며 내보내기 작업을 수행하지만 비공개 키 자료는 내보낼 수 없습니다. OS 커널도 에서 이 키 자료에 액세스할 수 없습니다. 일부 Android 지원 기기는 런타임 시 다음을 호출하여 하드웨어 지원 저장소를 사용할 수 있는지 확인할 수 있습니다. KeyChain.IsBoundKeyAlgorithm()

    매니페스트 선언

    선언이 필요한 기능

    이제 <uses-feature>에서 다음 값이 지원됩니다. 요소를 사용하여 해당 기능을 제공하는 기기에만 앱이 설치되도록 할 수 있습니다. 확인할 수 있습니다

    FEATURE_APP_WIDGETS
    앱이 앱 위젯을 제공하며 다음 조건을 충족하는 기기에만 설치되어야 한다고 선언합니다. 홈 화면 또는 사용자가 앱 위젯을 삽입할 수 있는 유사한 위치를 포함해야 합니다. 예:
    <uses-feature android:name="android.software.app_widgets" android:required="true" />
    
    FEATURE_HOME_SCREEN
    앱이 홈 화면 대체 기능으로 작동하며 다음 기기에만 설치되어야 한다고 선언합니다. 서드 파티 홈 화면 앱을 지원하는 기기 예:
    <uses-feature android:name="android.software.home_screen" android:required="true" />
    
    FEATURE_INPUT_METHODS
    앱이 맞춤 입력 방법 (InputMethodService로 빌드된 키보드)을 제공하며 다음 조건을 충족하는 기기에만 설치되어야 한다고 선언합니다. 서드 파티 입력 방법 지원 예:
    <uses-feature android:name="android.software.input_methods" android:required="true" />
    
    FEATURE_BLUETOOTH_LE
    앱이 저전력 블루투스 API를 사용하며 기기에만 설치해야 한다고 선언합니다. 블루투스 저전력 블루투스를 통해 다른 장치와 통신할 수 있는 장치입니다. 예:
    <uses-feature android:name="android.software.bluetooth_le" android:required="true" />
    

    사용자 권한

    이제 <uses-permission>에서 다음 값이 지원됩니다. kubectl run 명령어를 사용하여 권한을 부여할 수 있습니다.

    BIND_NOTIFICATION_LISTENER_SERVICE
    NotificationListenerService API를 사용하는 데 필요합니다.
    SEND_RESPOND_VIA_MESSAGE
    ACTION_RESPOND_VIA_MESSAGE을(를) 받는 데 필요합니다. 인텐트를 지정할 수 있습니다.

    Android 4.3의 모든 API 변경사항을 자세히 보려면 다음을 참조하세요. API 차이점 보고서를 참고하세요.