사용자는 이모티콘, 스티커 등 풍부한 정보를 사용하여 소통하고 싶어 하는 경우가 많습니다. 있습니다. 이전 버전의 Android에서는 소프트 키보드(또는 입력 방식 편집기(IME) 또는 IME—유니코드 그림 이모티콘만 앱에 보낼 수 있음 풍부한 콘텐츠를 위한 앱 다른 앱에서 사용할 수 없거나 간단한 공유 작업을 통해 이미지 전송 클립보드로 이동할 수 있습니다.
![이미지 검색을 지원하는 키보드를 보여주는 이미지](https://developer.android.com/static/images/guide/topics/text/image-keyboard-sample.png?hl=ko)
Android 7.1 (API 수준 25)부터 Android SDK에 커밋이 포함되어 있습니다. Content API: IME가 이미지 및 기타 멀티미디어 콘텐츠를 전송하는 보편적인 방법을 앱의 텍스트 편집기에 직접 전달할 수 있습니다. API는 다음에서도 사용할 수 있습니다. 버전 25.0.0부터 v13 지원 라이브러리만 지원합니다. 지원팀을 사용하는 것이 좋습니다. 구현을 간소화하는 도우미 메서드가 포함되어 있으므로 라이브러리입니다.
이 API를 사용하면 모든 애플리케이션에서 리치 콘텐츠를 허용하는 메시지 앱을 빌드할 수 있습니다. 앱에 리치 콘텐츠를 보낼 수 있는 키보드도 포함됩니다. Google 키보드 메시지 Google 그림 1과 같이 Android 7.1에서 Commit Content API를 지원해야 합니다.
이 문서에서는 IME 및 있습니다.
작동 방식
키보드 이미지 삽입을 사용하려면 IME 및 앱의 참여가 필요합니다. 이 다음 시퀀스는 이미지 삽입 프로세스의 각 단계를 설명합니다.
사용자가
EditText
를 탭하면 편집기가EditorInfo.contentMimeTypes
IME는 지원되는 유형 목록을 읽고 편집기가 허용할 수 있는 소프트 키보드의 콘텐츠를 표시합니다.
사용자가 이미지를 선택하면 IME가
commitContent()
드림 를 전송하며InputContentInfo
수정하겠습니다commitContent()
호출은commitText()
호출은 리치 콘텐츠를 사용할 수 있습니다.InputContentInfo
에는 다음과 같은 URI가 포함됩니다. 콘텐츠에서 콘텐츠를 식별하는 provider로 이동합니다.
이 프로세스는 그림 2에 묘사되어 있습니다.
![애플리케이션에서 IME로, 다시 애플리케이션으로 이어지는 시퀀스를 보여주는 이미지](https://developer.android.com/static/images/guide/topics/text/image-keyboard-diagram.png?hl=ko)
앱에 이미지 지원 추가
IME의 리치 콘텐츠를 허용하려면 앱에서 콘텐츠 유형을 IME에 알려야 합니다.
콘텐츠를 수신할 때 실행되는 콜백 메서드를 수락하고 지정합니다.
다음 예는 PNG를 허용하는 EditText
를 만드는 방법을 보여줍니다.
이미지:
Kotlin
var editText: EditText = object : EditText(this) { override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection { var ic = super.onCreateInputConnection(outAttrs) EditorInfoCompat.setContentMimeTypes(outAttrs, arrayOf("image/png")) val mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this) if (mimeTypes != null) { EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes) ic = InputConnectionCompat.createWrapper(this, ic, outAttrs) } return ic } }
자바
EditText editText = new EditText(this) { @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { InputConnection ic = super.onCreateInputConnection(outAttrs); EditorInfoCompat.setContentMimeTypes(outAttrs, new String[]{"image/png"}); String[] mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this); if (mimeTypes != null) { EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes); ic = InputConnectionCompat.createWrapper(this, ic, outAttrs); } return ic; } };
자세한 설명은 다음과 같습니다.
이 예에서는 지원 라이브러리를 사용하므로
android.support.v13.view.inputmethod
드림 를android.view.inputmethod
이 예에서는
EditText
를 만들고onCreateInputConnection(EditorInfo)
메서드를 사용하여InputConnection
입니다.InputConnection
는 IME와 알림을 받는다는 것을 의미합니다.호출
super.onCreateInputConnection()
드림 기본 제공 동작(텍스트 발신 및 수신)을 유지하고 그러면InputConnection
에 대한 참조가 제공됩니다.setContentMimeTypes()
드림 는 지원되는 MIME 유형 목록을EditorInfo
전화걸기setContentMimeTypes()
이전super.onCreateInputConnection()
입니다.callback
은 IME가 콘텐츠를 커밋할 때마다 실행됩니다. 메서드onCommitContent()
드림 은(는) 다음에 대한 참조입니다.InputContentInfoCompat
, 콘텐츠 URI가 들어 있습니다.- 앱이 API 수준 25에서 실행되는 경우 권한 요청 및 해제
이상 및
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
드림 플래그는 IME에서 설정합니다. 그렇지 않으면 이미 콘텐츠에 대한 액세스 권한이 있습니다. URI가 IME에 의해 부여되었거나 콘텐츠 제공자가 액세스를 제한하지 않습니다. 자세한 내용은 다음에 이미지 지원 추가를 참조하세요. IME를 사용합니다.
- 앱이 API 수준 25에서 실행되는 경우 권한 요청 및 해제
이상 및
createWrapper()
드림InputConnection
, 수정된EditorInfo
, 콜백을 래핑합니다. 새InputConnection
로 가져오고 반환합니다.
권장사항은 다음과 같습니다.
리치 콘텐츠를 지원하지 않는 편집자는 호출하지 않습니다.
setContentMimeTypes()
이며EditorInfo.contentMimeTypes
세트를 그대로 둡니다.null
님에게 보냅니다.InputContentInfo
에 지정된 MIME 유형이 있으면 편집자가 콘텐츠를 무시합니다. 허용되는 유형과 일치하지 않습니다.리치 콘텐츠는 텍스트 위치에 영향을 주지 않으며 영향을 받지도 않습니다. 커서를 올려놓습니다. 편집기는 콘텐츠를 사용할 때 커서 위치를 무시할 수 있습니다.
편집기의
OnCommitContentListener.onCommitContent()
메서드를 사용하여 비동기식으로true
를 반환할 수도 있고 콘텐츠를 로드하기 전에 확인할 수 있습니다커밋되기 전에 IME에서 수정할 수 있는 텍스트와 달리 풍부한 커밋 즉시 커밋됩니다. 사용자가 파일을 수정하거나 삭제할 수 있게 하려는 경우 로직을 직접 구현해야 합니다.
앱을 테스트하려면 기기나 에뮬레이터에 키보드가 내장되어 있어야 합니다. 있습니다. Android 7.1 이상에서 Google 키보드를 사용할 수 있습니다.
IME에 이미지 지원 추가
앱에 리치 콘텐츠를 전송하려는 IME는 커밋 콘텐츠를 구현해야 합니다. API를 사용할 수 있습니다.
- 재정의
onStartInput()
또는onStartInputView()
하고 타겟에서 지원되는 콘텐츠 유형 목록을 읽습니다. 있습니다 다음 코드 스니펫은 타겟 편집기에서 GIF 이미지를 허용하는지 확인하는 방법을 보여줍니다.
Kotlin
override fun onStartInputView(editorInfo: EditorInfo, restarting: Boolean) { val mimeTypes: Array<String> = EditorInfoCompat.getContentMimeTypes(editorInfo) val gifSupported: Boolean = mimeTypes.any { ClipDescription.compareMimeTypes(it, "image/gif") } if (gifSupported) { // The target editor supports GIFs. Enable the corresponding content. } else { // The target editor doesn't support GIFs. Disable the corresponding // content. } }
자바
@Override public void onStartInputView(EditorInfo info, boolean restarting) { String[] mimeTypes = EditorInfoCompat.getContentMimeTypes(editorInfo); boolean gifSupported = false; for (String mimeType : mimeTypes) { if (ClipDescription.compareMimeTypes(mimeType, "image/gif")) { gifSupported = true; } } if (gifSupported) { // The target editor supports GIFs. Enable the corresponding content. } else { // The target editor doesn't support GIFs. Disable the corresponding // content. } }
- 사용자가 이미지를 선택하면 앱에 콘텐츠를 커밋합니다. 통화 지양
commitContent()
작성 중인 텍스트가 있는 경우 편집기가 포커스를 잃을 수 있습니다. 다음 코드 스니펫은 GIF 이미지를 커밋할 수 있습니다.
Kotlin
// Commits a GIF image. // @param contentUri = Content URI of the GIF image to be sent. // @param imageDescription = Description of the GIF image to be sent. fun commitGifImage(contentUri: Uri, imageDescription: String) { val inputContentInfo = InputContentInfoCompat( contentUri, ClipDescription(imageDescription, arrayOf("image/gif")), null ) val inputConnection = currentInputConnection val editorInfo = currentInputEditorInfo var flags = 0 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { flags = flags or InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION } InputConnectionCompat.commitContent(inputConnection, editorInfo, inputContentInfo, flags, null) }
자바
// Commits a GIF image. // @param contentUri = Content URI of the GIF image to be sent. // @param imageDescription = Description of the GIF image to be sent. public static void commitGifImage(Uri contentUri, String imageDescription) { InputContentInfoCompat inputContentInfo = new InputContentInfoCompat( contentUri, new ClipDescription(imageDescription, new String[]{"image/gif"}), null ); InputConnection inputConnection = getCurrentInputConnection(); EditorInfo editorInfo = getCurrentInputEditorInfo(); Int flags = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { flags |= InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION; } InputConnectionCompat.commitContent( inputConnection, editorInfo, inputContentInfo, flags, null); }
IME 작성자로서 개발자는 자체 콘텐츠 제공자를 구현하여
콘텐츠 URI 요청에 응답합니다. IME가 콘텐츠를 지원하는 경우는 예외입니다.
기존 콘텐츠 제공업체로부터
MediaStore
자세한 내용은
자세한 내용은
provider 및 file
provider 문서를 참조하세요.
자체 콘텐츠 제공업체를 빌드하는 경우 내보내지 않는 것이 좋습니다.
설정
android:exported
(으)로
false
입니다. 대신 다음을 설정하여 제공자의 권한 부여를 사용 설정하세요.
android:grantUriPermission
드림
true
에게. 그러면 콘텐츠가 커밋될 때 IME에서 콘텐츠 URI 액세스 권한을 부여할 수 있습니다. 다음과 같은 두 가지 방법이 있습니다.
Android 7.1 (API 수준 25) 이상에서
commitContent()
호출 시 플래그 매개변수를INPUT_CONTENT_GRANT_READ_URI_PERMISSION
그러면 앱이 수신하는InputContentInfo
객체가 요청 및 다음을 호출하여 임시 읽기 권한을 해제합니다.requestPermission()
및releasePermission()
입니다.Android 7.0 (API 수준 24) 이하에서는
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
가 무시되므로 수동으로 부여합니다. 콘텐츠에 대한 권한을 부여하지 않습니다. 이를 위한 한 가지 방법은grantUriPermission()
를 지원하지만 개발자가 직접 실행할 내 요구사항에 맞게 맞춤설정할 수 있습니다
IME를 테스트하려면 기기나 에뮬레이터에 있습니다. Google 메신저 앱은 Android 7.1 이상에서 사용할 수 있습니다.