SlideShare uma empresa Scribd logo
True Time API
Para Data e
Horário NTP
no Android
thiengo.com.br
Network Time Protocol - NTP
O Network Time Protocol (NTP), ou Protocolo de Tempo para Redes, é o protocolo que
permite a sincronização dos relógios de dispositivos que se conectam a Internet.
O NTP é extremamente importante para qualquer dispositivo que se conecta a rede, um
forte indício disso é que qualquer aparelho computacional que adquirimos já vem com a
configuração de obtenção de data e hora em: atualização automática.
A discussão detalhada sobre o funcionamento do NTP você consegue no site oficial NTP.br
mantido pelo Comitê Gestor da Internet (CGI).
Estou indicando o CGI para mais informações, pois o estudo por completo do NTP tende a
não ser de grande importância a um profissional de desenvolvimento, principalmente
porque o dispositivo que receberá o software desenvolvido certamente já tem nele toda a
tecnologia de requisição de data e horário a servidores NTP.
O que é importante ao profissional de desenvolvimento de software é saber se o domínio
do problema atualmente trabalhado por ele exige, ou não, o gerenciamento de data e hora
exatos, independente da data e horário fornecidos pelo próprio aparelho.
Isso, pois o aparelho não é uma entidade confiável em termos de "data e hora exatos”,
principalmente porque o usuário pode mudar estes dados para atender a alguma
necessidade dele, por exemplo: adiantar o horário em dez minutos para sempre conseguir
sair ao menos dez minutos antes aos compromissos.
Simple Network Time Protocol - SNTP
O Simple Network Time Protocol (SNTP), ou Protocolo Simples de Tempo para
Rede, é uma versão simplificada do NTP, versão que não exige, por exemplo, a
complexidade de obter informações de tempo de um determinado servidor,
informações como: deslocamento, dispersão e variação.
Resumidamente, o SNTP permite: consultar o tempo em um servidor e ajustar o
relógio local de tempos em tempos. O NTP vai mais além, como, por exemplo:
obter os dados de tempo (data e hora) da fonte mais confiável dentre todas as
pesquisadas.
Para ficar mais claro: se em seu domínio é necessária uma requisição a um
servidor qualquer para então obter a data e horário desse servidor como fonte de
atualização de relógio, essa foi uma atualização utilizando o protocolo SNTP.
Agora se em seu domínio do problema houve a requisição a uma série de
servidores de data e hora, incluindo o trabalho de escolha da melhor resposta. Isso
já se caracteriza como fluxo de uso do protocolo NTP.
A biblioteca que estudaremos neste conjunto de slides trabalha com a versão
completa do NTP, mesmo ela exigindo poucas linhas de código.
Quando o NTP é importante para um desenvolvedor
Android
Certamente você deve estar se perguntando: Para desenvolvedores Android, qual a
utilidade do conhecimento de alguma API NTP?
A importância deste conhecimento fica evidente principalmente quando trabalhando
em domínios de problema onde há necessidade de comunicação remota com
servidores Web e também à exigência de trabalho offline, o app continua
funcionando (de maneira limitada) mesmo quando não há conexão com a rede.
Aplicativos de comércio eletrônico, por exemplo, exigem inúmeros dados que serão
utilizados na aplicação de inteligência em negócios, para assim decisões acertadas
serem tomadas, decisões de promoções em determinadas regiões, por exemplo.
Conhecer o tempo exato da maioria das interações dos usuários de seu aplicativo
de compras online provavelmente trará maior precisão nas tomadas de decisões.
Note que o conjunto de domínios de problemas que exigem exatidão em data e
horário, uso de API NTP, não é tão extenso quanto o conjunto de domínios que
exigem o trabalho com alguma API de carregamento de imagens remotas, mas
certamente os domínios para NTP também existem em grande número e até o
momento da construção destes slides nós, desenvolvedores Android, temos
somente uma API open source que permite requisição a servidores NTP.
Conhecendo e codificando:
biblioteca True Time Android
Biblioteca (ou API) True Time
A biblioteca True Time Android foi desenvolvida para o simples fornecimento de
uma data e horário confiáveis, obtidos de servidores NTP.
O projeto é open source e tem muita aceitação da comunidade de desenvolvedores
Android. Até o momento da construção deste conteúdo eram mais de 690 estrelas
de recomendação no GitHub, algo surpreendente para uma API específica de
domínio.
A True Time API atende a partir do Android API 14, Ice Cream Sandwich, e apesar
de algumas limitações encontradas, se o desenvolvedor Android souber trabalhar
com entidades como AsyncTask e LocalBroadcastManager, certamente ele vai
conseguir o máximo possível da True Time.
Instalação da API
A biblioteca está disponível no Jitpack, este que é um repositório de pacotes de
projetos JVM e Android. Logo, no Gradle Project Level, adicione a referência a este
repositório como a seguir (bloco maven):
Então, no Gradle App Level, adicione:
No código do anterior, do Gradle App Level, estamos referenciando a versão Rx
(ReactiveX) da True Time API.
Na documentação há também a versão vanilla, versão que não exige o
conhecimento da sintaxe do RxJava quando trabalhando com a True Time.
Porém na mesma documentação ainda é recomendado o uso da versão Rx, pois
ela é a versão que implementa a requisição NTP completa e não somente
requisição SNTP, como acontece com a versão vanilla.
Devido a isso, aqui estudaremos somente a versão Rx. Fique tranquilo se você
ainda não conhece o RxJava, a interface da True Time API é simples de entender e
de utilizar, ou seja, este "não conhecimento" não lhe atrapalhará.
Configuração inicial para requisição a servidores NTP
O código de requisição da True Time API deve entrar no método onCreate() de
uma classe Application. Veja o código a seguir:
Comentando o código anterior, temos:
- build(): retorna um objeto TrueTimeRx. Note que build() invoca é a
implementação do padrão Singleton, ou seja, sempre estaremos utilizando o
mesmo objeto TrueTimeRx;
- withSharedPreferences( this ): indica que o resultado retornado, de algum
dos servidores NTP, deve ser colocado em cache, cache gerenciado pela
própria biblioteca e utilizando a API SharedPreferences. O contexto,
argumento, sempre é o da aplicação;
- initializeRx( "time.apple.com" ): definição do conjunto, pool de servidores,
NTP para a obtenção da data e horário confiáveis;
- subscribeOn( Schedulers.io() ): método que permite que nós
desenvolvedores especifiquemos em qual operador de comunicação e thread a
entidade observável trabalhará. Aqui a entidade observável é o "algoritmo de
requisição a servidores NTP", onde o resultado dessa requisição deve ser
enviado a todos os observadores (inscritos via método subscribe(), por
exemplo). Segundo a documentação Rx da True Time API, o operador deve ser
o Schedulers.io().
- subscribe(…): assina uma entidade observadora para resultado positivo (sem
erro em tempo de execução), primeiro argumento. E assina uma entidade
observadora para resultado negativo, com erro em tempo de execução,
segundo argumento. Qualquer resultado é transmitido via operador definido em
subscribeOn(). A origem do resultado é uma entidade observável, aqui o
"algoritmo de comunicação com servidores NTP". Há sobrecargas de
subscribe(), mas a versão apresentada anteriormente tende a ser a utilizada
em todos os domínios da True Time API. Fizemos uso da versão Lambda, ou
literal de função, de implementações de Consumer, como na documentação
oficial da True Time.
Se o método withSharedPreferences() não for invocado com o argumento correto,
não será possível reaproveitar a data e horário já retornados por um servidor NTP.
O dado em cache, devido ao uso de withSharedPreferences(), permanecerá em
disco até o momento que houver o reboot do aparelho. Após o reboot, assim que o
aplicativo for aberto será necessária uma nova conexão NTP para obter novamente
a data e horário corretos.
Apesar das explicações sobre os métodos subscribeOn() e subscribe(), pode ser
que você queira se aprofundar ainda mais, logo, ao terminar este conteúdo, entre
nos links a seguir:
- Explicação de subscribeOn() no site ReactiveX (em inglês);
- Explicação de subscribe() no site ReactiveX (em inglês).
Pode lhe estar surgindo a dúvida sobre a necessidade de uso dos métodos
subscribeOn() e subscribe() somente para uma simples requisição a servidores
NTP. Segundo meus testes, se não houver a definição destes métodos, não haverá
requisição.
Agora, para que a requisição do código TrueTimeRx funcione, ainda é preciso
algumas configurações no AndroidManifest.xml:
Obtendo o objeto Date
Além do uso do primeiro argumento de subscribe() para obter o objeto do tipo
Date, objeto que contém data e horário corretos de servidores NTP, também
podemos utilizar o método now() em qualquer trecho de nosso projeto:
É importante o uso de um bloco try{} na invocação de now(), pois caso ainda não
haja uma resposta válida de TrueTimeRx, mesmo que em cache, uma exceção
será gerada.
Ok, mas não há algum método que nos auxilie em saber se já há ou não algum
dado em memória que possibilite a segura invocação de now()?
Até o momento da construção deste conjunto de slides não havia algum método na
API que permitisse essa verificação de cache.
Formatando a saída e o fuso horário
A data e horário retornados vão estar dentro do fuso horário do aparelho, mas há
inúmeras APIs Java e Kotlin que permitem a mudança disso em tempo de
execução.
O código a seguir é um exemplo de como obter a data e horário formatados e em
diferente fuso horário:
Para uma lista completa de Greenwich Mean Time (GMT), entre em GeoIPs
TimeZones.
Evitando novas invocações de TrueTimeRx.build()
Pode ser que você escolha não realizar mais invocações a TrueTimeRx.build()
depois de já ter no aparelho uma data e horário retornados por servidores NTP.
Para isso, ao invés do uso de isInitialized() que somente verifica se
TrueTimeRx.build() já foi iniciado, utilize um código try{}catch{} como a seguir:
Estude bem o domínio do problema do aplicativo em desenvolvimento para então
poder definir com total certeza se o código de segurança anterior é necessário.
Digo isso, pois depois que a data e horário são retornados de algum servidor NTP,
a API True Time utiliza o clocktick do aparelho para poder correr também o relógio
dos dados em cache, data e horário.
Devido a "não exata" precisão do clocktick do aparelho, depois de um tempo o
relógio ou fica adiantado, ou fica atrasado.
Tendo em mente o que foi discutido nos parágrafos anteriores, se seu aplicativo
continuar fazendo uso da data e horário armazenados pela True Time API e
também tiver com o código de bloqueio de novas invocações de
TrueTimeRx.build(), com um tempo a sua lógica de negócio estará trabalhando
com a data e hora errados.
Na documentação não há código de bloqueio. Alias, nos códigos de exemplo,
assim que o aplicativo é aberto, há novas requisições TrueTimeRx.build().
Com isso, o máximo que recomendo é que: se o código de bloqueio for necessário,
então trabalhe com um timer interno para que ao menos uma nova requisição seja
realizada a cada semana.
Uma possível limitação em withSharedPreferences()
Quando você for realizar seus testes de código de bloqueio, da seção anterior,
notará que o código em catch() somente não é invocado quando o aplicativo é
aberto em um estado onde ele já estava em background.
Segundo um dos mantenedores da biblioteca True Time, até o momento da
construção deste conjunto de slides: isso é problema de versão de Android /
aparelho em uso, pois nos testes dele o método withSharedPreferences()
funciona sem problemas.
Bom... agora é aguardar a evolução da API para que withSharedPreferences()
funcione para qualquer uma das versões do Android e aparelhos a partir da versão
mínima de API suportada pela True Time.
Tenha em mente que esta limitação não é muito crítica, pois novas requisições a
servidores NTP são sim recomendadas.
Se a apresentação de alguma data e horário for realmente necessária, então você
pode tentar algo como:
No projeto de exemplo do artigo que acompanha este conjunto de slides
utilizaremos um código de segurança como o anterior, além de APIs como
AsyncTask e LocalBroadcastManager, para obter o melhor da biblioteca True
Time.
Thread Principal (UI) bloqueada
Dependendo da versão da True Time API que você estiver utilizando, assim que
invocar o método TrueTimeRx.now() notará que a interface do usuário vai travar.
Isso acontece até mesmo quando a invocação de now() ocorre em uma thread
secundária.
A versão mais atual da API apresenta este problema. Na época da construção
deste conteúdo a versão mais atual era a 3.3:
A solução, encontrada nas issues da API no GitHub, é utilizar a versão
09087b6a6e, versão que a principio nos atende tão bem quanto as versões
posteriores a ela, porém com o adendo de não ter o travamento da thread principal:
Agora é acompanhar as novas versões da API para ver se o problema de trava de
thread UI é resolvido definitivamente.
Configurações extras
Ainda é possível o trabalho com outros métodos de RxJava, além de métodos de
configuração nativos da API. Veja o código a seguir:
Sendo um conhecedor de Rx, você também consegue utilizar os métodos
observeOn() e subscribeWith(), como no exemplo a seguir, direto da classe
Application, customizada e em Java, da documentação oficial:
Servidores NTP
Segundo a documentação oficial da API em estudo e também segundo meus
testes, o melhor pool de servidores NTP a consultar é o da Apple: time.apple.com
Na doc também há alguns exemplos com o pool de servidores NTP do Google:
time.google.com
Você pode tentar definir algum outro de seu conhecimento. Na documentação não
há restrições quanto ao uso de outros servidores, ao menos de maneira explicita
não há essa restrição.
Em meus testes eu não testei a precisão de cada pool de servidores NTP, mas
notei que o da Apple é o mais eficiente em termos de "devolver uma resposta",
rapidamente há o retorno da data e horário requisitados.
Pontos negativos
- A documentação, incluindo os códigos de exemplo, não condiz 100% com o
que há disponível de interface pública na biblioteca True Time. O método
withSharedPreferencesCache() de um dos códigos de exemplo, quando
invocado em código, mesmo com a versão 3.3 da API, não é reconhecido;
- O problema de trava de thread principal ainda não foi resolvido na versão
mais atual da API, 3.3;
- O método withSharedPreferences() não tem efeito algum se o aplicativo for
removido da memória primária, pilha de apps em background;
- Não há um simples método de verificação para saber se há ou não alguma
data e horário já obtidos de uma fonte NTP e salvos em disco;
- A versão vanilla da API ainda é apresentada na documentação mesmo
quando somente a versão Rx vem sendo evoluída.
Pontos positivos
- Apesar dos problemas, a sintaxe de uso é simples e realmente uma data e
horário exatos são obtidos;
- Os mantenedores da API respondem as issues, facilitando o encontro de
soluções de problemas ainda presentes na True Time.
Conclusão
Mesmo com a série de problemas ainda presentes na True Time API, ainda é
possível obter o melhor dela quando trabalhando junto a outros componentes de
linguagem de programação, componentes como o bloco try{}catch{}.
A simplicidade na requisição e retorno de um objeto Date válido faz com que não
tenhamos de depender de um algoritmo nosso ou até mesmo de um servidor
remoto, em nossa gerência, para o trabalho com uma data e horário NTP.
Necessitando da True Time API em algum de seus projetos, não deixe de
continuar acompanhando as issues e a evolução desta biblioteca. Os
mantenedores da True Time são bem ativos e vêm evoluindo ela.
Fontes
Conteúdo completo, em texto e em vídeo, no link a seguir:
- https://www.thiengo.com.br/true-time-api-para-data-e-horario-ntp-no-android
Fontes:
- https://tech.instacart.com/offline-first-introducing-truetime-for-swift-and-
android-15e5d968df96
- https://github.com/instacart/truetime-android
- https://ntp.br/ntp.php
Para estudo
- Treinamento oficial:
- Prototipagem Profissional de Aplicativos Android.
- Meus livros:
- Receitas Para Desenvolvedores Android;
- Refatorando Para Programas Limpos.
- Redes:
- Udemy;
- YouTube;
- Facebook;
- LinkedIn;
- GitHub;
- Twitter;
- Google Plus.
- Blog App.
True Time API Para Data e Horário
NTP no Android
thiengo.com.br
Vinícius Thiengo
thiengocalopsita@gmail.com

Mais conteúdo relacionado

Mais procurados

SelectionTracker Para Seleção de Itens no RecyclerView Android
SelectionTracker Para Seleção de Itens no RecyclerView AndroidSelectionTracker Para Seleção de Itens no RecyclerView Android
SelectionTracker Para Seleção de Itens no RecyclerView Android
Vinícius Thiengo
 
Observable Binding Para Atualização na UI Android
Observable Binding Para Atualização na UI AndroidObservable Binding Para Atualização na UI Android
Observable Binding Para Atualização na UI Android
Vinícius Thiengo
 
Uma breve introdução ao Terraform
Uma breve introdução ao TerraformUma breve introdução ao Terraform
Uma breve introdução ao Terraform
Leandro Silva
 
Preparar o ambiente para desenvolvimento angular
Preparar o ambiente para desenvolvimento angularPreparar o ambiente para desenvolvimento angular
Preparar o ambiente para desenvolvimento angular
Nize Costa
 
Como Impulsionar o App Android - Compartilhamento Nativo
Como Impulsionar o App Android - Compartilhamento NativoComo Impulsionar o App Android - Compartilhamento Nativo
Como Impulsionar o App Android - Compartilhamento Nativo
Vinícius Thiengo
 
Android DevConference - Automatizando testes sem sofrimento
Android DevConference - Automatizando testes sem sofrimentoAndroid DevConference - Automatizando testes sem sofrimento
Android DevConference - Automatizando testes sem sofrimento
iMasters
 
Estudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do BlogEstudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do Blog
Vinícius Thiengo
 
Escalando apps com React e Type Script e SOLID
Escalando apps com React e Type Script e SOLIDEscalando apps com React e Type Script e SOLID
Escalando apps com React e Type Script e SOLID
Ruben Marcus Luz Paschoarelli
 
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
Rogério Moraes de Carvalho
 
Dez dicas para_acompanhamento_de_bugs
Dez dicas para_acompanhamento_de_bugsDez dicas para_acompanhamento_de_bugs
Dez dicas para_acompanhamento_de_bugs
Paulo Mattos
 
Android Studio
Android StudioAndroid Studio
Android Studio
Vinícius Thiengo
 
Maven Versioning Strategy (VR)
Maven Versioning Strategy (VR)Maven Versioning Strategy (VR)
Maven Versioning Strategy (VR)
Marcus Carvalho
 
Grails
GrailsGrails
Apostila sobre o Visualg
Apostila sobre o VisualgApostila sobre o Visualg
Apostila sobre o Visualg
Regis Magalhães
 
Engenharia rever sa mentebinaria
Engenharia rever sa   mentebinariaEngenharia rever sa   mentebinaria
Engenharia rever sa mentebinaria
Patrese Renan
 
Indo além com Automação de Testes de Apps Android
Indo além com Automação de Testes de Apps AndroidIndo além com Automação de Testes de Apps Android
Indo além com Automação de Testes de Apps Android
Eduardo Carrara de Araujo
 
Annotation Span Para Estilização de Texto no Android
Annotation Span Para Estilização de Texto no AndroidAnnotation Span Para Estilização de Texto no Android
Annotation Span Para Estilização de Texto no Android
Vinícius Thiengo
 
Papel do QA na Transformação Ágil
Papel do QA na Transformação ÁgilPapel do QA na Transformação Ágil
Papel do QA na Transformação Ágil
Elias Nogueira
 
Básico sobre Debugging com Java
Básico sobre Debugging com JavaBásico sobre Debugging com Java
Básico sobre Debugging com Java
jesuinoPower
 
Parse Push Notification - O Lado negro da força
Parse Push Notification - O Lado negro da forçaParse Push Notification - O Lado negro da força
Parse Push Notification - O Lado negro da força
Rudson Lima
 

Mais procurados (20)

SelectionTracker Para Seleção de Itens no RecyclerView Android
SelectionTracker Para Seleção de Itens no RecyclerView AndroidSelectionTracker Para Seleção de Itens no RecyclerView Android
SelectionTracker Para Seleção de Itens no RecyclerView Android
 
Observable Binding Para Atualização na UI Android
Observable Binding Para Atualização na UI AndroidObservable Binding Para Atualização na UI Android
Observable Binding Para Atualização na UI Android
 
Uma breve introdução ao Terraform
Uma breve introdução ao TerraformUma breve introdução ao Terraform
Uma breve introdução ao Terraform
 
Preparar o ambiente para desenvolvimento angular
Preparar o ambiente para desenvolvimento angularPreparar o ambiente para desenvolvimento angular
Preparar o ambiente para desenvolvimento angular
 
Como Impulsionar o App Android - Compartilhamento Nativo
Como Impulsionar o App Android - Compartilhamento NativoComo Impulsionar o App Android - Compartilhamento Nativo
Como Impulsionar o App Android - Compartilhamento Nativo
 
Android DevConference - Automatizando testes sem sofrimento
Android DevConference - Automatizando testes sem sofrimentoAndroid DevConference - Automatizando testes sem sofrimento
Android DevConference - Automatizando testes sem sofrimento
 
Estudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do BlogEstudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do Blog
 
Escalando apps com React e Type Script e SOLID
Escalando apps com React e Type Script e SOLIDEscalando apps com React e Type Script e SOLID
Escalando apps com React e Type Script e SOLID
 
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
 
Dez dicas para_acompanhamento_de_bugs
Dez dicas para_acompanhamento_de_bugsDez dicas para_acompanhamento_de_bugs
Dez dicas para_acompanhamento_de_bugs
 
Android Studio
Android StudioAndroid Studio
Android Studio
 
Maven Versioning Strategy (VR)
Maven Versioning Strategy (VR)Maven Versioning Strategy (VR)
Maven Versioning Strategy (VR)
 
Grails
GrailsGrails
Grails
 
Apostila sobre o Visualg
Apostila sobre o VisualgApostila sobre o Visualg
Apostila sobre o Visualg
 
Engenharia rever sa mentebinaria
Engenharia rever sa   mentebinariaEngenharia rever sa   mentebinaria
Engenharia rever sa mentebinaria
 
Indo além com Automação de Testes de Apps Android
Indo além com Automação de Testes de Apps AndroidIndo além com Automação de Testes de Apps Android
Indo além com Automação de Testes de Apps Android
 
Annotation Span Para Estilização de Texto no Android
Annotation Span Para Estilização de Texto no AndroidAnnotation Span Para Estilização de Texto no Android
Annotation Span Para Estilização de Texto no Android
 
Papel do QA na Transformação Ágil
Papel do QA na Transformação ÁgilPapel do QA na Transformação Ágil
Papel do QA na Transformação Ágil
 
Básico sobre Debugging com Java
Básico sobre Debugging com JavaBásico sobre Debugging com Java
Básico sobre Debugging com Java
 
Parse Push Notification - O Lado negro da força
Parse Push Notification - O Lado negro da forçaParse Push Notification - O Lado negro da força
Parse Push Notification - O Lado negro da força
 

Semelhante a True Time API Para Data e Horário NTP no Android

Novidades do .Net 4.0
Novidades do .Net 4.0Novidades do .Net 4.0
Novidades do .Net 4.0
Giovanni Bassi
 
XML-RPC.pdf
XML-RPC.pdfXML-RPC.pdf
XML-RPC.pdf
MiguelHenley1
 
Acelerando sites e aplicações Web com uma CDN
Acelerando sites e aplicações Web com uma CDNAcelerando sites e aplicações Web com uma CDN
Acelerando sites e aplicações Web com uma CDN
Jose Papo, MSc
 
Acelerando sites e aplicacoes moveis com uma CDN
Acelerando sites e aplicacoes moveis com uma CDNAcelerando sites e aplicacoes moveis com uma CDN
Acelerando sites e aplicacoes moveis com uma CDN
Amazon Web Services LATAM
 
Arquitetura Serverless para Machine Learning
Arquitetura Serverless para Machine LearningArquitetura Serverless para Machine Learning
Arquitetura Serverless para Machine Learning
Felipe Santos
 
Lista 03 respostas
Lista 03 respostasLista 03 respostas
Lista 03 respostas
Força Tauá
 
GraphQL na GetNinjas (2017-09-20)
GraphQL na GetNinjas (2017-09-20)GraphQL na GetNinjas (2017-09-20)
GraphQL na GetNinjas (2017-09-20)
Bruno Soares
 
Relatório analytics de mula tempo de execução usando splunk
Relatório analytics de mula tempo de execução usando splunkRelatório analytics de mula tempo de execução usando splunk
Relatório analytics de mula tempo de execução usando splunk
Jeison Barros
 
Definições E Correlações Dhcp dns smtp e ntp
Definições E Correlações Dhcp dns smtp e ntpDefinições E Correlações Dhcp dns smtp e ntp
Definições E Correlações Dhcp dns smtp e ntp
Rogleison Rabelo, ITIL ISO
 
.NET Core e ASP.NET Core: Dicas e Truques
.NET Core e ASP.NET Core: Dicas e Truques.NET Core e ASP.NET Core: Dicas e Truques
.NET Core e ASP.NET Core: Dicas e Truques
Renato Groff
 
ApresentaçãO Thiago Bordini Campus Party 2010
ApresentaçãO Thiago Bordini   Campus Party 2010ApresentaçãO Thiago Bordini   Campus Party 2010
ApresentaçãO Thiago Bordini Campus Party 2010
Campus Party Brasil
 
ApresentaçãO Thiago Bordini Campus Party 2010
ApresentaçãO Thiago Bordini   Campus Party 2010ApresentaçãO Thiago Bordini   Campus Party 2010
ApresentaçãO Thiago Bordini Campus Party 2010
Campus Party Brasil
 
ASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - Março
ASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - MarçoASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - Março
ASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - Março
Renato Groff
 
Comet - ReverseAjax com DWR - Resumo
Comet - ReverseAjax com DWR - ResumoComet - ReverseAjax com DWR - Resumo
Comet - ReverseAjax com DWR - Resumo
Handerson Frota
 
Síntese do Fórum do livro-apf Outubro
Síntese do Fórum do livro-apf  OutubroSíntese do Fórum do livro-apf  Outubro
Síntese do Fórum do livro-apf Outubro
Fatto Consultoria e Sistemas
 
RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02
RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02
RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02
Wise Systems
 
TechEd_OFC305
TechEd_OFC305TechEd_OFC305
TechEd_OFC305
Rodolfo Roim
 
Cap06a
Cap06aCap06a
Cap06a
Tino Nipassa
 
REST vs GraphQL - A batalha das APIs.pdf
REST vs GraphQL - A batalha das APIs.pdfREST vs GraphQL - A batalha das APIs.pdf
REST vs GraphQL - A batalha das APIs.pdf
BrunoAlbuquerque864673
 
Testando aplicações DataSnap
Testando aplicações DataSnapTestando aplicações DataSnap
Testando aplicações DataSnap
Andreano Lanusse
 

Semelhante a True Time API Para Data e Horário NTP no Android (20)

Novidades do .Net 4.0
Novidades do .Net 4.0Novidades do .Net 4.0
Novidades do .Net 4.0
 
XML-RPC.pdf
XML-RPC.pdfXML-RPC.pdf
XML-RPC.pdf
 
Acelerando sites e aplicações Web com uma CDN
Acelerando sites e aplicações Web com uma CDNAcelerando sites e aplicações Web com uma CDN
Acelerando sites e aplicações Web com uma CDN
 
Acelerando sites e aplicacoes moveis com uma CDN
Acelerando sites e aplicacoes moveis com uma CDNAcelerando sites e aplicacoes moveis com uma CDN
Acelerando sites e aplicacoes moveis com uma CDN
 
Arquitetura Serverless para Machine Learning
Arquitetura Serverless para Machine LearningArquitetura Serverless para Machine Learning
Arquitetura Serverless para Machine Learning
 
Lista 03 respostas
Lista 03 respostasLista 03 respostas
Lista 03 respostas
 
GraphQL na GetNinjas (2017-09-20)
GraphQL na GetNinjas (2017-09-20)GraphQL na GetNinjas (2017-09-20)
GraphQL na GetNinjas (2017-09-20)
 
Relatório analytics de mula tempo de execução usando splunk
Relatório analytics de mula tempo de execução usando splunkRelatório analytics de mula tempo de execução usando splunk
Relatório analytics de mula tempo de execução usando splunk
 
Definições E Correlações Dhcp dns smtp e ntp
Definições E Correlações Dhcp dns smtp e ntpDefinições E Correlações Dhcp dns smtp e ntp
Definições E Correlações Dhcp dns smtp e ntp
 
.NET Core e ASP.NET Core: Dicas e Truques
.NET Core e ASP.NET Core: Dicas e Truques.NET Core e ASP.NET Core: Dicas e Truques
.NET Core e ASP.NET Core: Dicas e Truques
 
ApresentaçãO Thiago Bordini Campus Party 2010
ApresentaçãO Thiago Bordini   Campus Party 2010ApresentaçãO Thiago Bordini   Campus Party 2010
ApresentaçãO Thiago Bordini Campus Party 2010
 
ApresentaçãO Thiago Bordini Campus Party 2010
ApresentaçãO Thiago Bordini   Campus Party 2010ApresentaçãO Thiago Bordini   Campus Party 2010
ApresentaçãO Thiago Bordini Campus Party 2010
 
ASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - Março
ASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - MarçoASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - Março
ASP.NET Core 3.1: Desenvolvimento de APIs Multiplataforma - Março
 
Comet - ReverseAjax com DWR - Resumo
Comet - ReverseAjax com DWR - ResumoComet - ReverseAjax com DWR - Resumo
Comet - ReverseAjax com DWR - Resumo
 
Síntese do Fórum do livro-apf Outubro
Síntese do Fórum do livro-apf  OutubroSíntese do Fórum do livro-apf  Outubro
Síntese do Fórum do livro-apf Outubro
 
RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02
RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02
RTC - RATIONAL TEAM CONCERT - DEVELOPER - SCM ECLIPSE - aula 02
 
TechEd_OFC305
TechEd_OFC305TechEd_OFC305
TechEd_OFC305
 
Cap06a
Cap06aCap06a
Cap06a
 
REST vs GraphQL - A batalha das APIs.pdf
REST vs GraphQL - A batalha das APIs.pdfREST vs GraphQL - A batalha das APIs.pdf
REST vs GraphQL - A batalha das APIs.pdf
 
Testando aplicações DataSnap
Testando aplicações DataSnapTestando aplicações DataSnap
Testando aplicações DataSnap
 

Mais de Vinícius Thiengo

Android: Qual Tecnologia de Desenvolvimento Utilizar?
Android: Qual Tecnologia de Desenvolvimento Utilizar?Android: Qual Tecnologia de Desenvolvimento Utilizar?
Android: Qual Tecnologia de Desenvolvimento Utilizar?
Vinícius Thiengo
 
7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler
7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler
7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler
Vinícius Thiengo
 
5 livros que não são de TI, mas que um desenvolvedor deveria ler
5 livros que não são de TI, mas que um desenvolvedor deveria ler5 livros que não são de TI, mas que um desenvolvedor deveria ler
5 livros que não são de TI, mas que um desenvolvedor deveria ler
Vinícius Thiengo
 
Android About Page API Para Construir a Tela Sobre
Android About Page API Para Construir a Tela SobreAndroid About Page API Para Construir a Tela Sobre
Android About Page API Para Construir a Tela Sobre
Vinícius Thiengo
 
PhotoView Android Para a Completa Implementação de Zoom
PhotoView Android Para a Completa Implementação de ZoomPhotoView Android Para a Completa Implementação de Zoom
PhotoView Android Para a Completa Implementação de Zoom
Vinícius Thiengo
 
Utilizando Intenções Para Mapas de Alta Qualidade no Android
Utilizando Intenções Para Mapas de Alta Qualidade no AndroidUtilizando Intenções Para Mapas de Alta Qualidade no Android
Utilizando Intenções Para Mapas de Alta Qualidade no Android
Vinícius Thiengo
 
Trabalhando Análise Qualitativa em seu Aplicativo Android
Trabalhando Análise Qualitativa em seu Aplicativo AndroidTrabalhando Análise Qualitativa em seu Aplicativo Android
Trabalhando Análise Qualitativa em seu Aplicativo Android
Vinícius Thiengo
 
Chips Android, Quando e Como Utilizar
Chips Android, Quando e Como UtilizarChips Android, Quando e Como Utilizar
Chips Android, Quando e Como Utilizar
Vinícius Thiengo
 
BottomNavigationView Android, Como e Quando Utilizar
BottomNavigationView Android, Como e Quando UtilizarBottomNavigationView Android, Como e Quando Utilizar
BottomNavigationView Android, Como e Quando Utilizar
Vinícius Thiengo
 
Estudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do BlogEstudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do Blog
Vinícius Thiengo
 
Android: Avaliação do Pré-projeto Agenda Cultural
Android: Avaliação do Pré-projeto Agenda CulturalAndroid: Avaliação do Pré-projeto Agenda Cultural
Android: Avaliação do Pré-projeto Agenda Cultural
Vinícius Thiengo
 
ViewModel Android, Como Utilizar Este Componente de Arquitetura
ViewModel Android, Como Utilizar Este Componente de ArquiteturaViewModel Android, Como Utilizar Este Componente de Arquitetura
ViewModel Android, Como Utilizar Este Componente de Arquitetura
Vinícius Thiengo
 
Freelancer Android
Freelancer AndroidFreelancer Android
Freelancer Android
Vinícius Thiengo
 
Definindo Fontes em Aplicativos Android
Definindo Fontes em Aplicativos AndroidDefinindo Fontes em Aplicativos Android
Definindo Fontes em Aplicativos Android
Vinícius Thiengo
 
Fontes em XML, Android O. Configuração e Uso
Fontes em XML, Android O. Configuração e UsoFontes em XML, Android O. Configuração e Uso
Fontes em XML, Android O. Configuração e Uso
Vinícius Thiengo
 
Material Design
Material DesignMaterial Design
Material Design
Vinícius Thiengo
 

Mais de Vinícius Thiengo (16)

Android: Qual Tecnologia de Desenvolvimento Utilizar?
Android: Qual Tecnologia de Desenvolvimento Utilizar?Android: Qual Tecnologia de Desenvolvimento Utilizar?
Android: Qual Tecnologia de Desenvolvimento Utilizar?
 
7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler
7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler
7 Livros Que Não São de TI, Mas Que Um Programador Deveria Ler
 
5 livros que não são de TI, mas que um desenvolvedor deveria ler
5 livros que não são de TI, mas que um desenvolvedor deveria ler5 livros que não são de TI, mas que um desenvolvedor deveria ler
5 livros que não são de TI, mas que um desenvolvedor deveria ler
 
Android About Page API Para Construir a Tela Sobre
Android About Page API Para Construir a Tela SobreAndroid About Page API Para Construir a Tela Sobre
Android About Page API Para Construir a Tela Sobre
 
PhotoView Android Para a Completa Implementação de Zoom
PhotoView Android Para a Completa Implementação de ZoomPhotoView Android Para a Completa Implementação de Zoom
PhotoView Android Para a Completa Implementação de Zoom
 
Utilizando Intenções Para Mapas de Alta Qualidade no Android
Utilizando Intenções Para Mapas de Alta Qualidade no AndroidUtilizando Intenções Para Mapas de Alta Qualidade no Android
Utilizando Intenções Para Mapas de Alta Qualidade no Android
 
Trabalhando Análise Qualitativa em seu Aplicativo Android
Trabalhando Análise Qualitativa em seu Aplicativo AndroidTrabalhando Análise Qualitativa em seu Aplicativo Android
Trabalhando Análise Qualitativa em seu Aplicativo Android
 
Chips Android, Quando e Como Utilizar
Chips Android, Quando e Como UtilizarChips Android, Quando e Como Utilizar
Chips Android, Quando e Como Utilizar
 
BottomNavigationView Android, Como e Quando Utilizar
BottomNavigationView Android, Como e Quando UtilizarBottomNavigationView Android, Como e Quando Utilizar
BottomNavigationView Android, Como e Quando Utilizar
 
Estudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do BlogEstudando Android - Lista de Conteúdos do Blog
Estudando Android - Lista de Conteúdos do Blog
 
Android: Avaliação do Pré-projeto Agenda Cultural
Android: Avaliação do Pré-projeto Agenda CulturalAndroid: Avaliação do Pré-projeto Agenda Cultural
Android: Avaliação do Pré-projeto Agenda Cultural
 
ViewModel Android, Como Utilizar Este Componente de Arquitetura
ViewModel Android, Como Utilizar Este Componente de ArquiteturaViewModel Android, Como Utilizar Este Componente de Arquitetura
ViewModel Android, Como Utilizar Este Componente de Arquitetura
 
Freelancer Android
Freelancer AndroidFreelancer Android
Freelancer Android
 
Definindo Fontes em Aplicativos Android
Definindo Fontes em Aplicativos AndroidDefinindo Fontes em Aplicativos Android
Definindo Fontes em Aplicativos Android
 
Fontes em XML, Android O. Configuração e Uso
Fontes em XML, Android O. Configuração e UsoFontes em XML, Android O. Configuração e Uso
Fontes em XML, Android O. Configuração e Uso
 
Material Design
Material DesignMaterial Design
Material Design
 

Último

Que Pena Amor! Eugénio de Sá - Soneto.ppsx
Que Pena Amor! Eugénio de Sá - Soneto.ppsxQue Pena Amor! Eugénio de Sá - Soneto.ppsx
Que Pena Amor! Eugénio de Sá - Soneto.ppsx
Luzia Gabriele
 
Uma Breve História da Origem, Formação e Evolução da Terra
Uma Breve História da Origem, Formação e Evolução da TerraUma Breve História da Origem, Formação e Evolução da Terra
Uma Breve História da Origem, Formação e Evolução da Terra
Luiz C. da Silva
 
A Guerra do Presente - Ministério da Defesa.pdf
A Guerra do Presente - Ministério da Defesa.pdfA Guerra do Presente - Ministério da Defesa.pdf
A Guerra do Presente - Ministério da Defesa.pdf
Falcão Brasil
 
28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf
28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf
28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf
SheylaAlves6
 
UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...
UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...
UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...
Manuais Formação
 
Introdução ao filme Divertida Mente 2 em pdf
Introdução ao filme Divertida Mente 2 em pdfIntrodução ao filme Divertida Mente 2 em pdf
Introdução ao filme Divertida Mente 2 em pdf
valdeci17
 
Desafio matemático - multiplicação e divisão.
Desafio matemático -  multiplicação e divisão.Desafio matemático -  multiplicação e divisão.
Desafio matemático - multiplicação e divisão.
Mary Alvarenga
 
Boletim informativo - Contacto - julho de 2024
Boletim informativo - Contacto - julho de 2024Boletim informativo - Contacto - julho de 2024
Boletim informativo - Contacto - julho de 2024
Bibliotecas Escolares AEIDH
 
Escola Preparatória de Cadetes do Ar (EPCAR).pdf
Escola Preparatória de Cadetes do Ar (EPCAR).pdfEscola Preparatória de Cadetes do Ar (EPCAR).pdf
Escola Preparatória de Cadetes do Ar (EPCAR).pdf
Falcão Brasil
 
UFCD_5673_Segurança nos transportes_índice.pdf
UFCD_5673_Segurança nos transportes_índice.pdfUFCD_5673_Segurança nos transportes_índice.pdf
UFCD_5673_Segurança nos transportes_índice.pdf
Manuais Formação
 
O Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdf
O Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdfO Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdf
O Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdf
Falcão Brasil
 
Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...
Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...
Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...
Falcão Brasil
 
Escola de Especialistas de Aeronáutica (EEAR).pdf
Escola de Especialistas de Aeronáutica (EEAR).pdfEscola de Especialistas de Aeronáutica (EEAR).pdf
Escola de Especialistas de Aeronáutica (EEAR).pdf
Falcão Brasil
 
Geotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdf
Geotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdfGeotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdf
Geotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdf
Falcão Brasil
 
Fotossíntese e respiração: conceitos e trocas gasosas
Fotossíntese e respiração: conceitos e trocas gasosasFotossíntese e respiração: conceitos e trocas gasosas
Fotossíntese e respiração: conceitos e trocas gasosas
MariaJooSilva58
 
Aula 3 CURSO LETRANDO (classes gramaticais).pdf
Aula 3 CURSO LETRANDO (classes gramaticais).pdfAula 3 CURSO LETRANDO (classes gramaticais).pdf
Aula 3 CURSO LETRANDO (classes gramaticais).pdf
ProfessoraSilmaraArg
 
Administração Em Enfermagem.pptx caala - Cópia-1.pptx
Administração Em Enfermagem.pptx caala - Cópia-1.pptxAdministração Em Enfermagem.pptx caala - Cópia-1.pptx
Administração Em Enfermagem.pptx caala - Cópia-1.pptx
helenawaya9
 
Portfólio Estratégico da Força Aérea Brasileira (FAB).pdf
Portfólio Estratégico da Força Aérea Brasileira (FAB).pdfPortfólio Estratégico da Força Aérea Brasileira (FAB).pdf
Portfólio Estratégico da Força Aérea Brasileira (FAB).pdf
Falcão Brasil
 
Slides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptx
Slides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptxSlides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptx
Slides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptx
LuizHenriquedeAlmeid6
 
gestão_de_conflitos_no_ambiente_escolar.pdf
gestão_de_conflitos_no_ambiente_escolar.pdfgestão_de_conflitos_no_ambiente_escolar.pdf
gestão_de_conflitos_no_ambiente_escolar.pdf
Maria das Graças Machado Rodrigues
 

Último (20)

Que Pena Amor! Eugénio de Sá - Soneto.ppsx
Que Pena Amor! Eugénio de Sá - Soneto.ppsxQue Pena Amor! Eugénio de Sá - Soneto.ppsx
Que Pena Amor! Eugénio de Sá - Soneto.ppsx
 
Uma Breve História da Origem, Formação e Evolução da Terra
Uma Breve História da Origem, Formação e Evolução da TerraUma Breve História da Origem, Formação e Evolução da Terra
Uma Breve História da Origem, Formação e Evolução da Terra
 
A Guerra do Presente - Ministério da Defesa.pdf
A Guerra do Presente - Ministério da Defesa.pdfA Guerra do Presente - Ministério da Defesa.pdf
A Guerra do Presente - Ministério da Defesa.pdf
 
28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf
28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf
28 - Agente de Endemias (40 mapas mentais) - Amostra.pdf
 
UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...
UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...
UFCD_7224_Prevenção de acidentes em contexto domiciliário e institucional_índ...
 
Introdução ao filme Divertida Mente 2 em pdf
Introdução ao filme Divertida Mente 2 em pdfIntrodução ao filme Divertida Mente 2 em pdf
Introdução ao filme Divertida Mente 2 em pdf
 
Desafio matemático - multiplicação e divisão.
Desafio matemático -  multiplicação e divisão.Desafio matemático -  multiplicação e divisão.
Desafio matemático - multiplicação e divisão.
 
Boletim informativo - Contacto - julho de 2024
Boletim informativo - Contacto - julho de 2024Boletim informativo - Contacto - julho de 2024
Boletim informativo - Contacto - julho de 2024
 
Escola Preparatória de Cadetes do Ar (EPCAR).pdf
Escola Preparatória de Cadetes do Ar (EPCAR).pdfEscola Preparatória de Cadetes do Ar (EPCAR).pdf
Escola Preparatória de Cadetes do Ar (EPCAR).pdf
 
UFCD_5673_Segurança nos transportes_índice.pdf
UFCD_5673_Segurança nos transportes_índice.pdfUFCD_5673_Segurança nos transportes_índice.pdf
UFCD_5673_Segurança nos transportes_índice.pdf
 
O Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdf
O Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdfO Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdf
O Ministério da Defesa e a Sociedade no Tema de Defesa Nacional.pdf
 
Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...
Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...
Endereços — Centro Gestor e Operacional do Sistema de Proteção da Amazônia - ...
 
Escola de Especialistas de Aeronáutica (EEAR).pdf
Escola de Especialistas de Aeronáutica (EEAR).pdfEscola de Especialistas de Aeronáutica (EEAR).pdf
Escola de Especialistas de Aeronáutica (EEAR).pdf
 
Geotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdf
Geotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdfGeotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdf
Geotecnologias Aplicadas na Gestão de Riscos e Desastres Hidrológicos.pdf
 
Fotossíntese e respiração: conceitos e trocas gasosas
Fotossíntese e respiração: conceitos e trocas gasosasFotossíntese e respiração: conceitos e trocas gasosas
Fotossíntese e respiração: conceitos e trocas gasosas
 
Aula 3 CURSO LETRANDO (classes gramaticais).pdf
Aula 3 CURSO LETRANDO (classes gramaticais).pdfAula 3 CURSO LETRANDO (classes gramaticais).pdf
Aula 3 CURSO LETRANDO (classes gramaticais).pdf
 
Administração Em Enfermagem.pptx caala - Cópia-1.pptx
Administração Em Enfermagem.pptx caala - Cópia-1.pptxAdministração Em Enfermagem.pptx caala - Cópia-1.pptx
Administração Em Enfermagem.pptx caala - Cópia-1.pptx
 
Portfólio Estratégico da Força Aérea Brasileira (FAB).pdf
Portfólio Estratégico da Força Aérea Brasileira (FAB).pdfPortfólio Estratégico da Força Aérea Brasileira (FAB).pdf
Portfólio Estratégico da Força Aérea Brasileira (FAB).pdf
 
Slides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptx
Slides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptxSlides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptx
Slides Lição 4, CPAD, O Encontro de Rute com Boaz, 3Tr24.pptx
 
gestão_de_conflitos_no_ambiente_escolar.pdf
gestão_de_conflitos_no_ambiente_escolar.pdfgestão_de_conflitos_no_ambiente_escolar.pdf
gestão_de_conflitos_no_ambiente_escolar.pdf
 

True Time API Para Data e Horário NTP no Android

  • 1. True Time API Para Data e Horário NTP no Android thiengo.com.br
  • 2. Network Time Protocol - NTP O Network Time Protocol (NTP), ou Protocolo de Tempo para Redes, é o protocolo que permite a sincronização dos relógios de dispositivos que se conectam a Internet. O NTP é extremamente importante para qualquer dispositivo que se conecta a rede, um forte indício disso é que qualquer aparelho computacional que adquirimos já vem com a configuração de obtenção de data e hora em: atualização automática. A discussão detalhada sobre o funcionamento do NTP você consegue no site oficial NTP.br mantido pelo Comitê Gestor da Internet (CGI). Estou indicando o CGI para mais informações, pois o estudo por completo do NTP tende a não ser de grande importância a um profissional de desenvolvimento, principalmente porque o dispositivo que receberá o software desenvolvido certamente já tem nele toda a tecnologia de requisição de data e horário a servidores NTP. O que é importante ao profissional de desenvolvimento de software é saber se o domínio do problema atualmente trabalhado por ele exige, ou não, o gerenciamento de data e hora exatos, independente da data e horário fornecidos pelo próprio aparelho. Isso, pois o aparelho não é uma entidade confiável em termos de "data e hora exatos”, principalmente porque o usuário pode mudar estes dados para atender a alguma necessidade dele, por exemplo: adiantar o horário em dez minutos para sempre conseguir sair ao menos dez minutos antes aos compromissos.
  • 3. Simple Network Time Protocol - SNTP O Simple Network Time Protocol (SNTP), ou Protocolo Simples de Tempo para Rede, é uma versão simplificada do NTP, versão que não exige, por exemplo, a complexidade de obter informações de tempo de um determinado servidor, informações como: deslocamento, dispersão e variação. Resumidamente, o SNTP permite: consultar o tempo em um servidor e ajustar o relógio local de tempos em tempos. O NTP vai mais além, como, por exemplo: obter os dados de tempo (data e hora) da fonte mais confiável dentre todas as pesquisadas. Para ficar mais claro: se em seu domínio é necessária uma requisição a um servidor qualquer para então obter a data e horário desse servidor como fonte de atualização de relógio, essa foi uma atualização utilizando o protocolo SNTP. Agora se em seu domínio do problema houve a requisição a uma série de servidores de data e hora, incluindo o trabalho de escolha da melhor resposta. Isso já se caracteriza como fluxo de uso do protocolo NTP. A biblioteca que estudaremos neste conjunto de slides trabalha com a versão completa do NTP, mesmo ela exigindo poucas linhas de código.
  • 4. Quando o NTP é importante para um desenvolvedor Android Certamente você deve estar se perguntando: Para desenvolvedores Android, qual a utilidade do conhecimento de alguma API NTP? A importância deste conhecimento fica evidente principalmente quando trabalhando em domínios de problema onde há necessidade de comunicação remota com servidores Web e também à exigência de trabalho offline, o app continua funcionando (de maneira limitada) mesmo quando não há conexão com a rede. Aplicativos de comércio eletrônico, por exemplo, exigem inúmeros dados que serão utilizados na aplicação de inteligência em negócios, para assim decisões acertadas serem tomadas, decisões de promoções em determinadas regiões, por exemplo. Conhecer o tempo exato da maioria das interações dos usuários de seu aplicativo de compras online provavelmente trará maior precisão nas tomadas de decisões. Note que o conjunto de domínios de problemas que exigem exatidão em data e horário, uso de API NTP, não é tão extenso quanto o conjunto de domínios que exigem o trabalho com alguma API de carregamento de imagens remotas, mas certamente os domínios para NTP também existem em grande número e até o momento da construção destes slides nós, desenvolvedores Android, temos somente uma API open source que permite requisição a servidores NTP.
  • 6. Biblioteca (ou API) True Time A biblioteca True Time Android foi desenvolvida para o simples fornecimento de uma data e horário confiáveis, obtidos de servidores NTP. O projeto é open source e tem muita aceitação da comunidade de desenvolvedores Android. Até o momento da construção deste conteúdo eram mais de 690 estrelas de recomendação no GitHub, algo surpreendente para uma API específica de domínio. A True Time API atende a partir do Android API 14, Ice Cream Sandwich, e apesar de algumas limitações encontradas, se o desenvolvedor Android souber trabalhar com entidades como AsyncTask e LocalBroadcastManager, certamente ele vai conseguir o máximo possível da True Time.
  • 7. Instalação da API A biblioteca está disponível no Jitpack, este que é um repositório de pacotes de projetos JVM e Android. Logo, no Gradle Project Level, adicione a referência a este repositório como a seguir (bloco maven): Então, no Gradle App Level, adicione:
  • 8. No código do anterior, do Gradle App Level, estamos referenciando a versão Rx (ReactiveX) da True Time API. Na documentação há também a versão vanilla, versão que não exige o conhecimento da sintaxe do RxJava quando trabalhando com a True Time. Porém na mesma documentação ainda é recomendado o uso da versão Rx, pois ela é a versão que implementa a requisição NTP completa e não somente requisição SNTP, como acontece com a versão vanilla. Devido a isso, aqui estudaremos somente a versão Rx. Fique tranquilo se você ainda não conhece o RxJava, a interface da True Time API é simples de entender e de utilizar, ou seja, este "não conhecimento" não lhe atrapalhará.
  • 9. Configuração inicial para requisição a servidores NTP O código de requisição da True Time API deve entrar no método onCreate() de uma classe Application. Veja o código a seguir:
  • 10. Comentando o código anterior, temos: - build(): retorna um objeto TrueTimeRx. Note que build() invoca é a implementação do padrão Singleton, ou seja, sempre estaremos utilizando o mesmo objeto TrueTimeRx; - withSharedPreferences( this ): indica que o resultado retornado, de algum dos servidores NTP, deve ser colocado em cache, cache gerenciado pela própria biblioteca e utilizando a API SharedPreferences. O contexto, argumento, sempre é o da aplicação; - initializeRx( "time.apple.com" ): definição do conjunto, pool de servidores, NTP para a obtenção da data e horário confiáveis; - subscribeOn( Schedulers.io() ): método que permite que nós desenvolvedores especifiquemos em qual operador de comunicação e thread a entidade observável trabalhará. Aqui a entidade observável é o "algoritmo de requisição a servidores NTP", onde o resultado dessa requisição deve ser enviado a todos os observadores (inscritos via método subscribe(), por exemplo). Segundo a documentação Rx da True Time API, o operador deve ser o Schedulers.io().
  • 11. - subscribe(…): assina uma entidade observadora para resultado positivo (sem erro em tempo de execução), primeiro argumento. E assina uma entidade observadora para resultado negativo, com erro em tempo de execução, segundo argumento. Qualquer resultado é transmitido via operador definido em subscribeOn(). A origem do resultado é uma entidade observável, aqui o "algoritmo de comunicação com servidores NTP". Há sobrecargas de subscribe(), mas a versão apresentada anteriormente tende a ser a utilizada em todos os domínios da True Time API. Fizemos uso da versão Lambda, ou literal de função, de implementações de Consumer, como na documentação oficial da True Time. Se o método withSharedPreferences() não for invocado com o argumento correto, não será possível reaproveitar a data e horário já retornados por um servidor NTP. O dado em cache, devido ao uso de withSharedPreferences(), permanecerá em disco até o momento que houver o reboot do aparelho. Após o reboot, assim que o aplicativo for aberto será necessária uma nova conexão NTP para obter novamente a data e horário corretos.
  • 12. Apesar das explicações sobre os métodos subscribeOn() e subscribe(), pode ser que você queira se aprofundar ainda mais, logo, ao terminar este conteúdo, entre nos links a seguir: - Explicação de subscribeOn() no site ReactiveX (em inglês); - Explicação de subscribe() no site ReactiveX (em inglês). Pode lhe estar surgindo a dúvida sobre a necessidade de uso dos métodos subscribeOn() e subscribe() somente para uma simples requisição a servidores NTP. Segundo meus testes, se não houver a definição destes métodos, não haverá requisição.
  • 13. Agora, para que a requisição do código TrueTimeRx funcione, ainda é preciso algumas configurações no AndroidManifest.xml:
  • 14. Obtendo o objeto Date Além do uso do primeiro argumento de subscribe() para obter o objeto do tipo Date, objeto que contém data e horário corretos de servidores NTP, também podemos utilizar o método now() em qualquer trecho de nosso projeto: É importante o uso de um bloco try{} na invocação de now(), pois caso ainda não haja uma resposta válida de TrueTimeRx, mesmo que em cache, uma exceção será gerada. Ok, mas não há algum método que nos auxilie em saber se já há ou não algum dado em memória que possibilite a segura invocação de now()? Até o momento da construção deste conjunto de slides não havia algum método na API que permitisse essa verificação de cache.
  • 15. Formatando a saída e o fuso horário A data e horário retornados vão estar dentro do fuso horário do aparelho, mas há inúmeras APIs Java e Kotlin que permitem a mudança disso em tempo de execução. O código a seguir é um exemplo de como obter a data e horário formatados e em diferente fuso horário: Para uma lista completa de Greenwich Mean Time (GMT), entre em GeoIPs TimeZones.
  • 16. Evitando novas invocações de TrueTimeRx.build() Pode ser que você escolha não realizar mais invocações a TrueTimeRx.build() depois de já ter no aparelho uma data e horário retornados por servidores NTP. Para isso, ao invés do uso de isInitialized() que somente verifica se TrueTimeRx.build() já foi iniciado, utilize um código try{}catch{} como a seguir:
  • 17. Estude bem o domínio do problema do aplicativo em desenvolvimento para então poder definir com total certeza se o código de segurança anterior é necessário. Digo isso, pois depois que a data e horário são retornados de algum servidor NTP, a API True Time utiliza o clocktick do aparelho para poder correr também o relógio dos dados em cache, data e horário. Devido a "não exata" precisão do clocktick do aparelho, depois de um tempo o relógio ou fica adiantado, ou fica atrasado. Tendo em mente o que foi discutido nos parágrafos anteriores, se seu aplicativo continuar fazendo uso da data e horário armazenados pela True Time API e também tiver com o código de bloqueio de novas invocações de TrueTimeRx.build(), com um tempo a sua lógica de negócio estará trabalhando com a data e hora errados. Na documentação não há código de bloqueio. Alias, nos códigos de exemplo, assim que o aplicativo é aberto, há novas requisições TrueTimeRx.build(). Com isso, o máximo que recomendo é que: se o código de bloqueio for necessário, então trabalhe com um timer interno para que ao menos uma nova requisição seja realizada a cada semana.
  • 18. Uma possível limitação em withSharedPreferences() Quando você for realizar seus testes de código de bloqueio, da seção anterior, notará que o código em catch() somente não é invocado quando o aplicativo é aberto em um estado onde ele já estava em background. Segundo um dos mantenedores da biblioteca True Time, até o momento da construção deste conjunto de slides: isso é problema de versão de Android / aparelho em uso, pois nos testes dele o método withSharedPreferences() funciona sem problemas. Bom... agora é aguardar a evolução da API para que withSharedPreferences() funcione para qualquer uma das versões do Android e aparelhos a partir da versão mínima de API suportada pela True Time. Tenha em mente que esta limitação não é muito crítica, pois novas requisições a servidores NTP são sim recomendadas.
  • 19. Se a apresentação de alguma data e horário for realmente necessária, então você pode tentar algo como: No projeto de exemplo do artigo que acompanha este conjunto de slides utilizaremos um código de segurança como o anterior, além de APIs como AsyncTask e LocalBroadcastManager, para obter o melhor da biblioteca True Time.
  • 20. Thread Principal (UI) bloqueada Dependendo da versão da True Time API que você estiver utilizando, assim que invocar o método TrueTimeRx.now() notará que a interface do usuário vai travar. Isso acontece até mesmo quando a invocação de now() ocorre em uma thread secundária. A versão mais atual da API apresenta este problema. Na época da construção deste conteúdo a versão mais atual era a 3.3:
  • 21. A solução, encontrada nas issues da API no GitHub, é utilizar a versão 09087b6a6e, versão que a principio nos atende tão bem quanto as versões posteriores a ela, porém com o adendo de não ter o travamento da thread principal: Agora é acompanhar as novas versões da API para ver se o problema de trava de thread UI é resolvido definitivamente.
  • 22. Configurações extras Ainda é possível o trabalho com outros métodos de RxJava, além de métodos de configuração nativos da API. Veja o código a seguir:
  • 23. Sendo um conhecedor de Rx, você também consegue utilizar os métodos observeOn() e subscribeWith(), como no exemplo a seguir, direto da classe Application, customizada e em Java, da documentação oficial:
  • 24. Servidores NTP Segundo a documentação oficial da API em estudo e também segundo meus testes, o melhor pool de servidores NTP a consultar é o da Apple: time.apple.com Na doc também há alguns exemplos com o pool de servidores NTP do Google: time.google.com Você pode tentar definir algum outro de seu conhecimento. Na documentação não há restrições quanto ao uso de outros servidores, ao menos de maneira explicita não há essa restrição. Em meus testes eu não testei a precisão de cada pool de servidores NTP, mas notei que o da Apple é o mais eficiente em termos de "devolver uma resposta", rapidamente há o retorno da data e horário requisitados.
  • 25. Pontos negativos - A documentação, incluindo os códigos de exemplo, não condiz 100% com o que há disponível de interface pública na biblioteca True Time. O método withSharedPreferencesCache() de um dos códigos de exemplo, quando invocado em código, mesmo com a versão 3.3 da API, não é reconhecido; - O problema de trava de thread principal ainda não foi resolvido na versão mais atual da API, 3.3; - O método withSharedPreferences() não tem efeito algum se o aplicativo for removido da memória primária, pilha de apps em background; - Não há um simples método de verificação para saber se há ou não alguma data e horário já obtidos de uma fonte NTP e salvos em disco; - A versão vanilla da API ainda é apresentada na documentação mesmo quando somente a versão Rx vem sendo evoluída.
  • 26. Pontos positivos - Apesar dos problemas, a sintaxe de uso é simples e realmente uma data e horário exatos são obtidos; - Os mantenedores da API respondem as issues, facilitando o encontro de soluções de problemas ainda presentes na True Time.
  • 27. Conclusão Mesmo com a série de problemas ainda presentes na True Time API, ainda é possível obter o melhor dela quando trabalhando junto a outros componentes de linguagem de programação, componentes como o bloco try{}catch{}. A simplicidade na requisição e retorno de um objeto Date válido faz com que não tenhamos de depender de um algoritmo nosso ou até mesmo de um servidor remoto, em nossa gerência, para o trabalho com uma data e horário NTP. Necessitando da True Time API em algum de seus projetos, não deixe de continuar acompanhando as issues e a evolução desta biblioteca. Os mantenedores da True Time são bem ativos e vêm evoluindo ela.
  • 28. Fontes Conteúdo completo, em texto e em vídeo, no link a seguir: - https://www.thiengo.com.br/true-time-api-para-data-e-horario-ntp-no-android Fontes: - https://tech.instacart.com/offline-first-introducing-truetime-for-swift-and- android-15e5d968df96 - https://github.com/instacart/truetime-android - https://ntp.br/ntp.php
  • 29. Para estudo - Treinamento oficial: - Prototipagem Profissional de Aplicativos Android. - Meus livros: - Receitas Para Desenvolvedores Android; - Refatorando Para Programas Limpos. - Redes: - Udemy; - YouTube; - Facebook; - LinkedIn; - GitHub; - Twitter; - Google Plus. - Blog App.
  • 30. True Time API Para Data e Horário NTP no Android thiengo.com.br Vinícius Thiengo thiengocalopsita@gmail.com