Android는 복사하여 붙여넣기를 지원하는 강력한 클립보드 기반 프레임워크를 제공합니다. Kubernetes는 단순한 텍스트 문자열, 복잡한 데이터 구조, 텍스트 및 바이너리 스트림을 비롯한 복잡한 데이터 유형 애플리케이션 애셋 등이 있습니다 복잡한 반면 간단한 텍스트 데이터는 클립보드에 직접 저장됩니다. 데이터는 붙여넣기 애플리케이션이 콘텐츠 제공자로 확인하는 참조로 저장됩니다. 복사 중 붙여넣기는 애플리케이션 내에서 그리고 프레임워크입니다
프레임워크의 일부분에서 콘텐츠 제공자를 사용하므로 이 문서에서는 Android Content Provider API에 대한 자세한 내용은 콘텐츠 제공자.
사용자는 콘텐츠를 클립보드에 복사할 때 피드백을 기대하므로 복사하여 붙여넣기 지원, Android는 Android 13 (API 수준 33)에서 복사할 때 사용자에게 기본 UI를 표시합니다. 및 그 이상입니다. 이 기능으로 인해 알림이 중복될 위험이 있습니다. GNI의 웹사이트인 g.co/newsinitiative에서 이 에지 케이스의 중복 알림 피하기 섹션으로 이동합니다.
Android 12L (API 수준 32) 이하에서 복사할 때 사용자에게 수동으로 의견을 제공합니다. 자세한 내용은 권장사항에 대해 자세히 알아보세요.
클립보드 프레임워크
클립보드 프레임워크를 사용할 때는 데이터를 클립 객체에 넣고 클립 객체를 배치합니다. 복사해 보겠습니다. 클립 객체는 다음 세 가지 형식 중 하나일 수 있습니다.
- 텍스트
- 텍스트 문자열입니다. 문자열을 클립 객체에 직접 넣은 다음 클립보드로 이동합니다. 문자열을 붙여넣으려면 클립보드에서 클립 객체를 가져와 문자열도 마찬가지입니다.
- URI
-
모든 객체를 나타내는
Uri
객체 URI 형태입니다. 주로 콘텐츠 제공업체의 복잡한 데이터를 복사하기 위한 것입니다. 복사하기Uri
객체를 클립 객체에 넣고 클립 객체를 클립보드로 이동합니다. 데이터를 붙여넣으려면 클립 객체와Uri
객체를 가져옵니다. 이를 콘텐츠 제공자와 같은 데이터 소스로 변환하고 애플리케이션의 스토리지로 가져올 수 있습니다 - 인텐트
Intent
입니다. 이 애플리케이션 바로 가기 복사를 지원합니다. 데이터를 복사하려면Intent
을 만들고 다음을 실행합니다. 클립 객체를 클립보드에 배치하고 클립 객체를 클립보드에 배치합니다. 데이터를 붙여넣으려면 그런 다음Intent
객체를 애플리케이션의 메모리 영역입니다.
클립보드는 한 번에 클립 객체 하나만 보유합니다. 애플리케이션이 이전 클립 객체가 사라집니다.
사용자가 애플리케이션에 데이터를 붙여넣을 수 있게 하려면 데이터를 수집하는 데 사용됩니다 클립보드의 데이터를 검사한 후 사용자에게 붙여넣기 옵션을 제공할 수 있습니다. 클립 객체에는 특정 데이터 형식 외에도 어떤 MIME 형식을 사용할 수 있습니다 이 메타데이터는 애플리케이션이 유용한 작업을 수행할 수 있는지 여부를 판단하는 데 도움이 됩니다. 클립보드 데이터로 교체할 수 있습니다. 예를 들어 텍스트를 주로 처리하는 애플리케이션이 있는 경우 URI 또는 인텐트가 포함된 클립 객체를 무시하는 것이 좋습니다.
클립보드의 데이터 형식에 관계없이 사용자가 텍스트를 붙여넣도록 할 수도 있습니다. 받는사람 클립보드 데이터를 텍스트 표현으로 강제 변환한 다음 이 텍스트를 붙여넣습니다. 이것은 클립보드를 텍스트로 강제 변환 섹션에 설명되어 있습니다.
클립보드 클래스
이 섹션에서는 클립보드 프레임워크에서 사용하는 클래스를 설명합니다.
ClipboardManager
Android 시스템 클립보드는 전역
ClipboardManager
클래스.
이 클래스를 직접 인스턴스화하지 마세요. 대신
getSystemService(CLIPBOARD_SERVICE)
ClipData, ClipData.Item, ClipDescription
클립보드에 데이터를 추가하려면
다음을 포함하는 ClipData
객체
데이터 자체에 대한 설명이 있습니다. 클립보드에는 한 지점에 ClipData
가 하나 있습니다.
있습니다. ClipData
에는
객체 ClipDescription
개
및 1개 이상
ClipData.Item
객체
ClipDescription
객체에는 클립에 관한 메타데이터가 포함됩니다. 특히
- 클립 데이터에 사용할 수 있는 MIME 유형의 배열을 포함합니다. 또한
Android 12 (API 수준 31) 이상에서는 메타데이터에 객체가
포함
스타일 지정 텍스트와
객체의 텍스트 유형입니다.
클립보드에 클립을 넣으면 이 정보를 붙여넣기 애플리케이션에서 사용할 수 있습니다.
클립 데이터를 처리할 수 있는지 여부를 검토할 수 있습니다.
ClipData.Item
객체에는 텍스트, URI 또는 인텐트 데이터가 포함됩니다.
- 텍스트
CharSequence
입니다.- URI
Uri
입니다. 모든 URI가 허용됩니다. 데이터를 제공하는 애플리케이션은 URI를 클립보드에 배치합니다. 애플리케이션 클립보드에서 URI를 가져와서 이를 사용하여 콘텐츠에 액세스합니다. 데이터를 가져올 수 있습니다.- 인텐트
Intent
입니다. 이 데이터 유형을 사용하면 애플리케이션 바로가기를 클립보드로 이동합니다. 그러면 사용자가 바로가기를 애플리케이션에 붙여넣어 나중에 사용할 수 있습니다.
클립에 ClipData.Item
객체를 두 개 이상 추가할 수 있습니다. 이렇게 하면 사용자가
여러 선택 항목을 단일 클립으로 붙여넣습니다. 예를 들어 사용자가
한 번에 두 개 이상의 항목을 선택하는 경우 모든 항목을 한 번에 클립보드에 복사할 수 있습니다. 해야 할 일
각 목록 항목에 별도의 ClipData.Item
를 만든 다음
ClipData.Item
객체를 ClipData
객체에 추가합니다.
ClipData 편의 메서드
ClipData
클래스는
ClipData
하나의 ClipData.Item
객체와 간단한
ClipDescription
객체:
-
newPlainText(label, text)
- 단일
ClipData.Item
객체가 있는ClipData
객체를 반환합니다. 텍스트 문자열을 포함합니다.ClipDescription
객체의 라벨은 다음과 같이 설정됩니다.label
ClipDescription
의 단일 MIME 유형은MIMETYPE_TEXT_PLAIN
입니다.newPlainText()
를 사용하여 텍스트 문자열에서 클립을 만듭니다. -
newUri(resolver, label, URI)
- 단일
ClipData.Item
객체가 있는ClipData
객체를 반환합니다. URI를 포함합니다.ClipDescription
객체의 라벨은 다음과 같이 설정됩니다.label
URI가 콘텐츠 URI인 경우, 즉Uri.getScheme()
content:
를 반환합니다. 이 메서드는 <ph type="x-smartling-placeholder">ContentResolver
</ph> 객체를resolver
에서 제공하여 있습니다. 그런 다음ClipDescription
에 저장합니다. 구성되지 않은 URI의 경우content:
URI인 경우 메서드는 MIME 유형을 다음과 같이 설정합니다.MIMETYPE_TEXT_URILIST
newUri()
를 사용하여 URI, 특히content:
URI -
newIntent(label, intent)
- 단일
ClipData.Item
객체가 있는ClipData
객체를 반환합니다.Intent
를 포함합니다.ClipDescription
객체의 라벨은 다음과 같이 설정됩니다.label
MIME 유형은 다음과 같이 설정됩니다.MIMETYPE_TEXT_INTENT
newIntent()
를 사용하여Intent
객체에서 클립을 만듭니다.
클립보드 데이터를 텍스트로 강제 변환
애플리케이션이 텍스트만 처리하더라도
인코더로 전달하여
ClipData.Item.coerceToText()
메서드를 사용하여 축소하도록 요청합니다.
이 메서드는 ClipData.Item
의 데이터를 텍스트로 변환하고
CharSequence
ClipData.Item.coerceToText()
가 반환하는 값은
ClipData.Item
:
- 텍스트
-
ClipData.Item
가 텍스트인 경우, 즉 <ph type="x-smartling-placeholder">getText()
</ph> null이 아니면 coerceToText()가 텍스트를 반환합니다. - URI
-
ClipData.Item
가 URI인 경우, 즉 <ph type="x-smartling-placeholder">getUri()
</ph> 이(가) null이 아니면coerceToText()
가 콘텐츠 URI로 사용하려고 합니다.- URI가 콘텐츠 URI이고 제공자가 텍스트 스트림을 반환할 수 있다면,
coerceToText()
는 텍스트 스트림을 반환합니다. - URI가 콘텐츠 URI이지만 제공자가 텍스트 스트림을 제공하지 않는다면,
coerceToText()
는 URI의 표현을 반환합니다. 표현은 다음과 같습니다. 로 반환한 것과 동일Uri.toString()
- URI가 콘텐츠 URI가 아니라면
coerceToText()
는 있습니다. 표시는Uri.toString()
- URI가 콘텐츠 URI이고 제공자가 텍스트 스트림을 반환할 수 있다면,
- 인텐트
ClipData.Item
이Intent
이면getIntent()
null이 아닌 경우:coerceToText()
가 인텐트 URI로 변환하여 반환합니다. 표시는Intent.toUri(URI_INTENT_SCHEME)
클립보드 프레임워크는 그림 2에 요약되어 있습니다. 데이터를 복사하기 위해 애플리케이션은
ClipboardManager
전역 클립보드의 ClipData
객체 이
ClipData
에는 하나 이상의 ClipData.Item
객체와 하나가 포함되어 있습니다.
ClipDescription
객체 데이터를 붙여넣기 위해 애플리케이션은 ClipData
를 가져옵니다.
MIME 유형을 ClipDescription
에서 가져오고,
ClipData.Item
또는
ClipData.Item
입니다.
클립보드에 복사
데이터를 클립보드에 복사하려면 전역 ClipboardManager
객체의 핸들을 가져옵니다.
ClipData
객체를 만들고 ClipDescription
및 하나 이상을 추가합니다.
ClipData.Item
객체를 반환합니다. 그런 다음 완료된 ClipData
객체를
ClipboardManager
객체. 이 내용은 다음 절차에 자세히 설명되어 있습니다.
- 콘텐츠 URI를 사용하여 데이터를 복사하려면 콘텐츠 제공업체를 설정하세요.
- 시스템 클립보드 가져오기:
Kotlin
when(menuItem.itemId) { ... R.id.menu_copy -> { // if the user selects copy // Gets a handle to the clipboard service. val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager } }
자바
... // If the user selects copy. case R.id.menu_copy: // Gets a handle to the clipboard service. ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
-
새로운
ClipData
객체로 데이터 복사하기-
텍스트
Kotlin
// Creates a new text clip to put on the clipboard. val clip: ClipData = ClipData.newPlainText("simple text", "Hello, World!")
자바
// Creates a new text clip to put on the clipboard. ClipData clip = ClipData.newPlainText("simple text", "Hello, World!");
-
URI의 경우
이 스니펫은 레코드의 콘텐츠 URI에 레코드 ID를 인코딩하여 지정할 수 있습니다 이 기법에 대해서는 URI에 식별자 인코딩 섹션
Kotlin
// Creates a Uri using a base Uri and a record ID based on the contact's last // name. Declares the base URI string. const val CONTACTS = "content://com.example.contacts" // Declares a path string for URIs, used to copy data. const val COPY_PATH = "/copy" // Declares the Uri to paste to the clipboard. val copyUri: Uri = Uri.parse("$CONTACTS$COPY_PATH/$lastName") ... // Creates a new URI clip object. The system uses the anonymous // getContentResolver() object to get MIME types from provider. The clip object's // label is "URI", and its data is the Uri previously created. val clip: ClipData = ClipData.newUri(contentResolver, "URI", copyUri)
자바
// Creates a Uri using a base Uri and a record ID based on the contact's last // name. Declares the base URI string. private static final String CONTACTS = "content://com.example.contacts"; // Declares a path string for URIs, used to copy data. private static final String COPY_PATH = "/copy"; // Declares the Uri to paste to the clipboard. Uri copyUri = Uri.parse(CONTACTS + COPY_PATH + "/" + lastName); ... // Creates a new URI clip object. The system uses the anonymous // getContentResolver() object to get MIME types from provider. The clip object's // label is "URI", and its data is the Uri previously created. ClipData clip = ClipData.newUri(getContentResolver(), "URI", copyUri);
-
인텐트의 경우
이 스니펫은 애플리케이션의
Intent
를 구성한 다음 클립 객체에서 설정하면 됩니다.Kotlin
// Creates the Intent. val appIntent = Intent(this, com.example.demo.myapplication::class.java) ... // Creates a clip object with the Intent in it. Its label is "Intent" // and its data is the Intent object created previously. val clip: ClipData = ClipData.newIntent("Intent", appIntent)
자바
// Creates the Intent. Intent appIntent = new Intent(this, com.example.demo.myapplication.class); ... // Creates a clip object with the Intent in it. Its label is "Intent" // and its data is the Intent object created previously. ClipData clip = ClipData.newIntent("Intent", appIntent);
-
텍스트
- 새로운 클립 객체를 클립보드에 배치합니다.
Kotlin
// Set the clipboard's primary clip. clipboard.setPrimaryClip(clip)
자바
// Set the clipboard's primary clip. clipboard.setPrimaryClip(clip);
클립보드에 복사할 때 의견 보내기
사용자는 앱이 클립보드에 콘텐츠를 복사할 때 시각적 피드백을 기대합니다. 완료되었습니다. Android 13 이상에서 사용자에게 자동으로 적용되지만 이전 버전에서는 수동으로 구현해야 합니다. 제공합니다
Android 13부터 시스템에서 콘텐츠가 추가될 때 표준 시각적 확인 메시지를 표시합니다. 클립보드에 복사됩니다. 새 확인 메시지를 통해 다음 작업이 실행됩니다.
- 콘텐츠가 복사되었는지 확인합니다.
- 복사된 콘텐츠의 미리보기를 제공합니다.
Android 12L (API 수준 32) 이하에서는 사용자가 성공적으로 복사되었는지 확실하지 않을 수 있습니다. 복사된 콘텐츠 등이 있습니다 이 기능은 알림을 받은 후 앱에서 복사하기 때문에 사용자가 클립보드를 더 세부적으로 제어할 수 있습니다.
중복 알림 피하기
Android 12L (API 수준 32) 이하에서는 복사에 성공하면 사용자에게 알리는 것이 좋습니다.
Toast
같은 위젯을 사용하여 시각적 인앱 피드백을 제공하거나
복사 후 Snackbar
정보가 중복으로 표시되지 않도록 하려면 토스트 메시지를 삭제하는 것이 좋습니다. 또는 스낵바에 표시되지 않을 수 있습니다.
를 통해 개인정보처리방침을 정의할 수 있습니다. <ph type="x-smartling-placeholder">다음은 이를 구현하는 방법의 예입니다.
fun textCopyThenPost(textCopied:String) { val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager // When setting the clipboard text. clipboardManager.setPrimaryClip(ClipData.newPlainText ("", textCopied)) // Only show a toast for Android 12 and lower. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) Toast.makeText(context, “Copied”, Toast.LENGTH_SHORT).show() }
클립보드에 민감한 콘텐츠 추가
앱에서 사용자가 비밀번호나 크레딧과 같은 민감한 콘텐츠를 클립보드에 복사할 수 있는지 여부
ClipData
의 ClipDescription
에 플래그를 추가해야 합니다.
ClipboardManager.setPrimaryClip()
를 호출하기 전에 확인할 수 있습니다. 이 플래그를 추가하면 민감한 정보를
Android 13 이상에서 복사된 콘텐츠의 시각적 확인에 콘텐츠가 표시되지 않습니다.
민감한 콘텐츠를 신고하려면 ClipDescription
에 불리언 추가 항목을 추가하세요. 모든 앱이 해야 할 일
대상 API 수준과 관계없이 이 API 키를
사용하는 것이 좋습니다
// If your app is compiled with the API level 33 SDK or higher. clipData.apply { description.extras = PersistableBundle().apply { putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true) } } // If your app is compiled with a lower SDK. clipData.apply { description.extras = PersistableBundle().apply { putBoolean("android.content.extra.IS_SENSITIVE", true) } }
클립보드에서 붙여넣기
앞서 설명한 대로 전역 클립보드 객체를 가져와서 클립보드에서 데이터를 붙여넣습니다. 클립 객체 가져오기, 데이터 보기, 가능한 경우 클립 객체에서 데이터 복사 배포할 수 있습니다 이 섹션에서는 세 가지 클립보드 형식을 붙여넣는 방법을 자세히 설명합니다. 데이터를 수집하는 데 사용됩니다
<ph type="x-smartling-placeholder">일반 텍스트 붙여넣기
일반 텍스트를 붙여넣으려면 전역 클립보드를 가져와서 일반 텍스트를 반환할 수 있는지 확인합니다. 그런 다음
클립 객체를 빌드하고 이 문서에 설명된 대로 getText()
를 사용하여 자체 저장소에 텍스트를 복사합니다.
다음 절차를 따르세요.
- 다음을 사용하여 전역
ClipboardManager
객체 가져오기getSystemService(CLIPBOARD_SERVICE)
또한 포함할 전역 변수를 선언합니다. 붙여넣은 텍스트:Kotlin
var clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager var pasteData: String = ""
자바
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String pasteData = "";
- '붙여넣기'를 사용 또는 사용 중지해야 하는지 확인 옵션을
있습니다. 클립보드에 클립이 포함되어 있으며 데이터 유형을 처리할 수 있는지 확인하세요.
는 클립으로 표현됩니다.
Kotlin
// Gets the ID of the "paste" menu item. val pasteItem: MenuItem = menu.findItem(R.id.menu_paste) // If the clipboard doesn't contain data, disable the paste menu item. // If it does contain data, decide whether you can handle the data. pasteItem.isEnabled = when { !clipboard.hasPrimaryClip() -> { false } !(clipboard.primaryClipDescription.hasMimeType(MIMETYPE_TEXT_PLAIN)) -> { // Disables the paste menu item, since the clipboard has data but it // isn't plain text. false } else -> { // Enables the paste menu item, since the clipboard contains plain text. true } }
자바
// Gets the ID of the "paste" menu item. MenuItem pasteItem = menu.findItem(R.id.menu_paste); // If the clipboard doesn't contain data, disable the paste menu item. // If it does contain data, decide whether you can handle the data. if (!(clipboard.hasPrimaryClip())) { pasteItem.setEnabled(false); } else if (!(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))) { // Disables the paste menu item, since the clipboard has data but // it isn't plain text. pasteItem.setEnabled(false); } else { // Enables the paste menu item, since the clipboard contains plain text. pasteItem.setEnabled(true); }
- 클립보드에서 데이터를 복사합니다. 코드의 이 지점은
"붙여넣기" 사용 설정되었으므로 클립보드에 일반
있습니다. 텍스트 문자열이나 일반 텍스트를 가리키는 URI가 포함되어 있는지는 아직 모릅니다.
다음 코드 스니펫은 이를 테스트하지만 일반 텍스트를 처리하는 코드만 표시합니다.
Kotlin
when (menuItem.itemId) { ... R.id.menu_paste -> { // Responds to the user selecting "paste". // Examines the item on the clipboard. If getText() doesn't return null, // the clip item contains the text. Assumes that this application can only // handle one item at a time. val item = clipboard.primaryClip.getItemAt(0) // Gets the clipboard as text. pasteData = item.text return if (pasteData != null) { // If the string contains data, then the paste operation is done. true } else { // The clipboard doesn't contain text. If it contains a URI, // attempts to get data from it. val pasteUri: Uri? = item.uri if (pasteUri != null) { // If the URI contains something, try to get text from it. // Calls a routine to resolve the URI and get data from it. // This routine isn't presented here. pasteData = resolveUri(pasteUri) true } else { // Something is wrong. The MIME type was plain text, but the // clipboard doesn't contain text or a Uri. Report an error. Log.e(TAG,"Clipboard contains an invalid data type") false } } } }
자바
// Responds to the user selecting "paste". case R.id.menu_paste: // Examines the item on the clipboard. If getText() does not return null, // the clip item contains the text. Assumes that this application can only // handle one item at a time. ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0); // Gets the clipboard as text. pasteData = item.getText(); // If the string contains data, then the paste operation is done. if (pasteData != null) { return true; // The clipboard doesn't contain text. If it contains a URI, attempts to get // data from it. } else { Uri pasteUri = item.getUri(); // If the URI contains something, try to get text from it. if (pasteUri != null) { // Calls a routine to resolve the URI and get data from it. // This routine isn't presented here. pasteData = resolveUri(Uri); return true; } else { // Something is wrong. The MIME type is plain text, but the // clipboard doesn't contain text or a Uri. Report an error. Log.e(TAG, "Clipboard contains an invalid data type"); return false; } }
콘텐츠 URI의 데이터 붙여넣기
ClipData.Item
객체에 콘텐츠 URI가 포함되어 있고
MIME 유형 중 하나를 처리하고 ContentResolver
를 만든 후 적절한 콘텐츠를 호출합니다.
provider 메서드를 사용하여 데이터를 검색합니다.
다음 절차에서는 콘텐츠 URI를 기반으로 콘텐츠 제공자에서 데이터를 가져오는 방법을 설명합니다. 있습니다. 애플리케이션이 사용할 수 있는 MIME 유형이 제공업체
- 전역 변수를 선언하여 MIME 유형을 포함합니다.
Kotlin
// Declares a MIME type constant to match against the MIME types offered // by the provider. const val MIME_TYPE_CONTACT = "vnd.android.cursor.item/vnd.example.contact"
자바
// Declares a MIME type constant to match against the MIME types offered by // the provider. public static final String MIME_TYPE_CONTACT = "vnd.android.cursor.item/vnd.example.contact";
- 전역 클립보드 가져오기 또한 콘텐츠 리졸버를 가져와서 콘텐츠 제공업체에 액세스할 수 있습니다.
Kotlin
// Gets a handle to the Clipboard Manager. val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager // Gets a content resolver instance. val cr = contentResolver
자바
// Gets a handle to the Clipboard Manager. ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); // Gets a content resolver instance. ContentResolver cr = getContentResolver();
- 클립보드에서 기본 클립을 가져와서 콘텐츠를 URI로 가져옵니다.
Kotlin
// Gets the clipboard data from the clipboard. val clip: ClipData? = clipboard.primaryClip clip?.run { // Gets the first item from the clipboard data. val item: ClipData.Item = getItemAt(0) // Tries to get the item's contents as a URI. val pasteUri: Uri? = item.uri
자바
// Gets the clipboard data from the clipboard. ClipData clip = clipboard.getPrimaryClip(); if (clip != null) { // Gets the first item from the clipboard data. ClipData.Item item = clip.getItemAt(0); // Tries to get the item's contents as a URI. Uri pasteUri = item.getUri();
- 다음을 호출하여 URI가 콘텐츠 URI인지 테스트합니다.
getType(Uri)
이 메서드는Uri
가 유효한 콘텐츠 제공자를 가리키지 않으면 null을 반환합니다.Kotlin
// If the clipboard contains a URI reference... pasteUri?.let { // ...is this a content URI? val uriMimeType: String? = cr.getType(it)
자바
// If the clipboard contains a URI reference... if (pasteUri != null) { // ...is this a content URI? String uriMimeType = cr.getType(pasteUri);
- 콘텐츠 제공자가 애플리케이션이 이해하는 MIME 유형을 지원하는지 테스트합니다. 만약
지원하는 경우
ContentResolver.query()
데이터를 가져올 수 있습니다. 반환 값은Cursor
Kotlin
// If the return value isn't null, the Uri is a content Uri. uriMimeType?.takeIf { // Does the content provider offer a MIME type that the current // application can use? it == MIME_TYPE_CONTACT }?.apply { // Get the data from the content provider. cr.query(pasteUri, null, null, null, null)?.use { pasteCursor -> // If the Cursor contains data, move to the first record. if (pasteCursor.moveToFirst()) { // Get the data from the Cursor here. // The code varies according to the format of the data model. } // Kotlin `use` automatically closes the Cursor. } } } }
자바
// If the return value isn't null, the Uri is a content Uri. if (uriMimeType != null) { // Does the content provider offer a MIME type that the current // application can use? if (uriMimeType.equals(MIME_TYPE_CONTACT)) { // Get the data from the content provider. Cursor pasteCursor = cr.query(uri, null, null, null, null); // If the Cursor contains data, move to the first record. if (pasteCursor != null) { if (pasteCursor.moveToFirst()) { // Get the data from the Cursor here. // The code varies according to the format of the data model. } } // Close the Cursor. pasteCursor.close(); } } } }
인텐트 붙여넣기
인텐트를 붙여넣으려면 먼저 전역 클립보드를 가져옵니다. ClipData.Item
객체 확인
Intent
가 포함되어 있는지 확인합니다. 그런 다음 getIntent()
를 호출하여
인텐트를 자체 스토리지에 추가합니다 다음 스니펫은 이 작업을 보여줍니다.
Kotlin
// Gets a handle to the Clipboard Manager. val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager // Checks whether the clip item contains an Intent by testing whether // getIntent() returns null. val pasteIntent: Intent? = clipboard.primaryClip?.getItemAt(0)?.intent if (pasteIntent != null) { // Handle the Intent. } else { // Ignore the clipboard, or issue an error if // you expect an Intent to be on the clipboard. }
자바
// Gets a handle to the Clipboard Manager. ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); // Checks whether the clip item contains an Intent, by testing whether // getIntent() returns null. Intent pasteIntent = clipboard.getPrimaryClip().getItemAt(0).getIntent(); if (pasteIntent != null) { // Handle the Intent. } else { // Ignore the clipboard, or issue an error if // you expect an Intent to be on the clipboard. }
앱에서 클립보드 데이터에 액세스할 때 표시되는 시스템 알림
Android 12 (API 수준 31) 이상에서는 앱이 실행될 때 일반적으로 시스템에 토스트 메시지가 표시됩니다.
통화수
getPrimaryClip()
메시지 안의 텍스트에는 다음 형식이 포함되어 있습니다.
APP pasted from your clipboard
앱이 다음 중 하나를 실행하면 시스템에 토스트 메시지가 표시되지 않습니다.
- 액세스
자체 앱에서
ClipData
- 특정 앱에서
ClipData
에 반복적으로 액세스합니다. 토스트 메시지는 해당 앱의 데이터에 처음으로 액세스할 때 - 호출 등을 통해 클립 객체의 메타데이터를 검색합니다.
getPrimaryClipDescription()
드림 (getPrimaryClip()
대신)
콘텐츠 제공자를 사용하여 복잡한 데이터 복사
콘텐츠 제공업체는 데이터베이스 레코드나 파일 스트림과 같은 복잡한 데이터의 복사를 지원합니다. 복사하기 클립보드에 콘텐츠 URI를 배치합니다. 그런 다음 애플리케이션을 붙여넣으면 애플리케이션에서 이 URI를 데이터베이스 데이터 또는 파일 스트림 설명자를 검색하는 데 사용할 수 있습니다.
붙여넣기 애플리케이션에는 데이터의 콘텐츠 URI만 있으므로 어떤 애플리케이션이 데이터 조각입니다. 데이터 식별자를 인코딩하여 이 정보를 제공할 수 있습니다. 를 사용할 수도 있고, 복사하려는 데이터를 반환하는 고유한 URI를 제공할 수도 있습니다. 대상 선택하는 기법은 데이터의 구성에 따라 다릅니다.
다음 섹션에서는 URI를 설정하고, 복잡한 데이터를 제공하고, 파일을 제공하는 방법을 설명합니다. 있습니다. 설명에서는 사용자가 콘텐츠 제공업체의 일반 원칙을 잘 알고 있다고 가정합니다. 설계했습니다.
URI에 식별자 인코딩
URI를 사용하여 클립보드에 데이터를 복사하는 유용한 기술은 데이터를 가져올 수 있습니다. 그러면 콘텐츠 제공자가 URI에서 식별자를 가져와서 데이터를 검색할 수 있습니다 붙여넣기 애플리케이션은 식별자가 존재하는지 알 필요가 없습니다. 그것은 '참조'(URI와 식별자)를 데이터를 가져올 수 있습니다.
일반적으로 식별자를 URI 끝에 연결하여 콘텐츠 URI에 식별자를 인코딩합니다. 예를 들어 제공업체 URI를 다음 문자열로 정의한다고 가정해보겠습니다.
"content://com.example.contacts"
이 URI에 이름을 인코딩하려면 다음 코드 스니펫을 사용합니다.
Kotlin
val uriString = "content://com.example.contacts/Smith" // uriString now contains content://com.example.contacts/Smith. // Generates a uri object from the string representation. val copyUri = Uri.parse(uriString)
자바
String uriString = "content://com.example.contacts" + "/" + "Smith"; // uriString now contains content://com.example.contacts/Smith. // Generates a uri object from the string representation. Uri copyUri = Uri.parse(uriString);
콘텐츠 제공자를 이미 사용하고 있다면 URI는 복사용입니다 예를 들어 다음 URI 경로가 이미 있다고 가정해보겠습니다.
"content://com.example.contacts/people" "content://com.example.contacts/people/detail" "content://com.example.contacts/people/images"
URI를 복사하는 다른 경로를 추가할 수 있습니다.
"content://com.example.contacts/copying"
그런 다음 URI를 패턴 일치로 처리하고 복사 및 붙여넣기에 적합합니다.
이미 콘텐츠 제공업체, 내부 내부 테이블일 수 있습니다 이러한 경우에는 여러 개의 데이터가 있고 그리고 아마도 각 제품의 고유 식별자가 될 것입니다. Google의 붙여넣기 애플리케이션의 경우 식별자로 데이터를 조회하여 반환할 수 있습니다.
여러 데이터 조각이 없으면 식별자를 인코딩하지 않아도 됩니다. 제공업체 고유의 URI를 사용할 수 있습니다. 쿼리에 대한 응답으로 제공자는 현재 포함된 데이터입니다.
데이터 구조 복사
복잡한 데이터를 복사하여 붙여넣기 위한 콘텐츠 제공자를
ContentProvider
구성요소를 사용합니다. 클립보드에 배치한 URI가 원하는 정확한 레코드를 가리키도록 인코딩합니다.
제공합니다 또한 애플리케이션의 기존 상태를 고려하세요.
- 콘텐츠 제공업체가 이미 있는 경우 기능에 추가할 수 있습니다.
query()
메서드를 수정하여 붙여넣으려고 합니다. '복사'를 처리하도록 메서드를 수정하는 것이 URI 학습합니다. - 애플리케이션에서 내부 데이터베이스를 유지 관리하는 경우 이 데이터베이스를 다른 리전으로 이동하는 것이 좋습니다. 복사하기 쉽도록 콘텐츠 제공자에 추가해야 합니다.
- 데이터베이스를 사용하지 않는 경우 간단한 콘텐츠 제공자를 구현할 수 있습니다. 유일한 목적은 클립보드에서 붙여넣는 애플리케이션에 데이터를 제공하는 것입니다.
콘텐츠 제공자에서 최소한 다음 메서드를 재정의합니다.
-
query()
- 붙여넣기 애플리케이션은 개발자가 작성한 URI와 함께 이 메서드를 사용하여 데이터를 가져올 수 있다고 가정합니다. 클립보드에 저장 복사를 지원하려면 이 메서드가 특수 문자가 포함된 URI를 감지하도록 하세요. '복사' 있습니다. 그러면 애플리케이션에서 '사본'을 에 배치할 URI 클립보드에 복사 경로와 복사하려는 정확한 레코드의 포인터가 포함된 클립보드입니다.
-
getType()
- 이 메서드는 복사하려는 데이터의 MIME 유형을 반환해야 합니다. 메서드
newUri()
getType()
를 호출하여 MIME 유형을 새ClipData
에 넣습니다. 객체를 지정합니다.복잡한 데이터의 MIME 유형은 다음에 설명되어 있습니다. 콘텐츠 제공자.
다음과 같은 다른 콘텐츠 제공자 메서드는 필요하지 않습니다.
insert()
또는
update()
붙여넣기 애플리케이션은 지원되는 MIME 유형만 가져와서 제공업체에서 데이터를 복사하면 됩니다.
이러한 메서드가 이미 있다면 복사 작업을 방해하지 않습니다.
다음 스니펫은 애플리케이션을 설정하여 복잡한 데이터를 복사하는 방법을 보여줍니다.
-
애플리케이션의 전역 상수에서 기본 URI 문자열과 는 데이터를 복사하는 데 사용하는 URI 문자열을 식별합니다. 복사된 대상의 MIME 유형도 선언 데이터를 수집하는 데 사용됩니다
Kotlin
// Declares the base URI string. private const val CONTACTS = "content://com.example.contacts" // Declares a path string for URIs that you use to copy data. private const val COPY_PATH = "/copy" // Declares a MIME type for the copied data. const val MIME_TYPE_CONTACT = "vnd.android.cursor.item/vnd.example.contact"
자바
// Declares the base URI string. private static final String CONTACTS = "content://com.example.contacts"; // Declares a path string for URIs that you use to copy data. private static final String COPY_PATH = "/copy"; // Declares a MIME type for the copied data. public static final String MIME_TYPE_CONTACT = "vnd.android.cursor.item/vnd.example.contact";
- 사용자가 데이터를 복사하는 활동에서 코드를 설정하여 데이터를 클립보드에 복사합니다.
복사 요청에 대한 응답으로 클립보드에 URI를 배치합니다.
Kotlin
class MyCopyActivity : Activity() { ... when(item.itemId) { R.id.menu_copy -> { // The user has selected a name and is requesting a copy. // Appends the last name to the base URI. // The name is stored in "lastName". uriString = "$CONTACTS$COPY_PATH/$lastName" // Parses the string into a URI. val copyUri: Uri? = Uri.parse(uriString) // Gets a handle to the clipboard service. val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip: ClipData = ClipData.newUri(contentResolver, "URI", copyUri) // Sets the clipboard's primary clip. clipboard.setPrimaryClip(clip) } }
자바
public class MyCopyActivity extends Activity { ... // The user has selected a name and is requesting a copy. case R.id.menu_copy: // Appends the last name to the base URI. // The name is stored in "lastName". uriString = CONTACTS + COPY_PATH + "/" + lastName; // Parses the string into a URI. Uri copyUri = Uri.parse(uriString); // Gets a handle to the clipboard service. ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newUri(getContentResolver(), "URI", copyUri); // Sets the clipboard's primary clip. clipboard.setPrimaryClip(clip);
-
콘텐츠 제공업체의 전역 범위에서 URI 매처를 만들고 클립보드에 배치한 URI와 일치합니다.
Kotlin
// A Uri Match object that simplifies matching content URIs to patterns. private val sUriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply { // Adds a matcher for the content URI. It matches. // "content://com.example.contacts/copy/*" addURI(CONTACTS, "names/*", GET_SINGLE_CONTACT) } // An integer to use in switching based on the incoming URI pattern. private const val GET_SINGLE_CONTACT = 0 ... class MyCopyProvider : ContentProvider() { ... }
자바
public class MyCopyProvider extends ContentProvider { ... // A Uri Match object that simplifies matching content URIs to patterns. private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); // An integer to use in switching based on the incoming URI pattern. private static final int GET_SINGLE_CONTACT = 0; ... // Adds a matcher for the content URI. It matches // "content://com.example.contacts/copy/*" sUriMatcher.addURI(CONTACTS, "names/*", GET_SINGLE_CONTACT);
-
설정
query()
메서드를 사용하여 축소하도록 요청합니다. 이 메서드는 코딩 방법에 따라 다양한 URI 패턴을 처리할 수 있지만 클립보드 복사 작업의 패턴이 표시됩니다.Kotlin
// Sets up your provider's query() method. override fun query( uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String? ): Cursor? { ... // When based on the incoming content URI: when(sUriMatcher.match(uri)) { GET_SINGLE_CONTACT -> { // Queries and returns the contact for the requested name. Decodes // the incoming URI, queries the data model based on the last name, // and returns the result as a Cursor. } } ... }
자바
// Sets up your provider's query() method. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { ... // Switch based on the incoming content URI. switch (sUriMatcher.match(uri)) { case GET_SINGLE_CONTACT: // Queries and returns the contact for the requested name. Decodes the // incoming URI, queries the data model based on the last name, and // returns the result as a Cursor. ... }
-
복사된 항목의 적절한 MIME 유형을 반환하도록
getType()
메서드를 설정합니다. 데이터:Kotlin
// Sets up your provider's getType() method. override fun getType(uri: Uri): String? { ... return when(sUriMatcher.match(uri)) { GET_SINGLE_CONTACT -> MIME_TYPE_CONTACT ... } }
자바
// Sets up your provider's getType() method. public String getType(Uri uri) { ... switch (sUriMatcher.match(uri)) { case GET_SINGLE_CONTACT: return (MIME_TYPE_CONTACT); ... } }
콘텐츠 URI에서 데이터 붙여넣기 섹션에서는 클립보드에서 콘텐츠 URI를 가져와서 이를 사용하여 데이터를 가져오고 붙여넣습니다.
데이터 스트림 복사
대량의 텍스트 및 바이너리 데이터를 스트림으로 복사하여 붙여넣기 할 수 있습니다. 데이터에는 다음과 같습니다.
- 실제 기기에 저장된 파일
- 소켓 스트림
- 제공업체의 기본 데이터베이스 시스템에 저장된 대량의 데이터
데이터 스트림용 콘텐츠 제공자는 파일 설명자 객체를 사용하여 데이터에 대한 액세스를 제공합니다.
예:
AssetFileDescriptor
,
(Cursor
객체 대신) 붙여넣기 애플리케이션은 다음을 사용하여 데이터 스트림을 읽습니다.
파일 설명자입니다.
애플리케이션이 제공업체와 함께 데이터 스트림을 복사하도록 설정하려면 다음 단계를 따르세요.
-
클립보드에 배치하는 데이터 스트림의 콘텐츠 URI를 설정합니다. 이 작업 실행의 옵션에는 다음이 포함됩니다.
- 아래 설명된 대로 데이터 스트림의 식별자를 URI에 인코딩합니다. URI 섹션에 식별자를 인코딩한 다음 식별자와 해당 스트림 이름을 포함하는 제공자 내의 테이블입니다.
- 스트림 이름을 URI에 직접 인코딩합니다.
- 항상 제공업체의 현재 스트림을 반환하는 고유한 URI를 사용합니다. 만약 이 옵션을 사용하려면 다른 스트림을 가리키도록 제공자를 업데이트해야 합니다. 해야 합니다.
- 제공하려는 각 데이터 스트림 유형에 MIME 유형을 제공합니다. 애플리케이션 붙여넣기 클립보드에 데이터를 붙여넣을 수 있는지 여부를 결정하는 데 이 정보가 필요합니다.
- 다음의 파일 설명자를 반환하는
ContentProvider
메서드 중 하나를 구현합니다. 스트림 콘텐츠 URI에 식별자를 인코딩하는 경우 이 메서드를 사용하여 열려 있습니다. - 데이터 스트림을 클립보드에 복사하려면 콘텐츠 URI를 구성하여 클립보드로 이동합니다.
데이터 스트림을 붙여넣기 위해 애플리케이션은 클립보드에서 클립을 가져오고 URI를 가져온 후
스트림을 여는 ContentResolver
파일 설명자 메서드를 호출하면 됩니다. 이
ContentResolver
메서드는 상응하는 ContentProvider
메서드를 호출합니다.
콘텐츠 URI를 전달합니다. 제공자는 파일 설명자를
ContentResolver
메서드를 사용하여 지도 가장자리에
패딩을 추가할 수 있습니다. 그러면 붙여넣기 애플리케이션은
가져올 수 있습니다.
다음 목록은 콘텐츠 제공업체의 가장 중요한 파일 설명자 메서드를 보여줍니다. 각
그중에는 문자열과 함께 상응하는 ContentResolver
메서드가 있습니다.
'설명어' 가 추가됩니다. 예를 들면 ContentResolver
입니다.
아날로그
openAssetFile()
은
openAssetFileDescriptor()
입니다.
-
openTypedAssetFile()
-
이 메서드는 제공된 MIME 유형이 모두 사용 가능합니다 호출자(붙여넣기를 수행하는 애플리케이션)는 MIME 유형 패턴입니다. URI를 클립보드가
AssetFileDescriptor
파일 핸들을 제공할 수 있는 경우 이를 반환함 MIME 유형이며 사용할 수 없는 경우 예외가 발생합니다.이 메서드는 파일의 하위 섹션을 처리합니다. 이를 사용하여 클립보드에 복사했습니다.
-
openAssetFile()
-
이 메서드는 더 일반적인 형태의
openTypedAssetFile()
입니다. 필터링되지 않음 MIME 유형을 읽을 수 있지만 파일의 하위 섹션을 읽을 수 있습니다. -
openFile()
-
더 일반적인 형식의
openAssetFile()
입니다. 하위 섹션을 읽을 수 없습니다. 할 수 있습니다.
원하는 경우
openPipeHelper()
메서드를 파일 설명자 메서드와 함께 사용하세요. 이렇게 하면 붙여넣기 애플리케이션이
백그라운드 스레드를 호출합니다. 이 메서드를 사용하려면
ContentProvider.PipeDataWriter
인터페이스에 추가되었습니다.
효과적인 복사하여 붙여넣기 기능 디자인
애플리케이션에 효과적인 복사하여 붙여넣기 기능을 디자인하려면 다음 사항에 유의하세요.
- 언제나 클립보드에는 클립이 하나만 있습니다. 사용자가 새로 복사 작업을 애플리케이션이 이전 클립을 덮어씁니다. 사용자가 이동하면서 반환하기 전에 애플리케이션에서 복사해야 하는 경우 클립보드를 가정할 수 없습니다. 에는 사용자가 이전에 개발자 애플리케이션에서 복사한 클립이 포함됩니다.
-
클립당 여러
ClipData.Item
객체의 의도된 목적은 다음과 같습니다. 다른 형식의 이미지가 아닌 여러 개의 선택항목을 복사하고 붙여넣을 수 있습니다. 단일 선택 참조입니다. 일반적으로 모든ClipData.Item
개체들이 동일한 형태를 갖도록 하기 위한 것입니다. 즉, 모두 단순한 텍스트, 콘텐츠 URI 또는Intent
이고 혼합되지 않아야 합니다. -
데이터를 제공할 때 다양한 MIME 표시를 제공할 수 있습니다. MIME 유형 추가
ClipDescription
를 지원한 다음 있습니다. -
클립보드에서 데이터를 가져올 때 애플리케이션은 사용 가능한 MIME 유형을 확인하고 사용할 MIME 유형을 판단해야 합니다. 사용자가
클립보드의 클립이 있고 사용자가 붙여넣기를 요청하는 경우 애플리케이션이 필요하지 않습니다.
붙여넣습니다. MIME 유형이 호환되는 경우 붙여넣기를 실행합니다. 데이터를 강제로 변환하고
클립보드에
coerceToText()
를 사용하여 텍스트로 변환할 수 있습니다. 애플리케이션이 둘 이상의 MIME 유형이 있을 경우 사용자가 사용할 MIME 유형을 선택하도록 할 수 있습니다.