Este documento descreve as tarefas básicas de NFC que são realizadas no Android. Ele explica como enviar receber dados NFC na forma de mensagens NDEF e descrever as APIs do framework do Android que oferecem suporte esses recursos. Para tópicos mais avançados, incluindo uma discussão sobre como trabalhar com dados que não são NDEF, consulte NFC avançada.
Há dois casos de uso principais ao trabalhar com dados NDEF e Android:
- Leitura de dados NDEF de uma tag NFC
- Envio de mensagens NDEF de um dispositivo para outro com o Android BeamTM (em inglês)
A leitura de dados NDEF de uma tag NFC é processada com o envio de tag Google, que analisa tags NFC descobertas, categoriza os dados de maneira apropriada e inicia um aplicativo interessado nos dados categorizados. Um aplicativo que quer lidar com tag NFC lida pode declarar um filtro de intent e para manipular os dados.
O recurso Android BeamTM permite que um dispositivo envie uma mensagem NDEF para outro dispositivo tocando fisicamente nos dispositivos. Essa interação facilita enviar dados do que outras tecnologias sem fio, como Bluetooth, porque com NFC, nenhum dispositivo manual descoberta ou pareamento. A conexão é iniciada automaticamente quando dois dispositivos são conectados dentro do intervalo. O Android Beam está disponível por meio de um conjunto de APIs NFC, de modo que qualquer aplicativo pode transmitir informações entre dispositivos. Por exemplo, os aplicativos Contatos, Navegador e YouTube usam Android Beam para compartilhar contatos, páginas da Web e vídeos com outros dispositivos.
O sistema de expedição de etiquetas
Dispositivos com tecnologia Android geralmente procuram tags NFC quando a tela está desbloqueado, a menos que a NFC esteja desativada no menu "Configurações" do dispositivo. Quando um dispositivo Android descobre uma tag NFC, o comportamento desejado é fazer com que a atividade mais apropriada processe a intent sem perguntar ao usuário qual aplicativo usar. Como os dispositivos leem tags NFC a um alcance muito curto, é provável que fazer com que os usuários selecionar uma atividade os forçaria a afastar o dispositivo da tag e interromperia a conexão. Você deve desenvolver sua atividade para lidar apenas com as tags NFC que importam para sua atividade impedir que o Seletor de atividades apareça.
Para ajudar com isso, o Android oferece um sistema especial de distribuição de tags que analisa etiquetas NFC, as analisa e tenta localizar aplicativos que estejam interessados nos dados digitalizados. Ela faz isso:
- Analisando a tag NFC e descobrindo o tipo MIME ou um URI que identifica a carga útil dos dados na tag.
- Encapsula o tipo MIME ou o URI e o payload em um intent. As duas primeiras As etapas são descritas em Como as tags NFC são mapeadas para tipos MIME e URIs.
- Inicia uma atividade com base no intent. Isso é descrito em Como as etiquetas NFC são expedidas para aplicativos.
Como etiquetas NFC são mapeadas em tipos MIME e URIs
Antes de começar a criar aplicativos NFC, é importante entender as diferentes tipos de etiquetas NFC, como o sistema de expedição de etiquetas analisa etiquetas NFC e o trabalho especial que a etiqueta que o sistema de expedição faz quando detecta uma mensagem NDEF. As etiquetas NFC vêm em um uma ampla gama de tecnologias e podem gravar dados nelas de muitas maneiras diferentes. O Android tem mais compatibilidade com o padrão NDEF, que é definido pelo NFC Forum (link em inglês).
Os dados NDEF são encapsulados em uma mensagem (NdefMessage
) que contém um
ou mais registros (NdefRecord
). Cada registro NDEF precisa estar bem formado de acordo com
a especificação do tipo de registro que você quer criar. Android
também oferece suporte a outros tipos de tags que não contêm dados NDEF, com os quais você pode trabalhar usando
as classes no pacote android.nfc.tech
. Para saber mais
sobre essas tecnologias, consulte o tópico NFC avançada. Trabalhar com esses outros tipos de tags envolve
escrever sua própria pilha de protocolos para se comunicar com as tags; portanto, recomendamos usar o NDEF
possível para facilitar o desenvolvimento e oferecer o máximo de suporte possível para dispositivos com tecnologia Android.
Observação: Para fazer o download das especificações completas do NDEF, acesse o Fórum de especificações e Application Documents (em inglês) e consulte Como criar tipos comuns de registros NDEF para exemplos de como e criar registros NDEF.
Agora que você conhece as etiquetas NFC, as seções a seguir descrevem em mais detalhes como
O Android processa tags formatadas como NDEF. Quando um dispositivo Android faz a leitura de uma tag NFC contendo NDEF
dados formatados, ele analisa a mensagem e tenta descobrir o tipo MIME dos dados ou identificando
URI. Para fazer isso, o sistema lê o primeiro NdefRecord
dentro do NdefMessage
para determinar como interpretar toda a mensagem NDEF (uma mensagem NDEF pode
têm vários registros NDEF). Em uma mensagem NDEF bem formada, o primeiro NdefRecord
contém os seguintes campos:
- Formato de nome de tipo (TNF, na sigla em inglês) de 3 bits
- Indica como interpretar o campo de tipo de comprimento variável. Os valores válidos são descritos na Tabela 1.
- Tipo de comprimento variável
- Descreve o tipo do registro. Se estiver usando
TNF_WELL_KNOWN
, use este campo para especificar a definição de tipo de registro (RTD, na sigla em inglês). Os valores de RTD válidos são descritos na Tabela 2. - ID de comprimento variável
- Um identificador exclusivo para o registro. Esse campo não é usado com frequência, mas Se você precisar identificar uma tag de forma exclusiva, crie um ID para ela.
- Payload de comprimento variável
- O payload real que você quer ler ou gravar. Um NDEF A mensagem pode conter vários registros NDEF, portanto, não presuma que o payload completo está no primeiro NDEF. da mensagem NDEF.
O sistema de expedição de etiquetas usa os campos TNF e tipo para tentar mapear um tipo MIME ou URI para a
Mensagem NDEF. Se bem-sucedido, ele encapsula essas informações dentro de um intent ACTION_NDEF_DISCOVERED
com o payload real. No entanto, não há
são casos em que o sistema de expedição de etiquetas não consegue determinar o tipo de dados com base no primeiro NDEF
registro. Isso acontece quando os dados NDEF não podem ser mapeados para um tipo MIME ou URI ou quando o
A tag NFC não contém dados NDEF. Nesses casos, um objeto Tag
com informações sobre as tecnologias e o payload da tag são
encapsulados em uma intent ACTION_TECH_DISCOVERED
.
A Tabela 1 descreve como o sistema de expedição de etiquetas mapeia o TNF e o tipo
campos a tipos MIME ou URIs. Ela também descreve quais TNFs não podem ser mapeados para um tipo MIME ou URI.
Nesses casos, o sistema de expedição de etiquetas volta para
ACTION_TECH_DISCOVERED
:
Por exemplo, se o sistema de expedição de etiquetas encontrar um registro do tipo TNF_ABSOLUTE_URI
, ele mapeará o campo de tipo de comprimento variável desse registro.
em um URI. O sistema de expedição de etiquetas encapsula esse URI no campo de dados de uma intent ACTION_NDEF_DISCOVERED
, com outras informações sobre a tag.
como o payload. Por outro lado, se encontrar um registro do tipo TNF_UNKNOWN
, ele criará uma intent que encapsula as tecnologias da tag.
como alternativa.
Formato de nome de tipo (TNF) | Mapeamento |
---|---|
TNF_ABSOLUTE_URI |
URI com base no campo de tipo. |
TNF_EMPTY |
Volta para ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
URI com base no URN no campo de tipo. O URN é codificado no campo de tipo NDEF
uma forma abreviada: <domain_name>:<service_name> .
O Android mapeia isso para um URI no formato:
vnd.android.nfc://ext/<domain_name>:<service_name> : |
TNF_MIME_MEDIA |
Tipo MIME com base no campo de tipo. |
TNF_UNCHANGED |
Inválido no primeiro registro, então volta para
ACTION_TECH_DISCOVERED : |
TNF_UNKNOWN |
Volta para ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN |
Tipo MIME ou URI, dependendo da definição de tipo de registro (RTD, na sigla em inglês), que você define no type. Consulte a Tabela 2 para mais informações RTDs disponíveis e seus mapeamentos. |
Definição de tipo de registro (RTD) | Mapeamento |
---|---|
RTD_ALTERNATIVE_CARRIER |
Volta para ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER |
Volta para ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST |
Volta para ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT |
Volta para ACTION_TECH_DISCOVERED . |
RTD_SMART_POSTER |
URI com base na análise do payload. |
RTD_TEXT |
Tipo MIME de text/plain . |
RTD_URI |
URI com base no payload. |
Como etiquetas NFC são expedidas para aplicativos
Quando o sistema de expedição de etiquetas termina, criando uma intenção que encapsula a etiqueta NFC e seu informações de identificação, ele envia a intenção para um aplicativo interessado que filtros para a intent. Se mais de um aplicativo puder processar a intent, o Seletor de atividade é apresentado para que o usuário possa selecionar a atividade. O sistema de expedição de etiquetas define três intents, que estão listados em ordem de prioridade, da maior para a menor:
-
ACTION_NDEF_DISCOVERED
: essa intent é usada para iniciar uma Atividade quando uma etiqueta que contém um payload NDEF é lida e é de um tipo reconhecido. Isso é o intent de prioridade mais alta, e o sistema de expedição de etiquetas tenta iniciar uma atividade com este antes de qualquer outra, sempre que possível. ACTION_TECH_DISCOVERED
: se nenhuma atividade for registrada no lidar com oACTION_NDEF_DISCOVERED
o sistema de expedição de etiquetas tentará iniciar um aplicativo com essa intent. Isso também será iniciada diretamente (sem iniciarACTION_NDEF_DISCOVERED
primeiro) se a tag que for lida contém dados NDEF que não podem ser mapeados para um tipo MIME ou URI ou se a etiqueta não contiver NDEF mas de uma tecnologia de tags conhecida.ACTION_TAG_DISCOVERED
: esta intent é iniciada se nenhuma atividade processar oACTION_NDEF_DISCOVERED
ou oACTION_TECH_DISCOVERED
intents.
O funcionamento básico do sistema de expedição de etiquetas é o seguinte:
- Tentar iniciar uma atividade com a intent que foi criada pelo sistema de expedição de etiquetas
ao analisar a tag NFC (
ACTION_NDEF_DISCOVERED
ouACTION_TECH_DISCOVERED
). - Se nenhuma atividade for filtrada para essa intent, tente iniciar uma atividade com a próxima
intent de menor prioridade (
ACTION_TECH_DISCOVERED
ouACTION_TAG_DISCOVERED
) até que um aplicativo aplique o filtro ou até que o sistema de expedição de etiquetas teste todas as intents possíveis. - Se nenhum aplicativo aplicar um filtro para nenhum dos intents, nada acontecerá.
Sempre que possível, trabalhe com mensagens NDEF e com a intent ACTION_NDEF_DISCOVERED
, porque é a mais específica das
os três. Essa intent permite iniciar o aplicativo em um momento mais apropriado do que o
outras duas intents, proporcionando ao usuário uma experiência melhor.
Solicitar acesso a NFC no manifesto do Android
Antes de acessar o hardware NFC de um dispositivo e processar adequadamente as intents NFC, declare estes
itens no seu arquivo AndroidManifest.xml
:
- O elemento NFC
<uses-permission>
para acessar o hardware NFC:<uses-permission android:name="android.permission.NFC" />
- A versão mínima do SDK compatível com o aplicativo. A API de nível 9 só oferece suporte
de envio limitado de tags por
ACTION_TAG_DISCOVERED
e fornece apenas acesso a mensagens NDEF pelo extraEXTRA_NDEF_MESSAGES
. Não outras propriedades da tag ou operações de E/S são acessíveis. API de nível 10 inclui suporte abrangente para leitura/gravação, envio de NDEF em primeiro plano e nível de API A versão 14 oferece uma maneira mais fácil de enviar mensagens NDEF para outros dispositivos com o Android Beam e recursos extras e de conveniência para criar registros NDEF.<uses-sdk android:minSdkVersion="10"/>
- O elemento
uses-feature
para que seu aplicativo apareça no Google Play somente para dispositivos com hardware NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Se seu aplicativo usa a funcionalidade NFC, mas essa funcionalidade não é crucial para o seu aplicativo, você pode omitir o elemento
uses-feature
e verificar a disponibilidade de NFC em ambiente de execução verificando segetDefaultAdapter()
énull
.
Filtro para intents NFC
Para iniciar seu aplicativo quando uma tag NFC que você deseja processar for lida, seu aplicativo
pode filtrar por uma, duas ou todas as três intents NFC no manifesto do Android. No entanto,
normalmente filtre pela intent ACTION_NDEF_DISCOVERED
da
ter mais controle sobre quando o aplicativo é iniciado. A intent ACTION_TECH_DISCOVERED
é um substituto para ACTION_NDEF_DISCOVERED
quando nenhum aplicativo filtra por
ACTION_NDEF_DISCOVERED
ou para quando o payload não for
NDEF A filtragem de ACTION_TAG_DISCOVERED
costuma ser muito geral
categoria a ser filtrada. Muitos aplicativos filtram por ACTION_NDEF_DISCOVERED
ou ACTION_TECH_DISCOVERED
antes de ACTION_TAG_DISCOVERED
. Por isso, seu aplicativo tem uma probabilidade baixa de
começando. ACTION_TAG_DISCOVERED
só está disponível como último recurso
para que os aplicativos filtrem nos casos em que nenhum outro aplicativo estiver instalado para lidar com a
ACTION_NDEF_DISCOVERED
ou ACTION_TECH_DISCOVERED
.
Como as implantações de tags NFC variam e muitas vezes não estão sob seu controle, isso nem sempre é possível. É por isso que é possível usar as outras duas intents quando necessário. Quando você tiver controle sobre os tipos de tags e dados gravados, é recomendável usar o NDEF para formatar . As seções a seguir descrevem como aplicar um filtro para cada tipo de intent.
ACTION_NDEF_DISCOVERED
Para filtrar intents ACTION_NDEF_DISCOVERED
, declare o
com o tipo de dados que você quer filtrar. A
exemplos de filtros a seguir para ACTION_NDEF_DISCOVERED
intents com um tipo MIME de text/plain
:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter>
O exemplo a seguir filtra um URI na forma de
https://developer.android.com/index.html
:
<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>
ACTION_TECH_DISCOVERED
Se a atividade aplicar um filtro para a intent ACTION_TECH_DISCOVERED
,
é preciso criar um arquivo de recurso XML que especifique as tecnologias com as quais sua atividade oferece suporte
em um conjunto de tech-list
. Sua atividade é
será considerada uma correspondência se um conjunto tech-list
for um subconjunto das tecnologias
compatíveis com a tag, que você pode acessar chamando getTechList()
.
Por exemplo, se a etiqueta lida for compatível com MifareClássico, NdefFormatable e NfcA, o seu
O conjunto tech-list
precisa especificar as três, duas ou uma das tecnologias (e nada
outro) para que sua atividade seja correspondida.
O exemplo a seguir define todas as tecnologias. Você deve remover aqueles que não estão
compatível com sua tag NFC. Salve esse arquivo (você pode nomeá-lo como quiser) no
<project-root>/res/xml
.
<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>
Também é possível especificar vários conjuntos tech-list
. Cada um dos tech-list
é considerada de forma independente, e sua atividade é considerada uma correspondência se alguma
O conjunto tech-list
é um subconjunto das tecnologias retornadas por getTechList()
. Isso fornece AND
e OR
semântica para tecnologias de correspondência. O exemplo a seguir corresponde tags que podem suportar o
Tecnologias NfcA e Ndef ou compatíveis com as tecnologias NfcB e Ndef:
<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>
No arquivo AndroidManifest.xml
, especifique o arquivo de recurso que você acabou de criar.
no elemento <meta-data>
dentro da <activity>
como no exemplo a seguir:
<activity> ... <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>
Para mais informações sobre como trabalhar com tecnologias de tags e a intent ACTION_TECH_DISCOVERED
, consulte Como trabalhar com tags compatíveis.
Technologies no documento NFC avançado.
ACTION_TAG_DISCOVERED
Para filtrar por ACTION_TAG_DISCOVERED
, use a intent a seguir:
filtro:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Receber informações de intents
Se uma atividade iniciar devido a uma intent NFC, é possível obter informações sobre a NFC lida da intent. Os intents podem conter os seguintes extras, dependendo da etiqueta que for lida:
EXTRA_TAG
(obrigatório): um objetoTag
. que represente a etiqueta lida.EXTRA_NDEF_MESSAGES
(opcional): uma matriz de mensagens NDEF. analisado a partir da tag. Este extra é obrigatório emACTION_NDEF_DISCOVERED
.EXTRA_ID
(opcional): o ID de nível inferior da etiqueta.
Para obter esses extras, verifique se a sua atividade foi iniciada com um dos
as intenções NFC para garantir que uma etiqueta foi lida e, em seguida, obter os extras do
intenção. O exemplo a seguir verifica se o ACTION_NDEF_DISCOVERED
e recebe as mensagens NDEF de um extra de intent.
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. ... } } }
Você também pode obter um objeto Tag
da intent, o que
contêm a carga útil e permitem enumerar as tecnologias da tag:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Criar tipos comuns de registros NDEF
Esta seção descreve como criar tipos comuns de registros NDEF para ajudar você ao gravar em
Tags NFC ou envio de dados com o Android Beam. A partir do Android 4.0 (nível 14 da API), os
O método createUri()
está disponível para ajudar você a criar
registros de URI automaticamente. A partir do Android 4.1 (nível 16 da API),
createExternal()
e createMime()
estão disponíveis para ajudar você a criar
Registros NDEF de tipo MIME e externo. Use esses métodos auxiliares sempre que possível para evitar erros
ao criar registros NDEF manualmente.
Esta seção também descreve como criar o modelo filtro de intent para o registro. Todos esses exemplos de registro NDEF precisam estar no primeiro arquivo registro da mensagem NDEF que você está gravando em uma tag ou enviando.
TNF_ABSOLUTE_URI
Observação: recomendamos o uso do
Tipo RTD_URI
de TNF_ABSOLUTE_URI
, porque é mais eficiente.
Um registro NDEF TNF_ABSOLUTE_URI
pode ser criado da seguinte maneira:
:
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]);
O filtro de intent do registro NDEF anterior ficaria assim:
<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>
TNF_MIME_MEDIA
Um registro NDEF TNF_MIME_MEDIA
pode ser criado das seguintes maneiras:
Usando o método createMime()
:
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")));
Criando o NdefRecord
manualmente:
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")));
O filtro de intent do registro NDEF anterior ficaria assim:
<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>
TNF_WELL_KNOWN com RTD_TEXT
Um registro NDEF TNF_WELL_KNOWN
pode ser criado da seguinte maneira:
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; }
O filtro de intent do registro NDEF anterior ficaria assim:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
TNF_WELL_KNOWN com RTD_URI
Um registro NDEF TNF_WELL_KNOWN
pode ser criado das seguintes maneiras:
Usando o método createUri(String)
:
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
Usando o método createUri(Uri)
:
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);
Criando o NdefRecord
manualmente:
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);
O filtro de intent do registro NDEF anterior ficaria assim:
<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>
TNF_EXTERNAL_TYPE
É possível criar um registro NDEF TNF_EXTERNAL_TYPE
no seguinte
maneiras:
Usando o método createExternal()
:
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);
Criando o NdefRecord
manualmente:
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);
O filtro de intent do registro NDEF anterior ficaria assim:
<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>
Use TNF_EXTERNAL_TYPE
para implantações mais genéricas de tags NFC para oferecer melhor compatibilidade
Aparelhos com e sem tecnologia Android.
Observação: os URNs de TNF_EXTERNAL_TYPE
têm um formato canônico de:
urn:nfc:ext:example.com:externalType
, mas a especificação NFC Forum RTD
declara que a parte urn:nfc:ext:
do URN deve ser omitida do
Registro NDEF. Portanto, tudo que você precisa fornecer é o domínio (example.com
no exemplo)
e tipo (externalType
no exemplo) separados por dois pontos.
Ao enviar TNF_EXTERNAL_TYPE
, o Android converte o URN urn:nfc:ext:example.com:externalType
em um URI vnd.android.nfc://ext/example.com:externalType
, que é o que o
o filtro de intent no exemplo declara.
Registros do aplicativo para Android
Introduzido no Android 4.0 (API de nível 14), um Android Application Record (AAR) oferece uma experiência certeza de que seu aplicativo será iniciado quando uma tag NFC for lida. Um AAR tem o nome do pacote de um aplicativo incorporado em um registro NDEF. Você pode adicionar um AAR a qualquer registro NDEF do seu NDEF porque o Android pesquisa toda a mensagem NDEF em busca de AARs. Se ele encontra uma AAR, ela começa o aplicativo com base no nome do pacote dentro do AAR. Se o aplicativo não estiver presente dispositivo, o Google Play é iniciado para fazer o download do aplicativo.
Os AARs são úteis para evitar que outros aplicativos filtrem a mesma intenção e ele pode lidar com tags específicas implantadas. Os AARs só têm suporte no nível do aplicativo, devido à restrição do nome do pacote, e não no nível da atividade, como acontece e filtragem de intents. Se quiser processar um intent no nível da atividade, use os filtros de intent.
Se uma etiqueta contiver um AAR, o sistema de expedição de etiquetas fará a expedição da seguinte maneira:
- Ele tentará iniciar uma atividade usando um filtro de intent normalmente. Se a atividade que corresponde a intent também corresponder ao AAR, inicie a atividade.
- Se a atividade que filtra o intent não corresponder à AAR, se várias atividades puderem processar a intent ou se nenhuma atividade processar a intent, inicie o aplicativo especificado pelo AAR.
- Se nenhum aplicativo puder começar com as AARs, acesse o Google Play para fazer o download do aplicativo com base no AAR.
Observação:é possível substituir os AARs e o sistema de expedição de intents com as primeiro plano sistema de expedição, que permite que uma atividade em primeiro plano tenha prioridade quando uma tag NFC é descobertos. Com esse método, a atividade precisa estar em primeiro plano para substituir os AARs e as sistema de expedição de intents.
Se ainda quiser filtrar por tags verificadas que não contenham um AAR, você pode declarar filtros de intent como de costume. Isso é útil caso seu aplicativo esteja interessado em outras tags que não contenham AARs. Por exemplo, talvez você queira garantir que seu aplicativo processe tags proprietárias e tags gerais implantadas por terceiros. Observação importante que as AARs são específicas para dispositivos Android 4.0 ou mais recentes. Portanto, ao implantar tags, usar uma combinação de AARs e tipos MIME/URIs para oferecer suporte à maior variedade de dispositivos possível. Em Além disso, ao implantar etiquetas NFC, pense em como deseja escrever suas etiquetas NFC para ativar suporte para a maioria dos dispositivos (dispositivos Android e outros). Você pode fazer isso definir um tipo MIME ou URI relativamente exclusivo para facilitar a distinção pelos aplicativos.
O Android oferece uma API simples para criar um AAR,
createApplicationRecord()
: Tudo o que você precisa
é incorporar as AARs em qualquer lugar da sua NdefMessage
. Você não quer
usar o primeiro registro do NdefMessage
, a menos que o AAR seja o único
no NdefMessage
. Isso ocorre porque o Android
o sistema verifica o primeiro registro de uma NdefMessage
para determinar o tipo MIME ou
URI da tag, que é usado para criar um intent para que os aplicativos filtrem. O código a seguir
mostra como criar um AAR:
Kotlin
val msg = NdefMessage( arrayOf( ..., NdefRecord.createApplicationRecord("com.example.android.beam") ) )
Java
NdefMessage msg = new NdefMessage( new NdefRecord[] { ..., NdefRecord.createApplicationRecord("com.example.android.beam")} ); )
Enviar mensagens NDEF para outros dispositivos
O Android Beam permite a troca de dados peer-to-peer simples entre dois dispositivos com tecnologia Android. A aplicativo que queira enviar dados para outro dispositivo deve estar em primeiro plano e o dispositivo que recebem os dados não deve ser bloqueado. Quando o dispositivo emissor entra em contato próximo o suficiente com um dispositivo receptor, o dispositivo emissor vai exibir a mensagem "Toque para enviar" de ML pela IU. O usuário pode escolher enviar ou não a mensagem para o dispositivo receptor.
Observação:o envio de NDEF em primeiro plano estava disponível no nível 10 da API,
que fornece funcionalidade semelhante ao Android Beam. Essas APIs foram descontinuadas, mas
estão disponíveis para serem compatíveis com dispositivos mais antigos. Consulte enableForegroundNdefPush()
para mais informações.
É possível ativar o Android Beam para o aplicativo chamando um destes dois métodos:
setNdefPushMessage()
: aceita umaNdefMessage
para definir como a mensagem a ser enviada. Envia a mensagem automaticamente quando dois dispositivos estão próximos o suficiente.setNdefPushMessageCallback()
: Aceita um retorno de chamada que contém umcreateNdefMessage()
que é chamado quando um dispositivo está ao alcance do envio de dados. O callback permite criar a mensagem NDEF só quando necessário.
Uma atividade só pode enviar uma mensagem NDEF por vez, portanto, setNdefPushMessageCallback()
tem prioridade
mais de setNdefPushMessage()
se ambas estiverem definidas. Para usar
Android Beam, as seguintes diretrizes gerais precisam ser cumpridas:
- A atividade que está enviando os dados precisa estar em primeiro plano. Os dois dispositivos precisam ter com a tela desbloqueada.
- É preciso encapsular os dados que você está enviando em um
NdefMessage
. objeto. - O dispositivo NFC que estiver recebendo os dados enviados deve ser compatível com o
Protocolo de push NDEF
com.android.npp
ou Troca de NDEF simples (SNEP, na sigla em inglês) do NFC Forum protocolo). O protocolocom.android.npp
é obrigatório para dispositivos no nível 9 da API (Android). 2.3) ao nível 13 da API (Android 3.2).com.android.npp
e SNEP são obrigatórios em API de nível 14 (Android 4.0) e mais recentes.
Observação:se a atividade ativar o Android Beam e for em primeiro plano, o sistema de expedição de intents padrão é desativado. No entanto, se sua atividade também ativa envio em primeiro plano, ele ainda poderá verificar as tags que correspondem aos filtros de intent definidos no envio em primeiro plano.
Para ativar o Android Beam:
- Crie um
NdefMessage
que contenha asNdefRecord
s que você quer enviar para o outro dispositivo. - Chame
setNdefPushMessage()
com umNdefMessage
ou chamesetNdefPushMessageCallback
transmitindo um objetoNfcAdapter.CreateNdefMessageCallback
no métodoonCreate()
de sua atividade. Esses métodos exigem pelo menos uma atividade que você quer ativar com o Android Beam, junto com uma lista opcional de outras atividades a serem ativadas.Em geral, você normalmente usa
setNdefPushMessage()
se a Atividade só precisa sempre envia a mesma mensagem NDEF quando dois dispositivos estão ao alcance da comunicação. Você usasetNdefPushMessageCallback
quando seu se preocupa com o contexto atual do aplicativo e quer enviar uma mensagem NDEF dependendo do que o usuário está fazendo no aplicativo.
O exemplo a seguir mostra como uma atividade simples chama NfcAdapter.CreateNdefMessageCallback
no método onCreate()
de uma
atividade (consulte AndroidBeamDemo
para a amostra completa). Este exemplo também contém métodos para ajudar você a criar um registro MIME:
Kotlin
package com.example.android.beam import android.app.Activity import android.content.Intent import android.nfc.NdefMessage import android.nfc.NdefRecord import android.nfc.NfcAdapter import android.nfc.NfcAdapter.CreateNdefMessageCallback import android.nfc.NfcEvent import android.os.Bundle import android.os.Parcelable import android.widget.TextView import android.widget.Toast import java.nio.charset.Charset class Beam : Activity(), NfcAdapter.CreateNdefMessageCallback { private var nfcAdapter: NfcAdapter? = null private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) textView = findViewById(R.id.textView) // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this) if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show() finish() return } // Register callback nfcAdapter?.setNdefPushMessageCallback(this, this) } override fun createNdefMessage(event: NfcEvent): NdefMessage { val text = "Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis() return NdefMessage( arrayOf( createMime("application/vnd.com.example.android.beam", text.toByteArray()) ) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. *///,NdefRecord.createApplicationRecord("com.example.android.beam") ) } override fun onResume() { super.onResume() // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { processIntent(intent) } } override fun onNewIntent(intent: Intent) { // onResume gets called after this to handle the intent setIntent(intent) } /** * Parses the NDEF Message from the intent and prints to the TextView */ private fun processIntent(intent: Intent) { textView = findViewById(R.id.textView) // only one message sent during the beam intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMsgs -> (rawMsgs[0] as NdefMessage).apply { // record 0 contains the MIME type, record 1 is the AAR, if present textView.text = String(records[0].payload) } } } }
Java
package com.example.android.beam; import android.app.Activity; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateNdefMessageCallback; import android.nfc.NfcEvent; import android.os.Bundle; import android.os.Parcelable; import android.widget.TextView; import android.widget.Toast; import java.nio.charset.Charset; public class Beam extends Activity implements CreateNdefMessageCallback { NfcAdapter nfcAdapter; TextView textView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView textView = (TextView) findViewById(R.id.textView); // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show(); finish(); return; } // Register callback nfcAdapter.setNdefPushMessageCallback(this, this); } @Override public NdefMessage createNdefMessage(NfcEvent event) { String text = ("Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis()); NdefMessage msg = new NdefMessage( new NdefRecord[] { createMime( "application/vnd.com.example.android.beam", text.getBytes()) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. */ //,NdefRecord.createApplicationRecord("com.example.android.beam") }); return msg; } @Override public void onResume() { super.onResume(); // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { processIntent(getIntent()); } } @Override public void onNewIntent(Intent intent) { // onResume gets called after this to handle the intent setIntent(intent); } /** * Parses the NDEF Message from the intent and prints to the TextView */ void processIntent(Intent intent) { textView = (TextView) findViewById(R.id.textView); Parcelable[] rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES); // only one message sent during the beam NdefMessage msg = (NdefMessage) rawMsgs[0]; // record 0 contains the MIME type, record 1 is the AAR, if present textView.setText(new String(msg.getRecords()[0].getPayload())); } }
Observe que esse código comenta um AAR, que pode ser removido. Se você ativar as AARs, o aplicativo especificado no AAR sempre recebe a mensagem do Android Beam. Se o aplicativo não for o Google Play será iniciado a fazer o download do aplicativo. Portanto, a intent a seguir o filtro não é tecnicamente necessário para dispositivos Android 4.0 ou mais recentes se o AAR for usado:
<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>
Com esse filtro de intent, o aplicativo com.example.android.beam
agora pode ser iniciado
quando ele verifica uma tag NFC ou recebe um Android Beam com um AAR de
tipo com.example.android.beam
ou quando uma mensagem formatada em NDEF contiver um registro MIME
do tipo application/vnd.com.example.android.beam
.
Mesmo que as AARs garantam que um aplicativo será iniciado ou baixado, os filtros de intenção são recomendado, porque permitem que você inicie uma atividade de sua escolha no em vez de sempre iniciar a atividade principal dentro do pacote especificado por um AAR. Os AARs não têm granularidade no nível da atividade. Além disso, como alguns aparelhos com tecnologia Android não oferecer suporte a AARs, também é necessário incorporar informações de identificação no primeiro registro NDEF do seu NDEF mensagens e filtrar essas mensagens também, por precaução. Consulte Criação de conteúdo Tipos de registros NDEF para mais informações sobre como criar registros.