Bu belgede, Android'de gerçekleştirdiğiniz temel NFC görevleri açıklanmaktadır. NDEF mesajları biçiminde NFC verilerinin nasıl gönderileceğini ve alınacağını açıklar ve bu özellikleri destekleyen Android çerçeve API'lerini tanımlar. NDEF olmayan verilerle çalışma konusunun da ele alındığı daha ileri düzey konular için Gelişmiş NFC başlıklı makaleyi inceleyin.
Bir NFC etiketinden NDEF verilerini okuma işlemi, keşfedilen NFC etiketlerini analiz eden, verileri uygun şekilde kategorize eden ve kategorize edilmiş verilerle ilgilenen bir uygulamayı başlatan etiket dağıtım sistemi ile gerçekleştirilir. Taranan NFC etiketini işlemek isteyen bir uygulama, intent filtresi bildirebilir ve verileri işlemeyi isteyebilir.
Etiket gönderme sistemi
Android destekli cihazlar, cihazın Ayarlar menüsünde NFC devre dışı bırakılmadığı sürece genellikle ekranın kilidi açıkken NFC etiketlerini arar. Android destekli bir cihaz NFC etiketini algıladığında, kullanıcının hangi uygulamayı kullanacağını sormadan en uygun etkinliğin amaçla ilgilenmesi istenir. Cihazlar NFC etiketlerini çok kısa bir mesafede taradığından, kullanıcıların bir etkinliği manuel olarak seçmesini istemek muhtemelen cihazı etiketten uzaklaştırmalarına ve bağlantıyı kesmelerine neden olur. Etkinlik Seçici'nin görünmesini önlemek için etkinliğinizi yalnızca ilgilendiği NFC etiketlerini işleyecek şekilde geliştirmeniz gerekir.
Android, bu hedefe ulaşmanıza yardımcı olmak için taranan NFC etiketlerini analiz eden, ayrıştıran ve taranan verilerle ilgilenen uygulamaları bulmaya çalışan özel bir etiket gönderme sistemi sunar. Bu işlem şu şekilde yapılır:
- NFC etiketini ayrıştırma ve etiketteki veri yükünü tanımlayan MIME türünü veya URI'yi belirleme.
- MIME türünü veya URI'yi ve yükü bir amaç içinde kapsülleme. Bu ilk iki adım, NFC etiketleri MIME türleri ve URI'lerle nasıl eşlenir? başlıklı makalede açıklanmaktadır.
- Amaca dayalı bir etkinlik başlatır. Bu durum, NFC Etiketleri Uygulamalara Nasıl Gönderilir? başlıklı makalede açıklanmaktadır.
NFC etiketleri, MIME türleri ve URI'lerle nasıl eşlenir?
NFC uygulamalarınızı yazmaya başlamadan önce farklı NFC etiket türlerini, etiket gönderme sisteminin NFC etiketlerini nasıl ayrıştırdığını ve etiket gönderme sisteminin bir NDEF mesajı algıladığında yaptığı özel çalışmayı anlamanız önemlidir. NFC etiketleri çok çeşitli teknolojilerle birlikte gelir ve üzerlerine birçok farklı şekilde veri yazılabilir. Android, NFC Forum tarafından tanımlanan NDEF standardı için en fazla desteği sunar.
NDEF verileri, bir veya daha fazla kayıt (NdefRecord) içeren bir mesaj (NdefMessage) içinde kapsüllenir. Her NDEF kaydı, oluşturmak istediğiniz kayıt türünün spesifikasyonuna göre iyi biçimlendirilmiş olmalıdır. Android, NDEF verisi içermeyen diğer etiket türlerini de destekler. Bu etiketlerle android.nfc.tech paketindeki sınıfları kullanarak çalışabilirsiniz. Bu teknolojiler hakkında daha fazla bilgi edinmek için Gelişmiş NFC konusunu inceleyin. Bu diğer etiket türleriyle çalışmak, etiketlerle iletişim kurmak için kendi protokol yığını yazmanızı gerektirir. Bu nedenle, geliştirme kolaylığı ve Android destekli cihazlar için maksimum destek sağlamak amacıyla mümkün olduğunda NDEF kullanmanızı öneririz.
Not: NDEF spesifikasyonlarının tamamını indirmek için NFC Forum Specifications & Application Documents sitesine gidin ve NDEF kayıtlarının nasıl oluşturulacağıyla ilgili örnekler için Creating common types of NDEF records (Yaygın NDEF kayıt türleri oluşturma) bölümüne bakın.
NFC etiketleri hakkında temel bilgiler edindiğinize göre, aşağıdaki bölümlerde Android'in NDEF biçimli etiketleri nasıl işlediği daha ayrıntılı olarak açıklanmaktadır. Android destekli bir cihaz, NDEF biçimli veriler içeren bir NFC etiketini taradığında mesajı ayrıştırır ve verilerin MIME türünü veya tanımlayıcı URI'sini bulmaya çalışır. Bunu yapmak için sistem, NdefMessage içindeki ilk NdefRecord değerini okuyarak NDEF mesajının tamamının nasıl yorumlanacağını belirler (bir NDEF mesajında birden fazla NDEF kaydı olabilir). İyi biçimlendirilmiş bir NDEF mesajında ilk NdefRecord aşağıdaki alanları içerir:
- 3 bit TNF (Tür Adı Biçimi)
- Değişken uzunluk türü alanının nasıl yorumlanacağını belirtir. Geçerli değerler 1. Tablo'da açıklanmıştır.
- Değişken uzunluk türü
- Kaydın türünü açıklar.
TNF_WELL_KNOWNkullanıyorsanız Kayıt Türü Tanımı'nı (RTD) belirtmek için bu alanı kullanın. Geçerli RTD değerleri Tablo 2'de açıklanmıştır. - Değişken uzunluklu kimlik
- Kaydın benzersiz tanımlayıcısı. Bu alan sık kullanılmaz ancak bir etiketi benzersiz şekilde tanımlamanız gerekiyorsa etiket için bir kimlik oluşturabilirsiniz.
- Değişken uzunluklu yük
- Okumak veya yazmak istediğiniz gerçek veri yükü. Bir NDEF mesajı birden fazla NDEF kaydı içerebilir. Bu nedenle, tam yükün NDEF mesajının ilk NDEF kaydında olduğunu varsaymayın.
Etiket gönderme sistemi, bir MIME türünü veya URI'yi NDEF mesajıyla eşleştirmek için TNF ve tür alanlarını kullanır. Başarılı olursa bu bilgileri gerçek yükle birlikte bir ACTION_NDEF_DISCOVERED amacının içine yerleştirir. Ancak, etiket gönderme sisteminin ilk NDEF kaydına göre veri türünü belirleyemediği durumlar olabilir. Bu durum, NDEF verileri bir MIME türü veya URI ile eşlenemediğinde ya da NFC etiketinde başlangıçta NDEF verileri bulunmadığında ortaya çıkar. Bu gibi durumlarda, etiketin teknolojileri ve yük hakkında bilgi içeren bir Tag nesnesi, bunun yerine bir ACTION_TECH_DISCOVERED amacının içine yerleştirilir.
Tablo 1, etiket gönderme sisteminin TNF ve tür alanlarını MIME türleriyle veya URI'lerle nasıl eşlediğini açıklar. Ayrıca, hangi TNF'lerin MIME türü veya URI ile eşleştirilemeyeceğini de açıklar.
Bu durumlarda etiket gönderme sistemi ACTION_TECH_DISCOVERED'ya geri döner.
Örneğin, etiket gönderme sistemi TNF_ABSOLUTE_URI türünde bir kayda rastlarsa bu kaydın değişken uzunluklu tür alanını bir URI'ye eşler. Etiket gönderme sistemi, bu URI'yi ACTION_NDEF_DISCOVERED amacının veri alanında, etiketle ilgili diğer bilgilerle (ör. yük) birlikte kapsar. Diğer yandan, TNF_UNKNOWN türünde bir kayıtla karşılaşırsa etiketin teknolojilerini kapsayan bir amaç oluşturur.
Tablo 1. Desteklenen TNFs ve eşlemeleri
| Tür Adı Biçimi (TNF) | Eşleme |
|---|---|
TNF_ABSOLUTE_URI |
Tür alanına göre URI. |
TNF_EMPTY |
ACTION_TECH_DISCOVERED'ya geri döner. |
TNF_EXTERNAL_TYPE |
Tür alanındaki URN'ye dayalı URI. URN, NDEF türü alanına kısaltılmış biçimde kodlanır: <domain_name>:<service_name>.
Android bunu şu biçimde bir URI'ye eşler:
vnd.android.nfc://ext/<domain_name>:<service_name>. |
TNF_MIME_MEDIA |
Tür alanına göre MIME türü. |
TNF_UNCHANGED |
İlk kayıtta geçersiz olduğundan ACTION_TECH_DISCOVERED değerine geri döner. |
TNF_UNKNOWN |
ACTION_TECH_DISCOVERED'ya geri döner. |
TNF_WELL_KNOWN |
Tür alanında ayarladığınız Kayıt Türü Tanımı'na (RTD) bağlı olarak MIME türü veya URI. Kullanılabilir hazır teklif istekleri ve bunların eşlemeleri hakkında daha fazla bilgi için Tablo 2'ye bakın. |
Tablo 2. TNF_WELL_KNOWN için desteklenen RTD'ler ve bunların eşlemeleri
| Kayıt Türü Tanımı (RTD) | Eşleme |
|---|---|
RTD_ALTERNATIVE_CARRIER |
ACTION_TECH_DISCOVERED'ya geri döner. |
RTD_HANDOVER_CARRIER |
ACTION_TECH_DISCOVERED'ya geri döner. |
RTD_HANDOVER_REQUEST |
ACTION_TECH_DISCOVERED'ya geri döner. |
RTD_HANDOVER_SELECT |
ACTION_TECH_DISCOVERED'ya geri döner. |
RTD_SMART_POSTER |
Yük ayrıştırılarak oluşturulan URI. |
RTD_TEXT |
text/plain öğesinin MIME türü. |
RTD_URI |
Yüke dayalı URI. |
NFC etiketleri uygulamalara nasıl gönderilir?
Etiket gönderme sistemi, NFC etiketini ve kişisel verilerini kapsayan bir amaç oluşturmayı tamamladığında bu amacı, amaç için filtreleme yapan ilgili bir uygulamaya gönderir. Amacı birden fazla uygulama işleyebiliyorsa kullanıcı, etkinliği seçebilmesi için Etkinlik Seçici'yi görür. Etiket gönderme sistemi, öncelik sırası en yüksekten en düşüğe doğru olmak üzere üç amaç tanımlar:
-
ACTION_NDEF_DISCOVERED: Bu amaç, NDEF yükü içeren bir etiket tarandığında ve tanınan bir türde olduğunda bir Etkinliği başlatmak için kullanılır. Bu, en yüksek öncelikli amaçtır ve etiket gönderme sistemi, mümkün olduğunda diğer tüm amaçlardan önce bu amaçla bir Etkinlik başlatmaya çalışır.Not: Android 16'dan itibaren, web bağlantılarını depolayan NFC etiketlerinin taranması (yani URI şeması "http://" veya "https://" ise)
ACTION_NDEF_DISCOVEREDniyeti yerineACTION_VIEWniyetini tetikler. Android 17'den itibaren bu tür bir etiketin taranması,ACTION_VIEWamacını tetiklemek için açık kullanıcı etkileşimi gerektiren bir "bağlantıyı aç" bildirimi gösterir. ACTION_TECH_DISCOVERED:ACTION_NDEF_DISCOVEREDamacını işlemek için herhangi bir etkinlik kaydedilmezse etiket gönderme sistemi bu amaçla bir uygulamayı başlatmaya çalışır. Taranan etikette bir MIME türü veya URI ile eşlenemeyen NDEF verileri varsa ya da etikette NDEF verileri yoksa ancak bilinen bir etiket teknolojisine aitse bu amaç doğrudan (önceACTION_NDEF_DISCOVEREDbaşlatılmadan) da başlatılır.ACTION_TAG_DISCOVERED: Bu amaç,ACTION_NDEF_DISCOVEREDveyaACTION_TECH_DISCOVEREDamaçlarını işleyen etkinlik yoksa başlatılır.
Etiket gönderme sisteminin temel işleyiş şekli şöyledir:
- NFC etiketi ayrıştırılırken (
ACTION_NDEF_DISCOVEREDveyaACTION_TECH_DISCOVERED) etiket gönderme sistemi tarafından oluşturulan intent ile bir Activity başlatmaya çalışın. - Bu amaç için etkinlik filtresi yoksa bir uygulama amaç için filtre uygulayana veya etiket gönderme sistemi olası tüm amaçları deneyene kadar bir sonraki en düşük öncelikli amaçla (
ACTION_TECH_DISCOVEREDveyaACTION_TAG_DISCOVERED) bir Etkinlik başlatmayı deneyin. - Amaçlardan herhangi biri için uygulama filtresi yoksa hiçbir şey yapmayın.
Mümkün olduğunda, üçü arasında en spesifik olan ACTION_NDEF_DISCOVERED niyeti ve NDEF mesajlarıyla çalışın. Bu amaç, uygulamanızı diğer iki amaçtan daha uygun bir zamanda başlatmanıza olanak tanıyarak kullanıcıya daha iyi bir deneyim sunar.
Android manifest dosyasında NFC erişimi isteğinde bulunma
Bir cihazın NFC donanımına erişip NFC intent'lerini düzgün şekilde işleyebilmek için AndroidManifest.xml dosyanızda aşağıdaki öğeleri tanımlayın:
- NFC donanımına erişmek için NFC
<uses-permission>öğesi:<uses-permission android:name="android.permission.NFC" />
- Android 17'den (API düzeyi 37) itibaren, bir etkinliğin NFC intent'i gönderebilmesi için uygulama SDK >
Build.VERSION_CODES.BAKLAVA'yı hedefliyorsaandroid.permission.DISPATCH_NFC_MESSAGEizniyle korunması gerekir. Bu sayede, etkinliğinize yalnızca NFC sistem hizmeti niyet gönderebilir. Ayrıca sistem, durdurulmuş durumda olan uygulamalara (ör. uygulama kullanıcı tarafından hiç başlatılmamışsa veya zorla durdurulmuşsa) NFC amaçlarını göndermez.<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> ... </activity>
- Uygulamanızın destekleyebileceği minimum SDK sürümü. API düzeyi 9 yalnızca
ACTION_TAG_DISCOVEREDüzerinden sınırlı etiket göndermeyi destekler ve yalnızcaEXTRA_NDEF_MESSAGESekstrası aracılığıyla NDEF mesajlarına erişim sağlar. Diğer etiket özellikleri veya G/Ç işlemleri erişilebilir değildir. API düzeyi 10, kapsamlı okuyucu/yazıcı desteğinin yanı sıra ön planda NDEF gönderme özelliğini içerir. API düzeyi 14 ise NDEF kayıtları oluşturmak için ek kolaylık yöntemleri sunar.<uses-sdk android:minSdkVersion="10"/> - Uygulamanızın Google Play'de yalnızca NFC donanımına sahip cihazlarda görünmesi için
uses-featureöğesi:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Uygulamanızda NFC işlevi kullanılıyorsa ancak bu işlev uygulamanız için önemli değilse
uses-featureöğesini atlayabilir vegetDefaultAdapter()öğesininnullolup olmadığını kontrol ederek çalışma zamanında NFC'nin kullanılabilirliğini kontrol edebilirsiniz.
NFC amaçları için filtreleme
Uygulamanızın, işlemek istediğiniz bir NFC etiketi tarandığında başlatılması için Android manifestindeki bir, iki veya üç NFC intent'ini filtreleyebilir. Ancak, uygulamanızın ne zaman başlayacağını en iyi şekilde kontrol etmek için genellikle ACTION_NDEF_DISCOVERED amacına göre filtre uygulamak istersiniz. ACTION_TECH_DISCOVERED amacı, ACTION_NDEF_DISCOVERED için yedek olarak kullanılır. Bu amaç, ACTION_NDEF_DISCOVERED için uygulama filtresi olmadığında veya yük NDEF olmadığında kullanılır. ACTION_TAG_DISCOVERED için filtreleme genellikle filtrelemek için çok genel bir kategoridir. Birçok uygulama, ACTION_TAG_DISCOVERED'den önce ACTION_NDEF_DISCOVERED veya ACTION_TECH_DISCOVERED için filtreleme yapar. Bu nedenle, uygulamanızın başlatılma olasılığı düşüktür. ACTION_TAG_DISCOVERED yalnızca son çare olarak kullanılabilir
ACTION_NDEF_DISCOVERED veya ACTION_TECH_DISCOVERED amacını işlemek için başka uygulama yüklenmemişse uygulamaları filtrelemek için.
NFC etiketi dağıtımları değişiklik gösterdiğinden ve çoğu zaman sizin kontrolünüzde olmadığından bu her zaman mümkün değildir. Bu nedenle, gerektiğinde diğer iki amaca geri dönebilirsiniz. Yazılan etiket ve veri türleri üzerinde kontrol sahibi olduğunuzda, etiketlerinizi biçimlendirmek için NDEF kullanmanız önerilir. Aşağıdaki bölümlerde her bir amaç türüne göre nasıl filtreleme yapılacağı açıklanmaktadır.
ACTION_NDEF_DISCOVERED
ACTION_NDEF_DISCOVERED intent'leri için filtre uygulamak üzere, filtrelemek istediğiniz veri türüyle birlikte intent filtresini tanımlayın. Aşağıdaki örnek filtreler, ACTION_NDEF_DISCOVERED MIME türüne sahip text/plain amaçları içindir:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter> </activity>
Aşağıdaki örnek, https://developer.android.com/index.html biçimindeki bir URI'yi filtreler.
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter> </activity>
ACTION_TECH_DISCOVERED
Etkinliğiniz ACTION_TECH_DISCOVERED intent'i için filtre uyguluyorsa tech-list kümesi içinde etkinliğinizin desteklediği teknolojileri belirten bir XML kaynak dosyası oluşturmanız gerekir. Etkinliğinizin eşleşme olarak kabul edilmesi için tech-list kümesinin, getTechList() çağrılarak elde edilebilen etiket tarafından desteklenen teknolojilerin bir alt kümesi olması gerekir.
Örneğin, taranan etiket MifareClassic, NdefFormatable ve NfcA'yı destekliyorsa etkinliğinizin eşleştirilmesi için tech-list kümenizin üç teknolojinin tamamını, ikisini veya birini (başka hiçbir şeyi değil) belirtmesi gerekir.
Aşağıdaki örnekte tüm teknolojiler tanımlanmaktadır. NFC etiketiniz tarafından desteklenmeyenleri kaldırmanız gerekir. Bu dosyayı (istediğiniz adı verebilirsiniz) <project-root>/res/xml klasörüne kaydedin.
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech> <tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
Birden fazla tech-list kümesi de belirtebilirsiniz. tech-list
kümelerinin her biri bağımsız olarak değerlendirilir ve herhangi bir tech-list kümesi, getTechList() tarafından döndürülen teknolojilerin bir alt kümesi ise etkinliğiniz eşleşme olarak kabul edilir. Bu, eşleştirme teknolojileri için AND ve OR
anlamlarını sağlar. Aşağıdaki örnek, NfcA ve Ndef teknolojilerini veya NfcB ve Ndef teknolojilerini destekleyebilen etiketlerle eşleşir:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> </resources>
AndroidManifest.xml dosyanızda, az önce oluşturduğunuz kaynak dosyasını <activity> öğesinin içindeki <meta-data> öğesinde aşağıdaki örnekteki gibi belirtin:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> </activity>
Etiket teknolojileri ve ACTION_TECH_DISCOVERED amacı ile çalışma hakkında daha fazla bilgi için Gelişmiş NFC belgesindeki Desteklenen Etiket Teknolojileriyle Çalışma bölümüne bakın.
ACTION_TAG_DISCOVERED
Not: ACTION_TAG_DISCOVERED
Android 17'den (API düzeyi 37) itibaren kullanımdan kaldırılmıştır. Bunun yerine ACTION_NDEF_DISCOVERED veya ACTION_TECH_DISCOVERED kullanın.
ACTION_TAG_DISCOVERED için filtrelemek üzere aşağıdaki amaç filtresini kullanın:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter> </activity>
ACTION_VIEW
Android 16'dan itibaren, web bağlantılarını depolayan NFC etiketlerinin taranması (yani URI şeması "http://" veya "https://" ise) ACTION_NDEF_DISCOVERED amacı yerine ACTION_VIEW amacını tetikler. Android 17'den itibaren bu tür bir etiketin taranması, ACTION_VIEW amacını tetiklemek için açık kullanıcı etkileşimi gerektiren bir "bağlantıyı aç" bildirimi gösterir. ACTION_VIEW için filtreleme yapmak istiyorsanız
this bölümüne bakın. URL için uygulamanızı açmak üzere Android app links öğesini kullanın.
Intent'lerden bilgi edinme
Bir etkinlik NFC intent'i nedeniyle başlıyorsa taranan NFC etiketiyle ilgili bilgileri intent'ten alabilirsiniz. Niyetler, taranan etikete bağlı olarak aşağıdaki ekstraları içerebilir:
EXTRA_TAG(zorunlu): Taranan etiketi temsil eden birTagnesnesi.EXTRA_NDEF_MESSAGES(isteğe bağlı): Etiketten ayrıştırılan NDEF mesajları dizisi. Bu ek,ACTION_NDEF_DISCOVEREDamaçlarında zorunludur.EXTRA_ID(isteğe bağlı): Etiketin düşük düzeyli kimliği.
Bu ekstraları almak için etkinliğinizin NFC amaçlarından biriyle başlatılıp başlatılmadığını kontrol ederek bir etiketin tarandığından emin olun ve ardından amaçtan ekstraları alın. Aşağıdaki örnekte ACTION_NDEF_DISCOVERED intent'i kontrol edilir ve intent extra'dan NDEF mesajları alınır.
Kotlin
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) ... if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMessages -> val messages: List<NdefMessage> = rawMessages.map { it as NdefMessage } // Process the messages array. ... } } }
Java
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); ... if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMessages != null) { NdefMessage[] messages = new NdefMessage[rawMessages.length]; for (int i = 0; i < rawMessages.length; i++) { messages[i] = (NdefMessage) rawMessages[i]; } // Process the messages array. ... } } }
Alternatif olarak, amaçtan bir Tag nesnesi de alabilirsiniz. Bu nesne, yükü içerir ve etiketin teknolojilerini listelemenize olanak tanır:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Yaygın NDEF kaydı türleri oluşturma
Bu bölümde, NFC etiketlerine yazarken size yardımcı olması için yaygın NDEF kaydı türlerinin nasıl oluşturulacağı açıklanmaktadır. Android 4.0'dan (API seviyesi 14) itibaren, URI kayıtlarını otomatik olarak oluşturmanıza yardımcı olmak için createUri() yöntemi kullanılabilir. Android 4.1'den (API düzeyi 16) itibaren,
createExternal()
ve createMime(), MIME ve harici tür NDEF kayıtları oluşturmanıza yardımcı olmak için kullanılabilir. NDEF kayıtlarını manuel olarak oluştururken hata yapmamak için mümkün olduğunda bu yardımcı yöntemleri kullanın.
Bu bölümde, kayıt için ilgili intent filtresinin nasıl oluşturulacağı da açıklanmaktadır. Bu NDEF kaydı örneklerinin tümü, etikete yazdığınız NDEF mesajının ilk NDEF kaydında olmalıdır.
TNF_ABSOLUTE_URI
Not: Daha verimli olduğu için TNF_ABSOLUTE_URI yerine RTD_URI türünü kullanmanızı öneririz.
Aşağıdaki şekilde TNF_ABSOLUTE_URI NDEF kaydı oluşturabilirsiniz:
:
Kotlin
val uriRecord = ByteArray(0).let { emptyByteArray -> NdefRecord( TNF_ABSOLUTE_URI, "https://developer.android.com/index.html".toByteArray(Charset.forName("US-ASCII")), emptyByteArray, emptyByteArray ) }
Java
NdefRecord uriRecord = new NdefRecord( NdefRecord.TNF_ABSOLUTE_URI , "https://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")), new byte[0], new byte[0]);
Önceki NDEF kaydı için intent filtresi aşağıdaki gibi görünür:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter> </activity>
TNF_MIME_MEDIA
Aşağıdaki yöntemlerle TNF_MIME_MEDIA NDEF kaydı oluşturabilirsiniz:
createMime() yöntemini kullanarak:
Kotlin
val mimeRecord = NdefRecord.createMime( "application/vnd.com.example.android.beam", "Beam me up, Android".toByteArray(Charset.forName("US-ASCII")) )
Java
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam", "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
NdefRecord öğesini manuel olarak oluşturma:
Kotlin
val mimeRecord = Charset.forName("US-ASCII").let { usAscii -> NdefRecord( NdefRecord.TNF_MIME_MEDIA, "application/vnd.com.example.android.beam".toByteArray(usAscii), ByteArray(0), "Beam me up, Android!".toByteArray(usAscii) ) }
Java
NdefRecord mimeRecord = new NdefRecord( NdefRecord.TNF_MIME_MEDIA , "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")), new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
Önceki NDEF kaydı için intent filtresi aşağıdaki gibi görünür:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/vnd.com.example.android.beam" /> </intent-filter> </activity>
TNF_WELL_KNOWN with RTD_TEXT
Aşağıdaki şekilde TNF_WELL_KNOWN NDEF kaydı oluşturabilirsiniz:
Kotlin
fun createTextRecord(payload: String, locale: Locale, encodeInUtf8: Boolean): NdefRecord { val langBytes = locale.language.toByteArray(Charset.forName("US-ASCII")) val utfEncoding = if (encodeInUtf8) Charset.forName("UTF-8") else Charset.forName("UTF-16") val textBytes = payload.toByteArray(utfEncoding) val utfBit: Int = if (encodeInUtf8) 0 else 1 shl 7 val status = (utfBit + langBytes.size).toChar() val data = ByteArray(1 + langBytes.size + textBytes.size) data[0] = status.toByte() System.arraycopy(langBytes, 0, data, 1, langBytes.size) System.arraycopy(textBytes, 0, data, 1 + langBytes.size, textBytes.size) return NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, ByteArray(0), data) }
Java
public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; }
Önceki NDEF kaydı için intent filtresi aşağıdaki gibi görünür:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> </activity>
RTD_URI ile TNF_WELL_KNOWN
Aşağıdaki yöntemlerle TNF_WELL_KNOWN NDEF kaydı oluşturabilirsiniz:
createUri(String) yöntemini kullanarak:
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
createUri(Uri) yöntemini kullanarak:
Kotlin
val rtdUriRecord2 = Uri.parse("https://example.com").let { uri -> NdefRecord.createUri(uri) }
Java
Uri uri = Uri.parse("https://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
NdefRecord öğesini manuel olarak oluşturma:
Kotlin
val uriField = "example.com".toByteArray(Charset.forName("US-ASCII")) val payload = ByteArray(uriField.size + 1) //add 1 for the URI Prefix payload [0] = 0x01 //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.size) //appends URI to payload val rtdUriRecord = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, ByteArray(0), payload)
Java
byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix payload[0] = 0x01; //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord( NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
Önceki NDEF kaydı için intent filtresi aşağıdaki gibi görünür:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="example.com" android:pathPrefix="" /> </intent-filter> </activity>
TNF_EXTERNAL_TYPE
Aşağıdaki yöntemlerle TNF_EXTERNAL_TYPE NDEF kaydı oluşturabilirsiniz:
createExternal() yöntemini kullanarak:
Kotlin
var payload: ByteArray //assign to your data val domain = "com.example" //usually your app's package name val type = "externalType" val extRecord = NdefRecord.createExternal(domain, type, payload)
Java
byte[] payload; //assign to your data String domain = "com.example"; //usually your app's package name String type = "externalType"; NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
NdefRecord öğesini manuel olarak oluşturma:
Kotlin
var payload: ByteArray ... val extRecord = NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".toByteArray(Charset.forName("US-ASCII")), ByteArray(0), payload )
Java
byte[] payload; ... NdefRecord extRecord = new NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".getBytes(Charset.forName("US-ASCII")), new byte[0], payload);
Önceki NDEF kaydı için intent filtresi aşağıdaki gibi görünür:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="vnd.android.nfc" android:host="ext" android:pathPrefix="/com.example:externalType"/> </intent-filter> </activity>
Hem Android destekli hem de Android destekli olmayan cihazları daha iyi desteklemek için daha genel NFC etiketi dağıtımlarında TNF_EXTERNAL_TYPE kullanın.
Not: TNF_EXTERNAL_TYPE için URN'ler standart biçimde urn:nfc:ext:example.com:externalType olur. Ancak NFC Forum RTD spesifikasyonu, URN'nin urn:nfc:ext: bölümünün NDEF kaydından çıkarılması gerektiğini belirtir. Bu nedenle, iki nokta üst üste ile ayrılmış alan (örnekte example.com) ve tür (örnekte externalType) bilgilerini sağlamanız yeterlidir.
TNF_EXTERNAL_TYPE gönderilirken Android, urn:nfc:ext:example.com:externalType
URN'sini vnd.android.nfc://ext/example.com:externalType URI'sine dönüştürür. Bu, örnekteki intent filtresinin bildirdiği URI'dir.
Android uygulama kayıtları
Android 4.0'da (API düzeyi 14) kullanıma sunulan Android Uygulama Kaydı (AAR), bir NFC etiketi tarandığında uygulamanızın başlatılacağına dair daha güçlü bir kesinlik sağlar. AAR'de, NDEF kaydına yerleştirilmiş bir uygulamanın paket adı bulunur. Android, AAR'ler için NDEF mesajının tamamında arama yaptığından NDEF mesajınızın herhangi bir NDEF kaydına AAR ekleyebilirsiniz. Bir AAR bulursa uygulamayı AAR'nin içindeki paket adına göre başlatır. Uygulama cihazda yoksa Google Play başlatılarak uygulama indirilir.
Diğer uygulamaların aynı amaç için filtreleme yapmasını ve dağıttığınız belirli etiketleri işlemesini önlemek istiyorsanız AAR'ler kullanışlıdır. Paket adı kısıtlaması nedeniyle AAR'ler yalnızca uygulama düzeyinde desteklenir. Amaç filtresinde olduğu gibi Activity düzeyinde desteklenmez. Bir intent'i Activity düzeyinde işlemek istiyorsanız intent filtrelerini kullanın.
Bir etiket AAR içeriyorsa etiket gönderme sistemi aşağıdaki şekilde gönderim yapar:
- Normalde olduğu gibi bir amaç filtresi kullanarak Etkinlik başlatmayı deneyin. Amaca uygun Etkinlik, AAR ile de eşleşiyorsa Etkinliği başlatın.
- Intent'i filtreleyen etkinlik AAR ile eşleşmiyorsa, birden fazla etkinlik intent'i işleyebiliyorsa veya hiçbir etkinlik intent'i işlemiyorsa AAR tarafından belirtilen uygulamayı başlatın.
- AAR ile başlatılabilecek bir uygulama yoksa Google Play'e giderek AAR'ye dayalı uygulamayı indirin.
Not: NFC etiketi algılandığında ön plan etkinliğinin öncelikli olmasını sağlayan ön plan gönderme sistemi ile AAR'leri ve amaç gönderme sistemini geçersiz kılabilirsiniz. Bu yöntemde, AAR'leri ve amaç gönderme sistemini geçersiz kılmak için etkinliğin ön planda olması gerekir.
Yine de AAR içermeyen taranmış etiketleri filtrelemek istiyorsanız amaç filtrelerini normal şekilde bildirebilirsiniz. Bu, uygulamanız AAR içermeyen diğer etiketlerle ilgileniyorsa yararlıdır. Örneğin, uygulamanızın, dağıttığınız tescilli etiketlerin yanı sıra üçüncü taraflarca dağıtılan genel etiketleri de işlemesini garanti etmek isteyebilirsiniz. AAR'lerin Android 4.0 veya sonraki sürümlerdeki cihazlara özel olduğunu unutmayın. Bu nedenle, etiketleri dağıtırken en geniş cihaz aralığını desteklemek için büyük olasılıkla AAR'ler ile MIME türleri/URI'lerin bir kombinasyonunu kullanmak isteyeceksiniz. Ayrıca, NFC etiketlerini dağıtırken en çok cihazda (Android destekli ve diğer cihazlar) desteği etkinleştirmek için NFC etiketlerinize nasıl yazmak istediğinizi düşünün. Bunu, uygulamaların ayırt etmesini kolaylaştırmak için nispeten benzersiz bir MIME türü veya URI tanımlayarak yapabilirsiniz.
Android, AAR oluşturmak için basit bir API sağlar: createApplicationRecord(). Tek yapmanız gereken AAR'yi NdefMessage'nize yerleştirmek. NdefMessage içinde AAR dışında kayıt yoksa NdefMessage ilk kaydını kullanmak istemiyorsunuz. Bunun nedeni, Android sisteminin, uygulamaların filtreleyeceği bir amaç oluşturmak için kullanılan etiketin MIME türünü veya URI'sini belirlemek üzere bir NdefMessage öğesinin ilk kaydını kontrol etmesidir. Aşağıdaki kodda AAR'nin nasıl oluşturulacağı gösterilmektedir:
Kotlin
val msg = NdefMessage( arrayOf( ..., NdefRecord.createApplicationRecord("com.example.android.beam") ) )
Java
NdefMessage msg = new NdefMessage( new NdefRecord[] { ..., NdefRecord.createApplicationRecord("com.example.android.beam")} ); )
NFC etiketi taraması için uygulamaların izin verilenler listesi
Android 16'dan itibaren, bir uygulama NFC etiketlerini taramak için ilk NFC amacını aldığında kullanıcılar bilgilendirilir. Kullanıcıya, uygulamaya bildirimde artık NFC etiketlerini taramasına izin vermeme seçeneği sunulur.
- Uygulamalar, kullanıcının
NfcAdapter.isTagIntentAllowed()kullanarak uygulamanın NFC etiketlerini taramasına izin verip vermediğini kontrol edebilir. - Uygulamalar,
ACTION_CHANGE_TAG_INTENT_PREFERENCEamacını göndererek kullanıcıdan NFC etiketi taramasına tekrar izin vermesini isteyebilir.
Not: NFC etiketi tarama uygulaması izin verilenler listesine Settings > Apps > Special app access > Launch via NFC bölümünden erişilebilir.