Android, kopyalama ve yapıştırma işlemi için pano tabanlı güçlü bir çerçeve sunar. Basit kampanyaları destekler ve karmaşık veri türlerini (metin dizeleri, karmaşık veri yapıları, metin ve ikili akış dahil) veriler ve uygulama öğeleri. Basit metin verileri doğrudan panoda saklanırken karmaşık verileri, yapıştırma uygulamasının bir içerik sağlayıcıyla çözdüğü bir referans olarak saklanır. Kopyalanıyor hem bir uygulama içinde hem de bahsedeceğim.
Çerçevenin bir kısmında içerik sağlayıcılar kullanıldığı için bu belgede Android Content Provider API'si İçerik sağlayıcılar.
Kullanıcılar, içeriği panoya kopyalarken geri bildirim bekler. Bu nedenle, kopyalama ve yapıştırma özelliğini etkinleştirir. Android, Android 13'te (API düzeyi 33) kopyalama yaparken kullanıcılara varsayılan bir kullanıcı arayüzü gösterir. ve daha yüksek olabilir. Bu özellik nedeniyle yinelenen bildirim riski vardır. Web sitemiz g.co/newsinitiative/labs üzerinden bu uç örnekte, Yinelenen bildirimlerden kaçınma bölümüne bakın.
Android 12L (API düzeyi 32) ve önceki sürümlerde kopyalama yaparken kullanıcılara manuel olarak geri bildirim sağlayın. Görüntüleyin bununla ilgili öneriler bulabilirsiniz.
Pano çerçevesi
Pano çerçevesini kullanırken verileri bir klip nesnesine yerleştirin, ardından klip nesnesini yerleştirin. panodan takip edin. Klip nesnesi şu üç biçimden birinde olabilir:
- Metin
- . Metin dizesi. Dizeyi doğrudan klip nesnesinin içine yerleştirin. Daha sonra panoya ekleyebilirsiniz. Dizeyi yapıştırmak için panodan klip nesnesini alın ve dizeyi uygulamanızın depolama alanına yapıştırın.
- URI
- .
Herhangi birini temsil eden
Uri
nesnesi bir yolunu sunar. Bu, esas olarak bir içerik sağlayıcıdan karmaşık verilerin kopyalanması içindir. Kopyalamak için birUri
nesnesini klip nesnesine yerleştirin ve klip nesnesini panoya ekleyebilirsiniz. Verileri yapıştırmak için klip nesnesini,Uri
nesnesini ve bir veri kaynağına (örneğin bir içerik sağlayıcıya) çözümlemeli ve uygulamanızın depolama alanına yapıştırın. - Amaç
- .
Intent
. Bu uygulama kısayollarının kopyalanmasını destekler. Verileri kopyalamak için birIntent
oluşturun, klip nesnesine koyabilir ve klip nesnesini panoya koyabilirsiniz. Verileri yapıştırmak için klip nesnesini kopyalayın ve ardındanIntent
nesnesini uygulamanıza kopyalayın. görünür.
Panoda aynı anda yalnızca bir klip nesnesi bulunur. Bir uygulama, önceki klip nesnesi kaybolur.
Kullanıcıların uygulamanıza veri yapıştırmasına izin vermek istiyorsanız tüm uygulama türlerini işlemeniz gerekmez. dışı verilerdir. Kullanıcılara yapıştırma seçeneği sunmadan önce panodaki verileri inceleyebilirsiniz. Klip nesnesi, belirli bir veri formunun yanı sıra hangi MIME türünü belirten meta veriler de içerir? farklı türler vardır. Bu meta veriler, uygulamanızın faydalı bir şeyler yapıp yapamayacağına karar vermenize yardımcı olur pano verileriyle birlikte. Örneğin, ağırlıklı olarak metinlerle ilgili işlem yapan bir uygulamanız varsa URI veya intent içeren klip nesnelerini yoksaymak isteyebilirsiniz.
Kullanıcıların panodaki veri biçiminden bağımsız olarak metin yapıştırmasına da izin vermek isteyebilirsiniz. Alıcı: bunu yapın, pano verilerini metin biçiminde göstermeye zorlayın ve ardından bu metni yapıştırın. Bu Panoyu metne dönüştürme bölümünde bulabilirsiniz.
Pano dersleri
Bu bölümde, pano çerçevesi tarafından kullanılan sınıflar açıklanmaktadır.
Pano Yöneticisi
Android sistem panosu, global
ClipboardManager
sınıf.
Bu sınıfı doğrudan örneklendirmeyin. Bunun yerine,
getSystemService(CLIPBOARD_SERVICE)
ClipData, ClipData.Item ve ClipDescription
Panoya veri eklemek için bir
Şunları içeren ClipData
nesne
verilerin bir açıklamasıdır. Panoda her defasında başka bir ClipData
tutulup
gerekir. ClipData
, bir
ClipDescription
nesne
ve bir veya daha fazla
ClipData.Item
nesne.
Bir ClipDescription
nesnesi, kliple ilgili meta verileri içerir. Özellikle,
klibin verileri için bir dizi kullanılabilir MIME türü içerir. Ayrıca
Android 12 (API düzeyi 31) ve sonraki sürümlerde meta veriler, nesnenin
içerir
stilize edilmiş metin ve kullanıcıların
nesnedeki metnin türünü.
Panoya bir klip yerleştirdiğinizde bu bilgiler, uygulamaları yapıştırırken kullanılabilir ve
klip verilerini işleyip işleyemediklerini inceleyebilir.
ClipData.Item
nesnesi metin, URI veya intent verilerini içerir:
- Metin
- .
CharSequence
. - URI
- .
Uri
. Bu genellikle bir içerik sağlayıcı URI'si içerir, ancak herhangi bir URI izin verilir. Verileri sağlayan uygulama, URI'yı panoya yerleştirir. Uygulamalar verileri yapıştırmak isteyenlerin URI'yı panodan alıp içeriğe erişmek için kullanması veya başka bir veri kaynağında bulunabilir ve verileri alabilir. - Amaç
- .
Intent
. Bu veri türü, bir uygulama kısayolunu panoya ekleyebilirsiniz. Kullanıcılar, bu kısayolu daha sonra kullanmak üzere uygulamalarına yapıştırabilir.
Bir klibe birden fazla ClipData.Item
nesnesi ekleyebilirsiniz. Bu sayede kullanıcılar
birden fazla seçimi tek bir klip olarak yapıştırabilirsiniz. Örneğin,
kullanıcı aynı anda birden çok öğe seçerse, tüm öğeleri tek seferde panoya kopyalayabilirsiniz. Yapılacaklar
her liste öğesi için ayrı bir ClipData.Item
oluşturun ve daha sonra
ClipData
nesnesine ClipData.Item
nesne eklendi.
ClipData kolaylık yöntemleri
ClipData
sınıfı,
Tek bir ClipData.Item
nesnesi ve basit bir öğe içeren ClipData
nesnesi
ClipDescription
nesne:
-
newPlainText(label, text)
- Tek
ClipData.Item
nesnesi bulunanClipData
nesnesini döndürür bir metin dizesi içeriyorsa.ClipDescription
nesnesinin etiketilabel
.ClipDescription
alanındaki tek MIME türü:MIMETYPE_TEXT_PLAIN
.Bir metin dizesinden klip oluşturmak için
newPlainText()
öğesini kullanın. -
newUri(resolver, label, URI)
- Tek
ClipData.Item
nesnesi bulunanClipData
nesnesini döndürür URI içerir.ClipDescription
nesnesinin etiketilabel
. URI bir içerik URI'si ise (yani,Uri.getScheme()
.content:
değerini döndürür; yöntemContentResolver
resolver
kullanılarak sağlanan nesne içerik sağlayıcı. Daha sonra bunlarıClipDescription
konumunda depolar. Benzersiz bir URI için bircontent:
URI ise, yöntem MIME türünüMIMETYPE_TEXT_URILIST
.URI'dan klip oluşturmak için
newUri()
kullanın. Bu, özellikle decontent:
URI. -
newIntent(label, intent)
- Tek
ClipData.Item
nesnesi bulunanClipData
nesnesini döndürür birIntent
içerir.ClipDescription
nesnesinin etiketilabel
. MIME türü şuna ayarlanır:MIMETYPE_TEXT_INTENT
Intent
nesnesinden klip oluşturmak içinnewIntent()
işlemini kullanın.
Pano verilerini metne dönüştürme
Uygulamanız yalnızca metin işlese bile aşağıdakileri kullanarak metin dışı verileri panodan kopyalayabilirsiniz:
dönüşüm için
ClipData.Item.coerceToText()
.
yöntemidir.
Bu yöntem, ClipData.Item
içindeki verileri metne dönüştürür ve bir
CharSequence
. ClipData.Item.coerceToText()
işlevinin döndürdüğü değer temel alınmıştır.
ClipData.Item
içindeki veri biçiminde:
- Metin
- .
ClipData.Item
metin ise (yanigetText()
null değildir; coerceToText(), metni döndürür. - URI
- .
ClipData.Item
bir URI ise (yanigetUri()
boş değildir:coerceToText()
, bunu içerik URI'si olarak kullanmaya çalışır.- URI bir içerik URI'siyse ve sağlayıcı bir metin akışı döndürebiliyorsa
coerceToText()
bir metin akışı döndürür. - URI bir içerik URI'siyse ancak sağlayıcı bir metin akışı sunmuyorsa
coerceToText()
, URI'nın bir gösterimini döndürür. Bu temsil tarafından döndürülenUri.toString()
- URI bir içerik URI'si değilse
coerceToText()
bunun bir temsilini döndürür URI'yı ekleyin. Temsil,Uri.toString()
- URI bir içerik URI'siyse ve sağlayıcı bir metin akışı döndürebiliyorsa
- Amaç
ClipData.Item
birIntent
ise (yanigetIntent()
null değildir -coerceToText()
, bunu bir Intent URI'sine dönüştürür ve döndürür. Temsil,Intent.toUri(URI_INTENT_SCHEME)
Pano çerçevesi Şekil 2'de özetlenmiştir. Bir uygulama, verileri kopyalamak için
ClipboardManager
genel panosunda ClipData
nesnesi var. İlgili içeriği oluşturmak için kullanılan
ClipData
, bir veya daha fazla ClipData.Item
nesne ve bir tane içeriyor
ClipDescription
nesne. Bir uygulama, verileri yapıştırmak için ClipData
alır.
MIME türünü ClipDescription
kaynağından alır ve verileri şuradan alır:
ClipData.Item
veya atıfta bulunulan içerik sağlayıcıdan
ClipData.Item
.
Panoya kopyala
Verileri panoya kopyalamak için global ClipboardManager
nesnesini herkese açık kullanıcı adı olarak kullanın.
ClipData
nesnesi oluşturun, ClipDescription
ve bir veya daha fazlasını ekleyin
ClipData.Item
nesne var. Sonra, tamamlanmış ClipData
nesnesini
ClipboardManager
nesne algılandı. Bu, aşağıdaki prosedürde daha ayrıntılı bir şekilde açıklanmaktadır:
- Verileri içerik URI'si kullanarak kopyalıyorsanız bir içerik sağlayıcı ayarlayın.
- Sistem panosunu alın:
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 } }
Java
... // If the user selects copy. case R.id.menu_copy: // Gets a handle to the clipboard service. ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
-
Verileri yeni bir
ClipData
nesnesine kopyalayın:-
Metin için
Kotlin
// Creates a new text clip to put on the clipboard. val clip: ClipData = ClipData.newPlainText("simple text", "Hello, World!")
Java
// Creates a new text clip to put on the clipboard. ClipData clip = ClipData.newPlainText("simple text", "Hello, World!");
-
Bir URI için
Bu snippet içerik URI'sine kayıt kimliğini kodlayarak bir URI oluşturur. sağlayıcıdır. Bu teknik, bkz. URI'da bir tanımlayıcıyı kodlama bölümünde.
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)
Java
// 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);
-
Amaç için
Bu snippet, bir uygulama için bir
Intent
oluşturur ve ardından bunu klip nesnesine ekleyin: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)
Java
// 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);
-
Metin için
-
Yeni klip nesnesini panoya yerleştirin:
Kotlin
// Set the clipboard's primary clip. clipboard.setPrimaryClip(clip)
Java
// Set the clipboard's primary clip. clipboard.setPrimaryClip(clip);
Panoya kopyalarken geri bildirim ver
Kullanıcılar, bir uygulama panoya içerik kopyaladığında görsel geri bildirim bekler. Bu işlem tamamlandı Android 13 ve sonraki sürümlerdeki kullanıcılar için otomatik olarak oluşturulur, ancak öncesinde manuel olarak uygulanması gerekir sürümleri vardır.
Android 13'ten itibaren içerik eklendiğinde sistem standart bir görsel onay mesajı gösterir. panoya gönderir. Yeni onay şunları yapar:
- İçeriğin başarıyla kopyalandığını onaylar.
- Kopyalanan içeriğin önizlemesini sunar.
Android 12L (API düzeyi 32) ve önceki sürümlerde kullanıcılar başarıyla kopyalanıp kopyalanmadığından emin olmayabilir. geri bildirimde bulunurlar. Bu özellik, kullanıcılara pano üzerinde daha fazla kontrol olanağı sağlar.
Yinelenen bildirimlerden kaçının
Android 12L (API düzeyi 32) ve önceki sürümlerde, kopyalama işlemi başarılı olduğunda kullanıcıları uyarmanızı öneririz.
Toast
gibi bir widget kullanarak görsel ve uygulama içi geri bildirim göndererek
Snackbar
olarak gönderin.
Bilgilerin yinelenen şekilde gösterilmesini önlemek için kısa mesajları kaldırmanızı önemle tavsiye ederiz veya atıştırmalık çubuklarının yer aldığı reklamlar, uygulama içi kopyadan sonra gösteriliyor.
'nı inceleyin.Aşağıda, bunun nasıl uygulanacağına ilişkin bir örnek verilmiştir:
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() }
Panoya hassas içerik ekleme
Uygulamanız, kullanıcıların şifre veya kredi kartı gibi hassas içerikleri panoya kopyalamasına izin veriyorsa
kart bilgileri, ClipData
uygulamasında ClipDescription
uygulamasına bir bayrak eklemeniz gerekiyor
ClipboardManager.setPrimaryClip()
numaralı telefonu aramadan önce. Bu işaretin eklenmesi, hassasiyeti
içeriğin Android 13 ve sonraki sürümlerde kopyalanan içeriğin görsel onayında görünmesini engeller.
Hassas içeriği işaretlemek için ClipDescription
öğesine fazladan bir boole ekleyin. Tüm uygulamalar şunları yapmalıdır:
(hedeflenen API düzeyinden bağımsız olarak).
// 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) } }
Panodan yapıştır
Daha önce açıklandığı gibi, global pano nesnesini alarak verileri panodan yapıştırın, klip nesnesini alma, verilerine bakma ve mümkünse verileri klip nesnesinden kopyalama . Bu bölümde, üç pano biçiminin nasıl yapıştırılacağı ayrıntılı olarak açıklanmaktadır dışı verilerdir.
Düz metin yapıştır
Düz metni yapıştırmak için genel panoyu alın ve düz metin döndürebildiğini doğrulayın. Sonra
klip nesnesini oluşturun ve metni getText()
kullanarak aşağıdaki şekilde kendi depolama alanınıza kopyalayın:
şu prosedürü uygulayın:
- Şunu kullanarak global
ClipboardManager
nesnesini alın:getSystemService(CLIPBOARD_SERVICE)
. Ayrıca, şunu içerecek bir genel değişken bildirin: yapıştırılan metin:Kotlin
var clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager var pasteData: String = ""
Java
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String pasteData = "";
- "Yapıştır" işlemini etkinleştirmenin veya devre dışı bırakmanın gerekip gerekmediğini belirleme seçeneğinin yanındaki
etkinliği'ne dokunun. Panonun klip içerdiğini ve veri türünü işleyebildiğinizi doğrulayın
kliple temsil edilir:
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 } }
Java
// 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); }
- Panodaki verileri kopyalayın. Koddaki bu noktaya yalnızca
"Yapıştır" menü öğesi etkinleştirildiğinde, panonun düz metin içerdiğini varsayabilirsiniz
metin. Bir metin dizesi mi yoksa düz metne işaret eden bir URI mi içerdiğini bilmiyorsunuz.
Aşağıdaki kod snippet'i bunu test eder, ancak yalnızca düz metni işlemeye yönelik kodu gösterir:
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 } } } }
Java
// 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; } }
İçerik URI'sinden veri yapıştırma
ClipData.Item
nesnesi bir içerik URI'si içeriyorsa ve şunu yapıldığını belirlerseniz:
MIME türlerinden birini işleyip ContentResolver
oluşturup uygun içeriği çağırın
sağlayıcı yöntemini kullanın.
Aşağıdaki prosedürde, içerik URI'sine dayalı olarak içerik sağlayıcıdan nasıl veri alınacağı açıklanmaktadır. tıklayın. Uygulamanın kullanabileceği bir MIME türünün sağlar.
-
Bir genel değişkeni MIME türünü içerecek şekilde bildirin:
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"
Java
// 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";
- Genel panoyu alın. İçeriğe erişebilmek için içerik çözümleyici de edinin
sağlayıcı:
Kotlin
// Gets a handle to the Clipboard Manager. val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager // Gets a content resolver instance. val cr = contentResolver
Java
// Gets a handle to the Clipboard Manager. ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); // Gets a content resolver instance. ContentResolver cr = getContentResolver();
- Birincil klibi panodan alın ve içeriğini URI olarak alın:
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
Java
// 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'nın bir içerik URI'si olup olmadığını test etmek için şunu çağırarak:
getType(Uri)
Uri
geçerli bir içerik sağlayıcıya işaret etmiyorsa bu yöntem null değerini döndürür.Kotlin
// If the clipboard contains a URI reference... pasteUri?.let { // ...is this a content URI? val uriMimeType: String? = cr.getType(it)
Java
// If the clipboard contains a URI reference... if (pasteUri != null) { // ...is this a content URI? String uriMimeType = cr.getType(pasteUri);
- İçerik sağlayıcının, uygulamanın anladığı bir MIME türünü destekleyip desteklemediğini test edin. Eğer
çağırın,
ContentResolver.query()
. bu verileri almak için iyi bir fırsattır. Döndürülen değer: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. } } } }
Java
// 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(); } } } }
Niyet Yapıştır
Niyeti yapıştırmak için önce genel panoyu alın. ClipData.Item
nesnesini inceleyin
bir Intent
içerip içermediğini kontrol edin. Ardından şunu kopyalamak için getIntent()
işlevini çağırın:
depolama alanına sahip olursunuz. Aşağıdaki snippet bunu göstermektedir:
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. }
Java
// 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. }
Uygulamanız pano verilerine eriştiğinde gösterilen sistem bildirimi
Android 12 (API düzeyi 31) ve sonraki sürümlerde sistem, uygulamanız gerektiğinde genellikle bir posta mesajı gösterir.
telefon aramaları
getPrimaryClip()
.
İletinin içindeki metin aşağıdaki biçimdedir:
APP pasted from your clipboard
Uygulamanız aşağıdakilerden birini yaptığında sistem bir durum mesajı mesajı göstermez:
- Erişimler
Kendi uygulamanızdan
ClipData
. - Belirli bir uygulamadan
ClipData
cihazına sürekli olarak erişir. Kısa mesaj yalnızca Uygulamanız o uygulamadaki verilere ilk kez eriştiğinde - Klip nesnesinin meta verilerini alır (örneğin, şunu çağırarak)
getPrimaryClipDescription()
(getPrimaryClip()
yerine)
Karmaşık verileri kopyalamak için içerik sağlayıcıları kullanma
İçerik sağlayıcılar, veritabanı kayıtları veya dosya akışları gibi karmaşık verilerin kopyalanmasını destekler. Kopyalamak için verileri görüntülemek için panoya bir içerik URI'si yerleştirin. Uygulamaları yapıştırdıktan sonra, bu URI'yı şuradan alın: panoya kaydedebilir ve veritabanı verilerini veya dosya akışı tanımlayıcılarını almak için kullanabilirsiniz.
Yapıştırma uygulaması yalnızca verilerinize ait içerik URI'sine sahip olduğundan, uygulamanızın hangi küçük bir dosyadır. Veriler için bir tanımlayıcı kodlayarak bu bilgileri sağlayabilirsiniz tıklayabilir veya kopyalamak istediğiniz verileri döndüren benzersiz bir URI sağlayabilirsiniz. Hangi verilerinizin nasıl düzenlendiğine bağlıdır.
Aşağıdaki bölümlerde, URI'ların nasıl ayarlanacağı, karmaşık verilerin nasıl sağlanacağı ve nasıl dosya sağlanacağı açıklanmaktadır. akışlar. Açıklamalarda içerik sağlayıcının genel ilkelerine aşina olduğunuz varsayılır tasarım.
URI'da bir tanımlayıcıyı kodlama
URI içeren bir panoya veri kopyalamak için yararlı bir teknik, URI'nın kendisindeki veriler. Daha sonra içerik sağlayıcınız, tanımlayıcıyı URI'dan alıp verileri almak için kullanır. Yapıştırma uygulamasının tanımlayıcının mevcut olduğunu bilmesi gerekmez. Google tek yapmanız gereken içerik sağlayıcınıza vermeniz ve verileri geri almanız gerekir.
Genellikle bir tanımlayıcıyı URI'nın sonunda birleştirerek bir içerik URI'si üzerinde kodlarsınız. Örneğin, sağlayıcı URI'nizi aşağıdaki dize olarak tanımladığınızı varsayalım:
"content://com.example.contacts"
Bu URI'ye bir ad kodlamak istiyorsanız aşağıdaki kod snippet'ini kullanın:
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)
Java
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);
Zaten bir içerik sağlayıcı kullanıyorsanız URI, kopyalama içindir. Örneğin, zaten aşağıdaki URI yollarına sahip olduğunuzu varsayalım:
"content://com.example.contacts/people" "content://com.example.contacts/people/detail" "content://com.example.contacts/people/images"
URI'leri kopyalamak için başka bir yol ekleyebilirsiniz:
"content://com.example.contacts/copying"
Böylece bir "kopya" algılayabilir. Kalıp eşleştirmeye göre URI ve bunu özellikle kopyalama ve yapıştırma işlemlerine özeldir.
Halihazırda dahili bir içerik sağlayıcı kullanıyorsanız, normalde kodlama tekniğini kullanırsınız. verilerinizi düzenlemek için kullanabileceğiniz dahili bir tablodur. Böyle durumlarda, elinizde birden fazla ve muhtemelen her parça için benzersiz bir tanımlayıcı eklemeniz gerekir. bir uygulamayı yapıştırdığınızda, verileri tanımlayıcısına göre arayıp döndürebilirsiniz.
Birden çok veriniz yoksa muhtemelen bir tanımlayıcıyı kodlamanız gerekmez. Sağlayıcınıza özgü bir URI kullanabilirsiniz. Sağlayıcınız, bir sorguya yanıt olarak verilerini de içerebilir.
Veri yapılarını kopyalama
Karmaşık verileri
ContentProvider
.
bir bileşenidir. Panoya yerleştirdiğiniz URI'yı, tam olarak eklemek istediğiniz kaydı işaret edecek şekilde kodlayın
sağlar. Ayrıca, uygulamanızın mevcut durumunu da göz önünde bulundurun:
- Halihazırda bir içerik sağlayıcınız varsa işlevselliğini ekleyebilirsiniz. Yalnızca
query()
yöntemini, bu API'yi kullanan uygulamalardan gelen URI'leri işleyecek şekilde değiştirmesi verileri yapıştırmak istiyorsanız. Muhtemelen yöntemi bir "kopya" işlemini işleyecek şekilde değiştirmek isteyebilirsiniz. URI desen. - Uygulamanızda dahili bir veritabanı kullanılıyorsa bu veritabanını taşımak isteyebilirsiniz. kopyalamayı kolaylaştırmak için bir içerik sağlayıcıya.
- Veritabanı kullanmıyorsanız tek amacı, panodan yapıştırma işlemi yapan uygulamalara veri sunmaktır.
İçerik sağlayıcıda, aşağıdaki yöntemlerin en az birini geçersiz kılın:
-
query()
- Uygulamalar yapıştırılırken, bu yöntemi istediğiniz URI ile kullanarak verilerinizi alabilecekleri varsayılır panoya koyabilirim. Kopyalamayı desteklemek için bu yöntemin, özel bir "kopyala" yol'a dokunun. Ardından, uygulamanız bir "kopya" oluşturabilir bir pano da mevcuttur.
-
getType()
- Bu yöntem, kopyalamak istediğiniz verilerin MIME türlerini döndürmelidir. Yöntem
newUri()
. MIME türlerini yeniClipData
içine yerleştirmek içingetType()
çağrısı nesnesini tanımlayın.Karmaşık verilere ilişkin MIME türleri şurada açıklanmıştır: İçerik sağlayıcılar.
Örneğin,
insert()
.
veya
update()
.
Yapıştırma uygulamasının yalnızca desteklenen MIME türlerinizi alması ve sağlayıcınızdan veri kopyalaması gerekir.
Bu yöntemleri zaten kullanıyorsanız kopyalama işlemlerini engellemezler.
Aşağıdaki snippet'ler, uygulamanızı karmaşık verileri kopyalayacak şekilde nasıl ayarlayacağınızı gösterir:
-
Uygulamanızın genel sabit değerlerinde, bir taban URI dizesi ve verileri kopyalamak için kullandığınız URI dizelerini tanımlar. Kopyalanan dosya için de bir MIME türü bildir dışı verilerdir.
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"
Java
// 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";
- Kullanıcıların veri kopyaladığı etkinlikte, verileri panoya kopyalayacak kodu ayarlayın.
Kopyalama isteğine yanıt olarak URI'yı panoya yerleştirin.
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) } }
Java
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);
-
İçerik sağlayıcınızın global kapsamında bir URI eşleştirici oluşturun ve şunu içeren bir URI kalıbı ekleyin: panoya yerleştirdiğiniz URI'lerle eşleşir.
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() { ... }
Java
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);
-
Ayarlayın:
query()
. yöntemidir. Bu yöntem, onu nasıl kodladığınıza bağlı olarak farklı URI kalıplarını işleyebilir, ancak yalnızca panoya kopyalama işleminin kalıbı gösterilmektedir.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. } } ... }
Java
// 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. ... }
-
getType()
yöntemini, kopyalanan öğe için uygun bir MIME türü döndürecek şekilde ayarlayın veri: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 ... } }
Java
// Sets up your provider's getType() method. public String getType(Uri uri) { ... switch (sUriMatcher.match(uri)) { case GET_SINGLE_CONTACT: return (MIME_TYPE_CONTACT); ... } }
İçerik URI'sinden veri yapıştırma bölümünde, içerik URI'sini bulun ve verileri alıp yapıştırmak için kullanın.
Veri akışlarını kopyala
Büyük miktarda metin ve ikili veriyi akış olarak kopyalayıp yapıştırabilirsiniz. Verilerde formlar olabilir Örneğin:
- Asıl cihazda depolanan dosyalar
- Yuvalardan akışlar
- Bir sağlayıcının temel veritabanı sisteminde depolanan büyük miktarlarda veri
Veri akışları için içerik sağlayıcı, bir dosya tanımlayıcı nesnesiyle verilerine erişim sağlar.
örneğin:
AssetFileDescriptor
,
(Cursor
nesnesi) oluşturun. Yapıştırma uygulaması, bu veri akışını kullanarak veri akışını okur.
dosya tanımlayıcısıdır.
Uygulamanızı bir sağlayıcıyla veri akışını kopyalayacak şekilde ayarlamak için aşağıdaki adımları uygulayın:
-
Panoya koyduğunuz veri akışı için bir içerik URI'si oluşturun. Seçenekler
şunları içerir:
- Veri akışı için bir tanımlayıcıyı aşağıdaki bölümünde açıklandığı gibi URI üzerine kodlayın: URI bölümünde bir tanımlayıcıyı kodlayın ve ardından içinde tanımlayıcılar ve ilgili akış adını içeren bir tablo görürsünüz.
- Akış adını doğrudan URI üzerinde kodlayın.
- Her zaman sağlayıcıdan geçerli akışı döndüren benzersiz bir URI kullanın. Şu durumda: Bu seçeneği kullanırsanız sağlayıcınızı farklı bir akışa yönlendirecek şekilde güncellemeyi unutmayın. .
- Sunmayı planladığınız her veri akışı türü için bir MIME türü sağlayın. Uygulamalar yapıştırılıyor ve verileri panoya yapıştırıp yapıştıramayacağını belirlemek için bu bilgilere ihtiyaç duyar.
- Şu öğe için dosya açıklayıcısı döndüren
ContentProvider
yöntemlerinden birini uygulayın: bir deneyimdir. Tanımlayıcıları içerik URI'sinde kodluyorsanız hangi akışı açın. - Veri akışını panoya kopyalamak için içerik URI'sini oluşturun ve panoya yerleştirin. panoya ekleyebilirsiniz.
Uygulama, veri akışını yapıştırmak için klibi panodan alır, URI'yı alır ve daha sonra
akışı açan bir ContentResolver
dosyası açıklayıcı yöntemine çağrıda bulunur. İlgili içeriği oluşturmak için kullanılan
ContentResolver
yöntemi, karşılık gelen ContentProvider
yöntemini çağırır.
içerik URI'si iletmektir. Sağlayıcınız, dosya açıklayıcısını
ContentResolver
yöntemini çağırın. Ardından, yapıştırma uygulaması,
bu verileri kullanabilirsiniz.
Aşağıdaki liste, bir içerik sağlayıcı için en önemli dosya tanımlayıcı yöntemlerini göstermektedir. Her biri
Bunların arasından dizeyle karşılık gelen bir ContentResolver
yöntemi vardır
"Açıklayıcı" sonuna eklenir. Örneğin, ContentResolver
analog
openAssetFile()
:
openAssetFileDescriptor()
.
-
openTypedAssetFile()
-
Bu yöntem, yalnızca sağlanan MIME türü sağlayıcı tarafından destekleniyor olmasıdır. Arayan (yapıştırmayı yapan uygulama) MIME türü kalıbı. Bir URI'yı pano, aşağıdakileri sağlayabilirse bir
AssetFileDescriptor
dosya işleyicisi döndürür MIME türünü ifade eder ve bu mümkün değilse bir istisna atar.Bu yöntem dosyaların alt bölümlerini işler. Bunu, içerik sağlayıcı panoya kopyalandı.
-
openAssetFile()
- .
Bu yöntem,
openTypedAssetFile()
yönteminin daha genel bir biçimidir. Filtreleme, izin verilen MIME türlerine izin verir ancak dosyaların alt bölümlerini okuyabilir. -
openFile()
- .
Bu,
openAssetFile()
'ın daha genel bir biçimidir. Şunun alt bölümlerini okuyamaz: dosyası olarak da kaydedebilir.
İsterseniz
openPipeHelper()
.
yöntemini dosya tanımlayıcı yönteminizle birlikte kullanabilirsiniz. Bu işlem, yapıştırma uygulamasının akış verilerini
arka plan iş parçacığı kullanıyor. Bu yöntemi kullanmak için
ContentProvider.PipeDataWriter
.
kullanır.
Etkili kopyalama ve yapıştırma işlevi tasarlayın
Uygulamanız için etkili kopyalama ve yapıştırma işlevi tasarlamak için şu noktaları unutmayın:
- Panoda her zaman yalnızca bir klip bulunur. Herhangi bir önceki klibin üzerine yazılır. Kullanıcı, uygulamadan uzaklaştırıp geri dönmeden önce kopyalama işlemini kullanıcının daha önce uygulamanızda kopyaladığı klibi içerir.
-
Klip başına birden fazla
ClipData.Item
nesnesinin amaçlanan amacı şudur: farklı biçimler yerine birden çok seçimin kopyalanıp yapıştırılmasını desteklemez tek bir seçime referansta bulunur. GenellikleClipData.Item
içindeki tüm seçenekleri aynı biçime sahip olmasını sağlayın. Yani, tümü basit metin, içerik ve URI veyaIntent
ve karışık değil. -
Veri sağlarken farklı MIME gösterimleri sunabilirsiniz. MIME türlerini ekleme
ClipDescription
için desteğiniz, ardından MIME türlerini içerik sağlayıcınızda görüntüleyebilirsiniz. -
Panodan veri aldığınızda, uygulamanız gereken bilgileri kontrol etmekten
belirlemek ve hangisinin kullanılacağına karar vermek için kullanılır. Bir
bir klip olup olmadığını kontrol edin. Kullanıcı bir yapıştırma isteğinde bulunursa uygulamanız gerekmez.
tıklayın. MIME türü uyumluysa yapıştırma işlemini gerçekleştirin. Verileri
panoda
coerceToText()
kullanarak metin yazın. Uygulamanız birden çok MIME türü seçerseniz kullanıcının hangi MIME türünü kullanacağını seçmesine izin verebilirsiniz.