No Google I/O 2016 o Google anunciou o Firebase, uma plataforma completa com diversos serviços comuns a aplicativos móveis como analytics, crash reports, notificações push, dentre outros.
Muito tem se falado do Firebase nos últimos meses, portanto serei rápido neste post. O mais importante que você precisa saber para seguir este tutorial é que ele deve levar no máximo 10 a 15 minutos, e as mensagens de Push do Firebase são gratuitas 🙂
No livro Google Android 5a ed, explico como enviar mensagens de Push no Android com o GCM (Google Cloud Message).
Porém como o GCM foi migrado para o FCM (Firebase Cloud Messaging), é justo atualizar os leitores do meu livro com as novidades 🙂
Neste rápido tutorial vamos aprender a enviar mensagens de Push com a nova plataforma do Firebase, e o projeto que vamos fazer é baseado na documentação do Firebase, disponível neste link:
No github do Firebase você poderá encontrar diversos exemplos, inclusive o quickstart sobre o FCM. Os códigos deste tutorial, serão baseados neste quickstart.
Escolha um nome para seu projeto, selecione o Brasil como país e prossiga.
Depois de criar seu projeto, você verá a página de administração do Firebase.
O Firebase possui APIs para Android, iOS e Web. Neste tutorial estamos criando um app Android, portanto clique no botão Add Firebase to your Android app para configurar o projeto.
No wizard insira o nome do seu pacote, o SHA1 do seu certificado e clique em Add App.
Siga o wizard, e no passo 2 faça o download do arquivo google-services.json conforme indicado na figura. Este arquivo contem as configurações da sua conta do Firebase e deve ficar dentro do módulo appdo projeto, conforme indicado na figura.
No último passo do wizard, temos as instruções de como configurar o gradle. É só copiar o código e colar no local indicado. Veja que devemos alterar o arquivo build.gradle da raiz do projeto, e depois o arquivo app/build.gradle do módulo app.
Depois de fazer estas configurações, edite o arquivo app/build.gradle e adicione a dependência do Firebase no projeto:
No Android Studio, adicione a dependência FCM ao arquivo build.gradle de nível do aplicativo:
Veja que vamos usar o próprio exemplo de quickstart do Firebase, assim não temos como errar :-).
Nesta classe, o método onTokenRefresh() é chamado quando o aplicativo receber um token (registration id). Como você aprendeu no livro Google Android 5ed, este token representa o identificador do dispositivo e precisa ser enviado ao seu servidor, pois com ele é possível enviar uma mensagem para este dispositivo.
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(refreshedToken);
}
Feito isso, crie a classe MyFirebaseMessagingService. Ela será responsável por receber as mensagens de push e criar notificações para avisar ao usuário.
Novamente, vamos copiar a classe de exemplo do quickstart do Firebase.
4) Enviando uma mensagem pelo console do Firebase.
Já temos tudo configurado, e só falta enviarmos uma mensagem para testar o Push. O legal do Firebase é que isso pode ser feito pela sua própria página de console.
No console do Firebase, acesse o menu Notifications e envie uma notificação. Basta preencher o campo Message text e selecionar o aplicativo com o seu pacote no campo Target.
Ao enviar uma mensagem com o aplicativo aberto, você verá no LogCat conforme indicado na figura abaixo 🙂
Agora pressione o botão Home do Android e deixe o aplicativo em background. Neste caso ao enviar a mensagem o Firebase vai mostrar uma notificação automaticamente, conforme este print.
Veja que a notificação só foi exibida com o app em background, e este é o comportamento padrão do firebase.
Basicamente, existem 2 tipos de mensagens: data messages (pares de chave=valor) e notification messages.
1) As mensagens do tipo data messages são sempre recebidas no método onMessageReceived(removeMessage), independente se o app está aberto ou em background.
Para identificar se a mensagem é do tipo data message, basta verificar se o método getData() retorna um Map com registros (chave=valor).
if (remoteMessage.getData().size() > 0) {
   Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
Neste caso o desenvolvedor é sempre responsável por mostrar uma notificação para o usuário, ou seja, é preciso programar para mostrar a notificação. No código de exemplo do firebase tem até um exemplo disso basta descomentar o código.
Para enviar uma mensagem do tipo data message pelo console do Firebase, entre em opções avançadas e preencha a estrutura de chave=valor, é bem simples. Depois no app você poderá ler os valores.
2) As mensagens do tipo notification messages possuem um comportamento um pouco diferente, e foi esta mensagem que enviamos, pois ela não continha nenhum parâmetro do tipo (chave=valor).
Neste tipo de mensagem, se o app está aberto o método onMessageReceived(removeMessage) é executado. Neste caso, o desenvolvedor é responsável por programar a leitura da mensagem e mostrar a notificação para o usuário. Porém, caso o app esteja em background o Firebase vai mostrar uma notificação automaticamente para o usuário. Ao clicar na notificação os dados da mensagem de push serão enviados para a activity principal do aplicativo, então é só fazer o tratamento ao abrir o app e pronto 🙂
Para maiores detalhes sobre os tipos de notificações veja esse link:
É isso pessoal 🙂 Espero que este breve tutorial tenha ajudado a entender um pouco sobre como enviar mensagens de Push com o Firebase. Vale lembrar que o Google ainda vai dar suporte para o GCM um bom tempo, até porque existem muitas aplicações que estão utilizando este serviço em produção. Mas para novos apps, recomenda-se utilizar o Firebase.
Uma dica é usar o Firebase também para aplicativos iOS, pois o serviço de Push do Google é bem mais simples que o serviço da APNS (Apple Push Notification Service) da Apple.
Sempre recebo perguntas de como fazer paginação ao fazer um web service, pois no meu livro de Web Services os exemplos sempre retornam todos os registros do banco de dados.
Por exemplo, neste web service é retornado todos os carros do servidor:
Mas e se existir 1 milhão de registros no banco de dados? Neste caso o recomendado é retornar os registros paginados, por exemplo de 10 em 10, ou 20 em 20, conforme a necessidade.
Fazer isso é simples, então se você tem o código-fonte do projeto RESTful dos carros, é só fazer 2 pequenas alterações:
Na classe CarrosResource, tem um exemplo do tipo GET configurado, o qual retorna todos os carros no formato JSON, lembra-se?
O que podemos fazer é adicionar 2 parâmetros. Um deles para indicar a página que você está solicitando e outro para indicar a quantidade de registros que devem ser retornados.
Exemplo:
@GET
@Path("/page/{page}/max/{max}")
public List<Carro> get(@PathParam("page") int page,@PathParam("max") int max) {
List<Carro> carros = carroService.getCarros(page,max);
return carros;
}
O framework Hibernate que estudamos no livro nos ajuda a fazer a paginação. Eu gosto de criar um método setPage(…) como esse:
protected void setPage(Query q, int page, int max) {
// Paginação
int firstResult = 0;
if (page != 0) {
firstResult = page * max;
}
q.setFirstResult(firstResult);
q.setMaxResults(max);
}
Bom é isso 🙂 Se alguém tiver alguma dúvida avisa, pois o conceito é bem simples.
Com web services paginados, o correto seria alterar os aplicativos mobile para buscar sempre de 10 em 10 registros, por exemplo. Oas isso fica para uma próxima vez 🙂
Posted by rlechetaon Maio 22, 2016 Android, Livro Android /
Comentários desativados em github 5ed Livro Android atualizado com PreferenceFragmentCompat
Olá pessoal,
Postei no forum dos livros uma explicação sobre o PreferenceFragmentCompat, e atualizei o git do livro com exemplos.
Posted by rlechetaon Maio 04, 2016 Livros, Notícias /
Comentários desativados em Grupo de discussão para os Livros
Olá pessoal,
Como recebo muitos emails, mensagens no facebook, comentário aqui no blog, etc… criei um grupo de discussão para tirar dúvidas sobre meus livros. Peço que perguntem qualquer coisa lá para centralizar as respostas.
Esse post é para explicar meu objetivo ao escrevê-lo e qual a diferença com o Livro Android 5ª edição “a bíblia”.
Android Essencial (384 páginas) é um resumo do livro Google Android, 5ª edição (1.072 páginas).
“Para quem tem o Google Android 5ª edição, não precisa ler esse. Como eu falei o essencial é um resumo da 5ª edição.”
Para começar a explicação, vamos ler o texto que está na capa do livro:
O Android é o sistema operacional móvel mais utilizado no mundo, e o objetivo deste livro é apresentar ao leitor os conceitos essenciais do desenvolvimento de aplicativos para Android, por meio de uma explicação simples e prática.
Android Essencial é um resumo do livro Google Android, 5ª edição, com o objetivo de prepará-lo rapidamente para o mercado. É para leitores que não querem rodeios e precisam aprender logo, seja por questões de estudos ou por uma necessidade de trabalho.
Este livro utiliza o Android Studio, é focado nas boas práticas de interface do Google e do Material Design, e oferece uma abordagem prática direcionada ao desenvolvimento de aplicativos. Durante a leitura você vai desenvolver um aplicativo completo, com boa usabilidade de interface e com acesso a web services e banco de dados, além de utilizar recursos de multimídia e mapas.
O livro também apresenta capítulos resumidos dos principais conceitos da arquitetura do Android, como notificações, intents, broadcast receivers, services, alarmes, mensagens de push, câmera e fotos.
Depois de ler o livro Android Essencial você terá um bom entendimento sobre o desenvolvimento de aplicativos para Android.
O que me levou a escrever o livro foram várias coisas:
Eu precisava de uma forma rápida de treinar novos integrantes da Livetouch. Penso que o livro Google Android 5ª edição precisa ser lido por alguém que queira apavorar no desenvolvimento de apps, mas por ter + de 1.000 páginas ele não era um curso relâmpago, como muitas vezes tenho necessidade. O livro Android Essencial surgiu para isso, penso em usá-lo para treinar rapidamente os novos recursos da empresa, assim como usar em cursos pessoais, cursos na Novatec, e até como guia na Pós Graduação de Dispositivos Móveis e Computação em Nuvem que ministro na Universidade Positivo.
Por ser um resumo do Google Android 5ª edição, o livro é essencial para aprender Android rapidamente, pelo menos o básico e pode ser usado como guia em cursos. Também foi uma ideia da editora Novatec.
O livro Android Essencial tem um custo mais baixo, então também tivemos a ideia de oferecer uma opção de custo mais acessível para quem não pode comprar a 5ª edição.
Outro fator que me levou a escrever, foi ter identificado que muitas pessoas, inclusive devs bons de Android não chegam a ler o livro 5ª edição inteiro. Eu fiz capítulos avançados sobre Threads e várias coisas que percebo que muitos devs não chegam a ler. O mesmo acontece com capítulos como Bluetooth, Gestos, Wear, etc.. É o tipo de assunto que o leitor pode ler ou pesquisar quando ele tiver a necessidade (quando for usar na prática).. mas muitas vezes o que acontece é que o leitor precisa aprender o essencial que é: Instalar Android Studio, criar um projeto e executar no Android/Emulador, criar interfaces (formulários, listas), web services, banco de dados, vídeo, mapa, e é isso!
Sabendo esse básico do desenvolvimento já é suficiente para muitos devs, principalmente aqueles que não vão a fundo. Esse é o caso daquela estudante que precisa fazer o TCC correndo, vai estudar Android rápido e talvez nunca mais.
Creio que é isso pessoal.
Em minha opinião, se você quer um livro de custo mais acessível e quer aprender o básico rápido (android studio, criar telas, listas, web services, banco de dados, mapas, GPS, vídeo, foto, push, etc) e dar um tapa nos conceitos principais (intents, services, receiver, notifications), esse livro é um bom ponto de partida.
Depois de ler o livro Android Essencial você terá um bom entendimento sobre o desenvolvimento de aplicativos para Android, e então você decidirá o caminho a seguir!
Se seu objetivo foi aprender o “essencial” e se sentir satisfeito com o conteúdo, ótimo :-). Penso que vai ser o caso de muitos estudantes que precisam fazer o TCC :-). Mas se você for um desenvolvedor que vai trabalhar com Android todos os dias, recomendo ir mais a fundo. Tendo essa necessidade, você poderá complementar a leitura com o livro Google Android 5ª edição, ou a própria documentação oficial.
Este post visa esclarecer algumas coisas que mudaram no Xcode 7 e Swift 2.0.
O objetivo é ajudar os leitores do meu livro de iOS 3a edição que foi feito para iOS 8, Xcode 6 e Swift 1.1, na época.
Com a atualização do iOS 9 e Swift 2, a Apple mudou algumas coisas na sintaxe da linguagem e na assinatura de alguns métodos. Este post visa explicar alguns destes problemas, espero que ajude 🙂
Para deixar claro:
livro iphone 3 edição: iOS 8, Xcode 6 e Swift 1.1
lirvo iphone 4 edição (quando for lançado): iOS 9, Xcode 7 e Swift 2
Vamos ser rápidos, então bora pro código:
1) Wizard de migração
Se você abrir um projeto no Xcode que utiliza Swift 1, verá este wizard de migração. Recomendo clicar em Convert e ver o resultado. A função print() é uma das mudanças simples que você pode automatizar com este wizard.
2) Sobrescrevendo o construtor.
A notação a seguir para sobrescrever o construtor:
overrideinit() { … }
Mudou para (não precisa colocar a palavra override):
init() { … }
O construtor que recebe NSCode utiliza a sintaxe init? (failable initializer)
init?(coder aDecoder: NSCoder)
Portanto, caso for sobrescrevê-lo, não esqueça de colocar a ?:
No swift 1.0 somente existia a palavra chave as para fazer cast. Mas no Swift 2.0 foram criadas mais algumas opções.
· as: utilizado para fazer upcasting (cast para o tipo superior);
· as?: faz o cast (downcasting) e retorna um tipo opcional ?, portanto você deve utilizar esta maneira se possui alguma dúvida do tipo do objeto. Se o objeto não é do tipo correto é retornado nil.
· as!: faz o cast (downcasting) quando você tem certeza que é o tipo correto, e já faz o unwrapping da variável. Mas tome cuidado, pois se não for o tipo correto o aplicativo vai travar (crash);
Exemplo de código que mostra o cast com as!:
Neste código, altere a sintaxe do cast de as! para as? para ver a diferença. O compilador vai acusar erro ao utilizar a variável c pois ela é do tipo opcional. Neste caso teria que inicializá-la ou utilizar a sintaxe c!.nome. Ou ainda, se preferir a sintaxe if let como você aprendeu no livro.
5) var vs let
Você já sabe que var é uma variável e let uma constante. No Xcode 7, o compilador mostra um warning caso você utilize var em uma variável que nunca é alterada, pois nestes casos é recomendado usar let.
Um exemplo deste warning, é a figura abaixo:
Variable ‘url’ was never mutated; consider changing to ‘let’ constant
Para corrigir, troque por let. @Dica, faça isso pelo assistente de código.
6) Mudança na assinatura dos métodos de vários protocolos.
No cap 8 sobre WebView implementamos logo no início alguns métodos do protocolo UIWebViewDelegate.
A Apple já mudou algumas vezes a assinatura dos métodos. Antes não tinha o ! antes dos parâmetros, depois colocaram o ! e agora resolveram tirar de novo. Mas o compilador te ajuda nestes casos e ele avisa do erro.
Tirando o ! do parâmetro UIWebView resolve o problema. O mesmo acontece com outros protocolos, como o UITableViewDegate, etc.
7) HTTP vs HTTPs
A partir do iOS 9, requisições HTTP (mesmo com WebView) são bloqueadas pois não são seguras. A Apple recomenda o uso de HTTPS.
No app dos Carros que mostro no livro, o WebView pode falhar e mostrar o seguinte erro:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.
Para solucionar este problema no iOS 9, abra o arquivo Info.plist e adicione o item App Transport Security Settings. Dentro deste item adicione um sub-item chamado Allow Arbitrary Loads com o valor YES.
Feito isso a conexão HTTP será permitida e o exemplo com WebView que mostrei no app dos carros vai funcionar. Lembrando que isso é necessário para iOS >=9 .
8) Método supportedInterfaceOrientations()
Controle de telas na vertical e horizontal foi o assunto do capítulo 10. Na revisão do livro encontrei essa mudança.
Até o iOS 8 o método supportedInterfaceOrientations() utilizado para controlar a orientação (vertical/horizontal) da tela do view controller retornava um Int.
Agora a função ficou com uma assinatura mais esperta, e retorna direto alguma das constantes da estrutura UIInterfaceOrientationMask:
9) UILabel, a propriedade text e String vs NString
A propriedade text da classe UILabel é do tipo String.
No capítulo 10 onde estudamos o acelerômetro, tinha um código que formatava a String utilizando o construtor de NSString.
Para o código compilar foi necessário fazer o cast para String, com a notação (as String).
Isso é preciso pois o NSString é uma classe do Obj-C e a classe String é do Swift. Mas como a classe NSString contém mais métodos que a String, muitas vezes ainda utilizamos elas para fazer algumas tarefas como essa (até você descobrir outro jeito rsrs):
10) Projeto sem Launch Screen.
Ao revistar alguns projetos para iOS 9, me deparei com algumas telas com a nav bar e tab bar pretas assim:
Isso acontece porque o projeto não possui um arquivo de Launch Screen. Para solucionar crie o arquivo com o wizard > iOS > User Interface > Launch Screen e associe este arquivo nas propriedades do projeto em Target.
Por mais bizarro que isso pode ser, faça isso que vai resolver :-). Veja resultado abaixo:
11) Assinatura dos métodos do protocolo NSXMLParserDelegate
No capítulo 11 sobre XML/JSON, teve outra alteração, referente a sintaxe dos métodos do protocolo NSXMLParserDelegate.
Mas basicamente a Apple trocou de ! para ? (opcionais) alguns parâmetros. Então quando o compilador reclamar no Xcode é só trocar. Qualquer dúvida avise.
12) Obter a quantidade de elementos de um array.
No Swift 1.1 tinha a estranha função countElements(array) que agora virou array.count, algo mais comum em linguagens de programação.
Veja como ficou a sintaxe:
//Array<Carro>: array de carros…
let carros = parserXML_SAX(data)
…
// Swift 1
var count = countElements(carros)
// Swift 2
let count = carros.count
13) Idem com a classe String.
Já que falamos de como obter a quantidade de elementos, com a classe String também mudou.
Antes era countElements(string), depois virou count(string) e agora é string.characters.count.
Basicamente você acessa o array de caracteres dentro da classe String e obtem a quantidade por meio do array.
14) Try/Catch
Na explicação de parser de XML com DOM a classe SMXMLDocument era usada assim:
let document = SMXMLDocument(data: data, error:nil)
O 2º parâmetro era do tipo NSError, que inclusive nem usei no código rsrs. Isso era usado para obter o erro do método que faz o parser .
Mas no Swift 2 apareceu o try/catch e o tratamento de exceções, então o construtor deste método mudou e agora ele lança uma exceção. O Legal é usar a sintaxe try? que abrevia o try/cach e tenta executar o código que pode lançar uma exceção. Se funcionar ele retorna uma variável opcional, senão retorna nulo.
O código atualizado é assim:
let document = try? SMXMLDocument(data: data)
if(document == nil) {
print(“Erro ao ler os dados”);
return carros
}
// Continue usando o document aqui…
Como o retorno é uma variável opcional ‘?’, depois temos que fazer o unwrapping ou usar o document!. Para maiores detalhes veja no livro 🙂
15) Parser de JSON
Ainda no capítulo sobre XML/JSON, o jeito de fazer o parser de JSON com a classe NSJSONSerialization também mudou. Na verdade é porque novamente antes usava o NSError como parâmetro para obter o erro no parser, e agora é usado as exceções com try/catch.
Novamente gosto de usar o try?. Podemos até usar o if let para inicializar o dicionário do json.
Segue código atualizado:
// Faz a leitura do JSON, converte para dictionary
let dictOp = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary if let dict = dictOp {
// usar o dicionário para ler os dados do carro aqui…
} else {
// erro
}
16) Threads e Web Services
Neste capítulo não encontrei grandes mudanças, então é só para constar.
Tem pequenas coisas de ! e ? na assinatura do método dataTaskWithURLpara variar, mas nada que você não vai conseguir resolver.
17) Estilo do botão na nav bar.
No capítulo de web services, foi adicionado um botão “Atualizar” na navigation bar. Esse botão faz a atualização da lista de carros. No iOS9 o estilo Bordered ficou deprecated. Agora recomenda-se utilizar o estilo Plain.
let btAtualizar = UIBarButtonItem(title: “Atualizar”, style: UIBarButtonItemStyle.Plain,target: self, action: “atualizar”)
No capítulo de persistência de dados, a classe Prefs tem uma pequena mudança.
let valorInt = valorString.toInt()
Isso mudou para:
let valorInt = Int(valorString)
19) SQLite
Na parte de SQLite teve poucas mudanças. Nada que trocar uns ! por ? e fazer cast com as! não resolva.
Se alguém tiver problemas é só me informar aqui neste post.
20) Mapas
Na parte de mapas não teve grandes mudanças.
Teve esse construtor do UIButton que mudou de:
let btPin = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as UIView
Para:
let btPin = UIButton(type: UIButtonType.DetailDisclosure) as UIView
No exemplo de Geocoding a assinatura do método mudou. Para auxiliar, veja trecho do código atualizado mostrado no livro.
21) Video
No capítulo de multimídia, a classe VideoUtil teve um problema no iOS9, pois a classe MPMoviePlayerController ficou deprecated. No iOS9, A Apple recomenda usar a AVPlayerViewController.
Para ajudar o pessoal que comprou a 3ª edição, segue classe atualizada 😉
Como no iOS 9 utiliza-se a classe AVPlayerItem, devemos utilizar as suas constantes de notificação para monitorar os eventos do player de vídeo. No exemplo que mostro para interceptar o evento do fim do vídeo, basta trocar a constante por esta:
Novamente devido ao novo tratamento de exceções e o uso de try/catch, temos algumas mudanças em outras classes, pois não é mais usado aquele NSError como parâmetro.
Um exemplo desta alteração, é no exemplo que mostra como tocar e gravar músicas com a classe AVAudioPlayer.
do {
// Inicializa o player com a URL do arquivo
self.player = try AVAudioPlayer(contentsOfURL: url)
} catch let error as NSError {
self.player = nil
print(“Error \(error)”)
return
}
23) Câmera e galeria de fotos
Na parte da câmera e tirar fotos não teve mudanças.
Mas no exemplo que mostra como acessar a galeria de fotos, os métodos do protocolo UIImagePickerControllerDelegate mudaram um pouco. Segue trecho atualizado:
No capítulos sobre Quartz e Views customizadas, foi mostrado como tratar o evento de touch. Como a assinatura do método mudou, segue aqui o código atualizado:
Olá pessoal, sempre recebo emails sobre dúvidas referente as diferenças do livro de AWS e de REST, então esse post é para explicar. Assim sempre faço o link com esse post para responder 😉
Vamos lá, serei breve nas diferenças.
1) AWS
O livro de AWS fala apenas sobre computação em nuvem e explica com utilizar os serviços da Amazon AWS.
O objetivo é explicar como configurar servidores na internet, para que você seja dono do seu próprio data-center.
O livro explora assuntos básicos como servidores e bancos de dados na nuvem, e até avançados da AWS como: cache de informações, serviços de filas e balanceadores de carga.
Vale lembrar que este livro não fala sobre como desenvolver web services. Não é um livro sobre programação. O objetivo é ensinar o leitor a configurar um servidor na nuvem utilizando a Amazon como provedor de serviço.
Ele é muito mais avançado do que o do REST no sentido de configurar um servidor, pois fala de balanceamento de carga, etc..
2) REST
O objetivo desse livro é ensinar a criar web services em java. Esse é um livro sobre programação.
O livro vai desde o básico, como por exemplo: configurar um banco de dados local para desenvolvimento, é feito Hello World de programação web para Java e o assunto sobre web services vai sendo explicado aos poucos.
É feito um desenvolvimento completo de um aplicativo de Carros, com banco de dados e web services. Para testar os web services o livro inclusive possui um pacote de “bônus” com um aplicativo Android e um sistema web em AngularJS. No app Android inclusive você tira uma foto e a envia pelo web service para o servidor. No sistema web você poderá ver toda a lista de carros.
Na segunda parte do livro, ensino como criar um servidor na nuvem do Google para disponibilizar o web service criado no próprio livro. Assim você poderá testar seu web service lá na internet.
@Obs: caso você leia o livro de AWS, pode instalar estes web services lá na Amazon também.
Porém referente a esta parte de configuração de servidor, no livro de REST a explicação é básica, já no livro de AWS essa parte vai mais a fundo.
3) Estou na dúvida de qual comprar, e agora?
Isso depende… vou dar alguns exemplos:
Se você precisa aprender a desenvolver web services em Java ou se seu objetivo é aprender coisas sobre programação, vai de REST.
Se você já sabe programar em alguma linguagem e quer aprender sobre computação em nuvem, vai de AWS. O livro de REST também explica um pouco dessa parte, a diferença é que é mostrada a plataforma do Google ao invés do de AWS.
Mas por mim, leria ambos :-). Quem me dera saber tudo isso à uns 10/15 anos atrás quando eu precisava fazer essas coisas e não sabia rsrs.. No livro está tudo mastigado.
AWS e Google são dois gigantes da internet e computação em nuvem, e ambos os livros vão lhe dar uma boa base para o mercado web.
Caso você esteja no início da faculdade e começando no assunto, vai de REST pois ele é mais simples. O de AWS vai complementar seus estudos e vai lhe dar ideias mais avançadas.
Olá pessoal, foi lançado o livro Google Android 5ª edição 🙂
Esta edição foi lançada (5 meses depois do lançamento da 4ª), e este post é só para tranquilizar quem possui a 4ª edição.
Quem acompanhou o processo de escrita do livro sabe, que um livro de +- 1.000 páginas demora bastante para sair do forno, e na reta final do lançamento (2 semanas antes) teve o Google I/O 2015. Neste evento o Google lançou a lib do Material Design.
Então nas últimas 2 semanas do lançamento da 4ª edição, foi uma correria para eu atualizar o livro e felizmente deu tempo de atualizar muita coisa, como por exemplo:
Explicações de Material Design
Layout com Tabs
Floating Action Button (FAB)
SnackBar
Animações de transições entre activities
Enfim, é a última vez que atualizo antes do Google I/O rsrs..
Mas nessa atualização de última hora, ficaram dois assuntos de fora, pois não tive tempo.
1ª) Navigation Drawer (menu lateral). Na 4ª edição foi explicado um fragment que gerava o menu lateral. Este fragment foi baseado no template que o próprio Android Studio criava na época.
Na 5ª edição foi alterado para usar o NavigationView, que é o novo componente do Google para criar o menu lateral.
Mas não se preocupe, pois esse componente é muito simples e fiz um tutorial para você entender ele aqui. Assim você não perde nada 🙂
2ª) A outra alteração na verdade é uma “adição” de conteúdo. No final do capítulo 15 adicionei uma explicação referente a como criar animações na toolbar durante a rolagem da lista (algo bem comum nos aplicativos atualmente).
Estou falando destas animações na toolbar quando você rola a tela para cima e para baixo:
Este item é um conteúdo novo, portanto não descarta nada do que você aprendeu na 4ª edição.
Sobre estas técnicas de rolagem do Material Design, fiz um tutorial passo a passo bem simples que mostra como aplicá-las em uma tela com uma lista de planetas.
Então recomendo você ver esse post abaixo para complementar seus estudos e aprender à criar estes efeitos. Se você leu meu livro deve estar com um conhecimento bom de Android, então vai tirar este tutorial de letra.
Bom pessoal, não quero me estender muito, pois foi só isso que mudou na 5ª edição.
Quando fui fazer uma revisão para uma nova impressão do livro, acabei escrevendo demais e o número de páginas do livro mudou. O resultado foi que a editora teve que lançar uma nova edição.
Então quem comprou a 4ª edição, podem ficar tranquilos, pelos motivos já explicados acima.
As vezes é complicado acompanhar tantas mudanças, mas fazemos o possível 🙂
E quem tem o livro sabe onde encontrar o código-fonte… Então qualquer dúvida é só dar uma espiada no fonte dos carros da 5ª edição que você vai ver o projeto completo lá 🙂
No livro Google Android 4ª edição mostrei como fazer o Navigation Drawer (menu lateral) usando um fragment, que foi baseado no próprio fragment que o Android Studio gerava como template ao criar um projeto.
No Google I/O 2015 o Google lançou a lib do Material Design e dentre os novos componentes, foi criada a classe NavigationView, que facilita justamente criar este menu lateral.
Usar esta classe não requer prática nem habilidade, e você verá como é simples neste post.
Caso queira ver a explicação direta do Google, no canal do Android Developpent Patterns foi disponibilizado um vídeo explicando como utilizar o NavigationView, recomendo assistir, este canal é show!
Mas vamos explicar passo a passo aqui. Bom, algo simples que você pode fazer é utilizar o próprio wizard do Android Studio e escolher o template do Navigation Drawer conforme esta figura.
Ao gerar o wizard, você verá que tudo continua como expliquei no livro. É usado o DrawerLayout na raiz do layout e dentro dele o NavigationView (que substitui o fragment que mostrei no livro 4ª edição).
O Navigation view possui 2 propriedades simples para configurar o menu lateral.
A 1ª propriedade é a app:headerLayout=”@layout/nav_header_hello_nav_drawer”, é utilizada para definir o layout do cabeçalho do menu. É possível criar o layout que você quiser aqui, e um bom exemplo é o layout que o próprio Android Studio gera. Na figura abaixo este header é aquela parte verde.
A 2ª propriedade do NavigationView é o app:menu=”@menu/activity_hello_nav_drawer_drawer”, que define um arquivo de menu (formato XML) para compor as opções do menu lateral.
Ficou tudo muito simples, pois este arquivo de menu possui o mesmo formato do arquivo de menu que usamos para a action bar / toolbar.
Faça os seus testes, e confira o wizard do Android Studio!
Mas e o projeto dos Carros do livro Google Android 4ª edição é possível atualizar para utilizar o Navigation View?
Claro que sim, demora uns 5 minutos se você seguir este tutorial.
1) Altere o arquivo de layout activity_main.xml para declarar o NavigationView. Ele vai entrar exatamente no lugar daquele fragment que mostrei no livro.
Veja que a forma de tratar eventos é simples, pois é só implementar o método onNavDrawerItemSelected().
private void onNavDrawerItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.nav_item_carros_todos:
// tratar os eventos aqui
break;
case R.id.nav_item_carros_classicos:
// tratar os eventos aqui
break;
case R.id.nav_item_carros_esportivos:
// tratar os eventos aqui
break;
case R.id.nav_item_carros_luxo:
// tratar os eventos aqui
break;
case R.id.nav_item_site_livro:
// tratar os eventos aqui
break;
case R.id.nav_item_settings:
// tratar os eventos aqui
break;
}
}
É só isso, usar o NavigationViewpara criar o menu lateral é bem simples, espero que este post tenha ajudado quem quiser entender um pouco mais sobre este componente, e também os leitores do livro Google Android 4ª edição.
Lembre-se que o código-fonte do livro 5ª edição está no github, então é só consultar o app dos Carros sempre atualizado :-).
Olá pessoal, o objetivo deste tutorial é mostrar passo a passo como criar o app (vídeo abaixo) demonstrado no DevFest Sul 2015.
Este tutorial será bem prático, então vamos lá!
1) Criar o projeto no Android Studio:
Utilize o o wizard > File > New Project.
Atenção: No wizard digite br.com.devfestsul no campo Company Domain, pois assim todas as classes e código-fonte que forem copiados durante este tutorial vão funcionar prontamente.
Selecione qualquer API Level. Eu deixei com a opção padrão.
Selecione o template para criar o Navigation Drawer que é o menu lateral.
No final do wizard, aceite o padrão que é criar a MainActivity e clique em Finish.
2) Execute o projeto no emulador.
O resultado deve ser como a figura abaixo. O wizard do Android Studio já criou o Nav Drawer (menu lateral).
3) Faça o download dos arquivos para ajudar na digitação do código.
Para auxiliar a execução do exercício, este arquivo contém algumas activities e fragments para mostrar uma lista de planetas e uma tela de detalhes.
Este arquivo não tem nada de mais, e vou explicar cada classe quando chegar o momento.
Ao descompactar o arquivo você verá algumas pastas.
Entre na pasta resources-1.
Copie ambas as pastas java e res (Fazendo Ctrl+C) e cole (CTRL+V) no Android Studio.
Mas para colar, deixe o Android Studio no modo de navegação Project, e com a pasta /app/src/main selecionada, conforme mostra a figura.
Ao colar (CTRL+V), alguns arquivos serão substituídos, como por exemplo, o arquivo colors.xml. Clique em Override for all para confirmar.
Depois de copiar os arquivos você verá várias classes. Não vou explicar cada uma pois isso é Android básico.
A única coisa que você precisa saber é que o fragment PlanetaListFragment mostra uma lista de planetas. Ao clicar em algum planeta, a activity PlanetaActivity é aberta para mostrar os detalhes. Esta activity insere no seu layout o fragment PlanetFragment.
Eu gosto de utilizar este modelo: a activity controla a navegação de telas e os fragments controlam o conteúdo.
Depois de copiar os arquivos, volte o modo de visualização para Android, pois a visualização fica mais enxuta, sendo mais fácil de encontrar os arquivos.
4) Adicionando o fragment que lista os planetas.
O layout da activity main mostra apenas um TextView, portanto em seu lugar vamos adicionar um layout de marcação para adicionar o fragment da lista.
O código que lista os planetas está usando algumas libs como RecyclerView e CardView do Material Design. Então vamos adicionar estas bibliotecas (e outras) no app/build.gradle.
Feito isso execute o projeto novamente. O resultado será a lista de planetas (PlanetaListFragment). Ao clicar em algum planeta você verá a tela de detalhes (PlanetaActivity / PlanetaFragment).
Repare que a system bar (barra superior onde mostra o relógio) está transparente na tela do planeta, e isso está errado.
Isso acontece porque utilizamos o tema AppTheme.NoActionBar para a activity PlanetaActivity, pois era preciso remover a action bar, a fim de adicionar a Toolbar.
Caso não conheça a Toolbar, sugiro reforçar o conceito antes de continuar.
O problema é que o Android Studio criou um único tema para a 1ª tela que mostra o Nav Drawer e para as demais activities. Porém, este recurso de deixar a barra de sistema transparente deveria ser utilizado apenas pela MainActivity, pois ela precisa disso para o Nav Drawer abrir em tela cheia, sobre a system bar.
Para corrigir o problema, vamos criar um tema mais elaborado, para isso vamos copiar o arquivo /res/values/styles.xml e /res/values-v21/styles.xml da pasta resources-2-styles.
Depois de substituir os arquivos no projeto, o arquivo de styles.xml será assim:
/res/values/styles.xml
<resources>
<!-- Base application theme. -->
<style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorControlHighlight">@color/colorControlHighlight</item>
</style>
<!-- Tema do projeto -->
<style name="AppTheme" parent="BaseAppTheme" />
<!-- Nav Drawer -->
<style name="AppTheme.NavDrawer" parent="BaseAppTheme" />
<!-- Toolbar -->
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat" />
</resources>
Já o arquivo da pasta /res/values-v21 vai customizar o tema para o Android 5.0 ou superior.
Note que no AppTheme foi adicionado as propriedades para fazer a animação de transição entre activities. E no tema AppTheme.NavDrawer foi deixado a system bar transparente, algo que vamos usar apenas na MainActivity, pois somente ela mostra o Nav Drawer.
/res/values-v21/styles.xml
<resources>
<!-- Activity Animations para API Level 21 -->
<style name="AppTheme" parent="BaseAppTheme" >
<!-- Activity Animations -->
<item name="android:windowEnterTransition">@android:transition/fade</item>
<item name="android:windowExitTransition">@android:transition/fade</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
<!-- Nav Drawer em full screen para API Levle 21 -->
<style name="AppTheme.NavDrawer" parent="BaseAppTheme">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
Uma vez que os temas estão configurados altere o AndroidManifest.xml para que o tema padrão na tag <application> seja AppTheme. Deixe apenas a MainActivity com o tema AppTheme.NavDrawer. O restante das activities não precisam declarar o tema, pois será utilizado o tema padrão definido na tag <application>.
A figura abaixo mostra como tem que ficar a configuração:
Pronto! Execute o projeto novamente e desta vez a tela do planeta estará com a system bar com a cor azul primaryDark definida no tema e no arquivo colors.xml.
Lembrando que a MainActivity utiliza o outro tema, pois o Nav Drawer abre sobre a system bar, e por isso que neste caso ela precisa ser transparente.
5) Brincando com animações durante a transição de telas
No arquivo /res/values-v21/styles.xml o tema AppTheme foi customizado para habilitar as propriedades das animações das activities (no caso de Android >= 5.0).
O segredo para fazer a animação de transição de telas, é utilizar o método ActivityOptionsCompat.makeSceneTransitionAnimation(…) ao invés do clássico método startActivity(intent).
Faça o seguinte: Clique uma vez na raiz do projeto e depois utilize a tecla de atalho Ctrl+Shift+F (Find) para abrir o janela de busca. Na janela digite (1).
Isso vai encontrar no código três lugares onde deixei o comentário (1). A única coisa que você precisa fazer é descomentar o código como vou explicar a seguir.
Na classe PlanetaListFragment troque o startActivity(intent) pelo seguinte código:
Na classe PlanetaFragment remova o comentário da seguinte linha:
PlanetaFragment.java
// (1) Chave da animação
ViewCompat.setTransitionName(img, getString(R.string.transition_key));
E na classe PlanetaAdapter também remova o comentário:
PlanetaAdapter.java
// (1) Chave da animação
ViewCompat.setTransitionName(holder.img, context.getString(R.string.transition_key));
O que fizemos foi ativar a chave compartilhada (transition key) do ImageView entre a tela da lista (adapter) e a tela de detalhes.
Como o ImageView possui a mesma chave de transição entre as duas telas, a transição entre as duas activities será animada.
Portanto vá em frente e execute o código. O resultado será a animação que você viu no vídeo no início deste tutorial.
Por padrão a animação de transição de uma activity é desfeita ao clicar no botão voltar.
Porém, também por padrão, se você clicar no botão up navigation da toolbar (aquele lá em cima com a seta para a esquerda) a animação não acontece.
Mas como eu já chamei o método supportFinishAfterTransition() ao clicar no botão up navigation (android.R.id.home) esta animação foi feita (por isso funcionou). Moral da história, sempre chame o método supportFinishAfterTransition() no lugar do finish() para executar a animação inversa ao sair da tela.
6) Adicionando as Tabs + ViewPager
A lib do Material Designa possui o componente TabLayout que facilita a criação das tabs, e o melhor de tudo é que ela funciona de forma integrada ao ViewPager.
Neste exemplo vou criar duas tabs, Planetas e Constelações. Porém para facilitar a explicação, vou adicionar o mesmo fragment dos planetas em ambas as tabs ahha. Sendo assim, se quiser melhore o exemplo depois.
Então mãos a obra!
No arquivo app_bar_main.xml, troque o layout de marcação “fragContainer” que adicionamos anteriormente pelo ViewPager:
No lugar deste código vamos adicionar o método setupViewPagerTabs();
Este método deverá ser criado na classe MainActivity:
MainActivity.java
private void setupViewPagerTabs() {
// ViewPager
ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(new TabsAdapter(this, getSupportFragmentManager(),getIntent().getExtras()));
// Tabs
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
// Cria as tabs com o mesmo adapter utilizado pelo ViewPager
tabLayout.setupWithViewPager(viewPager);
int cor = ContextCompat.getColor(this, R.color.white);
// Cor branca no texto (o fundo azul foi definido no layout)
tabLayout.setTabTextColors(cor, cor);
}
Para o código compilar adicione a seguinte linha no arquivo colors.xml. Esta cor é utilizada para configurar a cor do título das tabs.
<color name="white">#ffffff</color>
Pronto, as Tabs + ViewPager já estão funcionando. Ao executar o projeto o resultado será o seguinte:
7) Brincando com Scroll.
No arquivo include_toolbar.xml adicione o seguinte atributo dentro da Toolbar:
app:layout_scrollFlags="scroll|enterAlways"
Isso fará com que a Toolbar suma da tela ao fazer o scroll da lista de carros. O print a seguir mostra este efeito ao fazer a rolagem. Se quiser veja no vídeo no início do tutorial que fica mais claro.
Ooops, você deve ter percebido algo de errado na figura, ou talvez no emulador. A toolbar invadiu o espaço da system bar e ficou meio pra fora da tela. Tem algo errado.
Isso acontece porque o wizard do Android Studio gerou o código do CoordinatorLayout com o atributo android:fitsSystemWindows=”true” que faz com que este layout ocupe a tela inteira. Mas isso está errado. Esse atributo só deve ser usado no DrawerLayout e NavigationView, lá dentro da MainActivity. Pois somente na tela inicial vamos utilizar o Nav Drawer.
Então remova o código indicado em amarelo na figura:
app_bar_main.xml
Feito isso, o código deve funcionar conforme o esperado.
8) Scroll e o botão FAB.
Outro efeito interessante que é comum encontrar neste tipo de tela, é animar (show/hide) o botão FAB (Floating Action Button) durante a rolagem. Isso pode ser feito implementando uma classe de Behavior customizada, pois o CoordinatorLayout permite que seus filhos reajam ao efeito de scroll por meio desta classe de comportamento.
Já existe no projeto a classe ScrollAwareFABBehavior, portanto basta adicionar a seguinte linha no botão FAB no arquivo app_bar_main.xml:
Com esta alteração, quando rolar a lista, o botão FAB vai executar a animação definida no arquivo /res/anim/fab_out.xml. E quando a lista rolar novamente para cima, a animação contrária será executada /res/anim/fab_in.xml.
Você pode ver a animação no vídeo mostrado no início do tópico, e como você pode ver o botão FAB vai sumir ao fazer a rolagem da lista e depois vai aparecer novamente.
9) Efeito de rolagem na tela de detalhes.
No vídeo você pode ver que na tela de detalhes o app está mostrando a foto do planeta na Toolbar.
Para construir este layout, você deve organizar seu layout +- com estes componentes.
Mas este desenho assusta mais do que o necessário. Na prática é bem simples.
Eu já deixei no projeto a classe CollapsingToolbarActivity que já faz toda a mágica. E o arquivo /res/layout/activity_collapsing_toolbar.xml contém o layout descrito nesta figura.
Você está duvidando que é simples? Então vamos lá.
Altere a classe PlanetaActivity para ser filha de CollapsingToolbarActivity .
Depois copie o fonte do arquivo activity_collapsing_toolbar.xml para o arquivo activity_planeta.xml. Ou utilize o layout activity_collapsing_toolbar.xml.
Chame o método initViews() dentro do método onCreate(bundle).
Confira como ficaram estas 3 alterações:
Ao executar o projeto e clicar no planeta Terra, o resultado será o seguinte:
No centro do layout a foto do planeta Terra será corretamente exibida, pois isso era o que a classe PlanetaFragment já fazia.
No layout da (AppBar / Toolbar / CollapsingToolbarLayout) está fixo um ImageView com a foto do planeta Marte.
O que precisamos fazer é remover o ImageView do layout da classe PlanetaFragment. Isso deve ser feito tanto no layout XML quanto no código Java.
No arquivo fragment_planeta.xml basta comentar o ImageView como mostra nesta figura:
E no código da classe PlanetaFragment também remova o código do ImageView.
No lugar do ImageView, utilize o seguinte código (que vai setar a imagem diretamente na App Bar)
Confira como ficou o código nesta figura:
Pronto! Execute o projeto e veja que a foto do planeta será mostrada no header da App Bar. E o melhor de tudo é que o scroll flexível já está funcionando. Você verá que afoto do planeta vai diminuir ou aumentar, conforme a rolagem é feita.
10) Mostrando o nome do planeta na AppBar / Toolbar
Até o momento na tela de detalhes, o texto “Planetas” está fixo no header da CollapsingToolbarLayout, pois por padrão o nome do aplicativo é mostrado como título.
Para mostrar o nome do planeta no header, temos que passar o objeto Planeta como parâmetro para a próxima tela, pois atualmente estamos passando apenas o int que é a a referência ao recurso de uma imagem R.drawable.
Para passar parâmetros para a outra tela podemos fazer a classe Planeta implementar a interface Serializable, ou melhor ainda interface Parcelable (que é mais performática). Mas como implementar a interface Parcelable não é simples, vamos utilizar a lib parcels (já adicionada no build.gradle).
Para isso, adicione a anotação @Parcel na classe Planeta conforme indicado na figura.
Na classe PlanetaListFragment vamos trocar a forma de passar parâmetro de:
intent.putExtra("imgPlaneta", p.img);
Para:
intent.putExtra("planeta", Parcels.wrap(p));
Neste caso a classe Parcels faz a mágica de converter o objeto planeta para o tipo Parcelable.
A figura baixo mostra a alteração:
Na classe PlanetaFragment precisamos ler o objeto Planeta, portanto utilize o código abaixo. Neste caso a foto e o nome do planeta são mostrados na App Bar.
Planeta p = Parcels.unwrap(getArguments().getParcelable("planeta"));
if (p != null) {
CollapsingToolbarActivity activity = (CollapsingToolbarActivity) getActivity();
activity.setAppBarImage(p.img);
activity.setAppBarTitle(p.nome);
}
Para sua validação, a figura abaixo mostra como o código tem que ficar:
Ao executar o projeto novamente veja que tanto a foto quanto o título do planeta aparecem na App Bar. Na prática este é o espaço do CollapsingToolbarLayout.
O nome CollapsingToolbarLayout é um tanto quanto sugestivo certo?
11) Paleta de cores
Para melhorar ainda mais a brincadeira, vamos brincar com a paleta de cores. O objetivo é extrair a cor da foto do planeta e pintar o fundo da App Bar com esta cor.
Por exemplo, o fundo do planeta Terra ficará azul, mas do planeta Marte ficará meio laranja.
Esta parte é simples, portanto só copie o código do github:
Neste código a classe Palette é responsável por fazer a extração da cor. Veja que adicionamos esta biblitoteca no build.gradle no início do tutorial.
Na figura eu marquei com uma seta dois métodos da classe CollapsingToolbarLayout:
O método setBackgroundColor(color) define a cor de fundo extraída da figura.
O método setContentScrimColor(color) define a cor usada pela toolbar, quando a imagem é contraída. O código extrai a variação escura “dark” para esta cor. No vídeo fica bem claro a diferença de cores.
Você verá que no código também estou pintando cada TextView da tela do planeta com uma cor diferente, todas extraídas da foto por meio da paleta de cores. Por isso deixei 6 TextViews no layout.
12) Botão FAB na CollapsingToolbarLayout
Para fechar o tutorial, adicione este botão FAB no layout da tela do planeta. Veja que ele é ancorado na App Bar.
Ao executar o projeto, você verá o botão FAB com o símbolo de (+) na App Bar. Ele está lá pois o atributo layout_anchor (âncora) foi definido na App Bar. Simples não é? E o melhor de tudo, é que o botão FAB vai animar automaticamente durante a rolagem.
É isso pessoal, espero que este tutorial tenha ajudado alguém, qualquer dúvida é só entrar em contato. Abs.