Android

Livro Android Essencial

Posted by rlecheta on março 15, 2016
Android, Livro Android, Livros / 20 Comments

Olá pessoal,

Foi lançado meu livro Android Essencial  :-).

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.”

capa_android_essencial

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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!
  5. 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.

Lembre-se: O livro Android Essencial (384 páginas) é um resumo do Google Android 5ª edição (1.072 páginas).

Livro Google Android 5ª edição

Posted by rlecheta on novembro 26, 2015
Android, Livro Android, Livros / 117 Comments

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 🙂

NavigationView – A nova view para criar o Navigation Drawer

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.

GDG DevFest Sul 2015 – Animações na Toolbar


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á 🙂

Qualquer dúvida, estou a disposição como sempre.

abraços

NavigationView – A nova view para criar o Navigation Drawer

Posted by rlecheta on novembro 23, 2015
Android, Livro Android / 29 Comments

Olá pessoal

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.

10.002-parte1

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.

Screen Shot 11-23-15 at 04.00 PM

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).

A seguir um exemplo do NavigationView.

Screen Shot 11-23-15 at 04.12 PM

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.

Screen Shot 11-23-15 at 04.17 PM

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.

Sabemos que o NavigationView vai usar um arquivo de header e menu.

O arquivo de header é o mesmo nas 4ª e 5ª edições:

Já o arquivo com as opções de menu é este aqui aqui. Simples não é?

No código da BaseActivity, é só mudar a implementação do método setupNavDrawer() para usar o NavigationView, segue código-fonte atualizado.

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 NavigationView para 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 :-).

https://github.com/livroandroid/5ed

GDG DevFest Sul 2015

Posted by rlecheta on novembro 14, 2015
Android, Eventos / 4 Comments

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.

Screen Shot 11-13-15 at 05.32 PM

Selecione qualquer API Level. Eu deixei com a opção padrão.

Screen Shot 11-13-15 at 05.32 PM 001

Selecione o template para criar o Navigation Drawer que é o menu lateral.

Screen Shot 11-13-15 at 05.32 PM 002

No final do wizard, aceite o padrão que é criar a MainActivity e clique em Finish.

Screen Shot 11-13-15 at 05.33 PM

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).
a

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.

https://raw.githubusercontent.com/rlecheta/DevFestSul2015/master/Resources.zip

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.

Screen Shot 11-13-15 at 05.54 PM

Entre na pasta resources-1.

Screen Shot 11-13-15 at 05.54 PM 001

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.

d

Ao colar (CTRL+V), alguns arquivos serão substituídos, como por exemplo, o arquivo colors.xml. Clique em Override for all para confirmar.

Screen Shot 11-13-15 at 05.55 PM 001

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.

Screen Shot 11-13-15 at 05.55 PM 002

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.


e

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.

  • app_bar_main.xml

Altere esta linha:

 
<include layout="@layout/content_main" />

Por esta:

<LinearLayout
 android:id="@+id/fragContainer"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Adicione o fragment pela API na classe MainActivity, lá no final do método onCreate(bundle).

  • MainActivity.java
if(savedInstanceState == null) {
 getSupportFragmentManager().beginTransaction().add(R.id.fragContainer,new PlanetaListFragment(),null).commit();
}

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.

compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.android.support:palette-v7:23.1.1'
compile 'org.parceler:parceler:1.0.4'
compile 'org.parceler:parceler-api:1.0.4'
compile 'com.squareup.picasso:picasso:2.5.2'

A última configuração é adicionar a activity PlanetaActivity no arquivo de manifesto.

  • AndroidManifest.xml
<activity android:name=".activity.PlanetaActivity" android:theme="@style/AppTheme.NoActionBar" />

Feito isso execute o projeto novamente. O resultado será a lista de planetas (PlanetaListFragment).
c
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.
d

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.

Screen Shot 11-13-15 at 06.22 PM

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:

tema

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.

e

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:

  • PlanetaListFragment.java
String key = getString(R.string.transition_key);
ImageView img = holder.img;
ActivityOptionsCompat opts = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), img, key);
ActivityCompat.startActivity(getActivity(), intent, opts.toBundle());

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.

Screen Shot 11-13-15 at 08.59 PM

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:

  • app_bar_main.xml
<android.support.v4.view.ViewPager
 android:id="@+id/viewPager"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 app:layout_behavior="@string/appbar_scrolling_view_behavior" />

E no mesmo arquivo, logo abaixo da toolbar adicione as Tabs.

<android.support.design.widget.TabLayout
 android:id="@+id/tabLayout"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 />

Se precisar confira como ficou o layout do arquivo aqui:

https://github.com/rlecheta/DevFestSul2015/blob/master/Planetas/app/src/main/res/layout/app_bar_main.xml

Na MainActivity, vamos remover o código que adicionava o fragment da lista de planetas:

if(savedInstanceState == null) {
      getSupportFragmentManager().beginTransaction().add(R.id.fragContainer,new PlanetaListFragment(),null).commit();
}

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:

tabs

7) Brincando com Scroll.

No arquivo include_toolbar.xml adicione o seguinte atributo dentro da Toolbar:

app:layout_scrollFlags="scroll|enterAlways"

Screen Shot 11-13-15 at 09.17 PM

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.

a

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

Screen Shot 11-13-15 at 09.21 PM

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:

app:layout_behavior=”br.com.devfestsul.planetas.utils.ScrollAwareFABBehavior”

Screen Shot 11-13-15 at 09.34 PM

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.

Este efeito é chamado na documentação do Material Design de Flexible space with image.

Para construir este layout, você deve organizar seu layout +- com estes componentes.

15.006

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á.

  1. Altere a classe PlanetaActivity para ser filha de CollapsingToolbarActivity .
  2. Depois copie o fonte do arquivo activity_collapsing_toolbar.xml para o arquivo activity_planeta.xml. Ou utilize o layout activity_collapsing_toolbar.xml.
  3. Chame o método initViews() dentro do método onCreate(bundle).

Confira como ficaram estas 3 alterações:

Screen Shot 11-13-15 at 09.57 PM

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.

terra

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:

Screen Shot 11-13-15 at 10.07 PM

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)

CollapsingToolbarActivity activity = (CollapsingToolbarActivity) getActivity();
activity.setAppBarImage(imgPlaneta);

Confira como ficou o código nesta figura:
Screen Shot 11-13-15 at 10.10 PM
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.

terra

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.

Screen Shot 11-13-15 at 10.54 PM 001

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:
Screen Shot 11-13-15 at 10.59 PM
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:

Screen Shot 11-13-15 at 11.02 PM
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?

terra
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:

https://github.com/rlecheta/DevFestSul2015/blob/master/Planetas/app/src/main/java/br/com/devfestsul/planetas/fragments/PlanetaFragment.java

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.

Screen Shot 11-13-15 at 11.11 PM

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.

Screen Shot 11-13-15 at 11.28 PM

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.

mais
É isso pessoal, espero que este tutorial tenha ajudado alguém, qualquer dúvida é só entrar em contato. Abs.

https://plus.google.com/+RicardoLecheta

https://www.facebook.com/ricardolecheta

https://twitter.com/rlecheta

Sistema de permissões do Android 6.0

Posted by rlecheta on outubro 02, 2015
Android, Tutorial / 10 Comments

Olá pessoal, este post visa explicar um recurso importante do Android 6.0 (Marshmallow) que se você não conhecer pode quebrar seu aplicativo.

A partir do Android 6.0 (API 23) os aplicativos precisam pedir permissões em tempo de execução para utilizar determinadas APIs, como por exemplo: escrever no sdcard, câmera, localização, etc.

Farei um resumo aqui, mas recomendo que você leia a documentação oficial para pegar todos os detalhes:

http://developer.android.com/guide/topics/security/permissions.html

http://developer.android.com/training/permissions/index.html

  • Caso o código seja compilado com a API 22 (targetSdkVersion 22), o comportamento antigo ainda se aplica, ou seja, o usuário precisará aceitar todas as permissões no momento da instalação do aplicativo.
  • Caso o código seja compilado com a API 23 (targetSdkVersion 23), o aplicativo será instalado diretamente sem confirmar as permissões. Porém, em tempo de execução o aplicativo deverá solicitar a permissão do usuário para utilizar as funcionalidades restritas. Somente quando o usuário aceitar a permissão, o aplicativo pode usar a funcionalidade desejada.

As permissões são divididas entre normais e perigosas (dangerous). As permissões normais, exemplo: acessar a internet, bluetooth, etc, podem ser acessadas diretamente sem a confirmação do usuário. Já as permissões perigosas, como escrever no sdcard, acessar a localização, utilizar a câmera, etc, precisam da aprovação do usuário.

Para maiores detalhes sobre a lista de permissões, recomendo ler a documentação oficial:

http://developer.android.com/guide/topics/security/permissions.html#normal-dangerous

Dito isso, vamos partir para a prática. Sempre que precisar utilizar alguma funcionalidade restrita precisamos verificar se o usuário já autorizou o acesso. O código a seguir mostra como validar se o usuário permitiu o aplicativo escrever no cartão de memória.

boolean ok = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

Caso o retorno seja verdadeiro, podemos escrever um arquivo no cartão de memória, caso contrário precisamos pedir a permissão com o método requestPermissions(activity,permissoes,requestCode). Isso é feito com o seguinte template de código:

 
// Se não possui permissão
if (ContextCompat.checkSelfPermission(thisActivity,WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
      // Verifica se já mostramos o alerta e o usuário negou na 1ª vez.
      if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
           // Caso o usuário tenha negado a permissão anteriormente, e não tenha marcado o check "nunca mais mostre este alerta"
           // Podemos mostrar um alerta explicando para o usuário porque a permissão é importante.
      } else {
          // Solicita a permissão
          ActivityCompat.requestPermissions(thisActivity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
      }
} else {
      // Tudo OK, podemos prosseguir.
}

Note que este código utiliza as classes ContextCompat e ActivityCompat para manter a compatibilidade, pois estes métodos de solicitar permissões somente existem no Android 6.0.

Depois de solicitar a permissão com o método requestPermissions(activity,permissoes,requestCode), o usuário verá um alerta para aceitar ou não a permissão, conforme a figura abaixo.

18.004

O resultado da decisão do usuário será entregue via o método onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults), que recebe como parâmetro o código da chamada (requestCode), a lista de permissões e a lista de respostas do usuário.

@Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
 switch (requestCode) {
      case 0: {
      if (grantResults.length &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; 0 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; grantResults[0] == PackageManager.PERMISSION_GRANTED)      {
           // Usuário aceitou a permissão!
      } else {
           // Usuário negou a permissão.
           // Não podemos utilizar esta funcionalidade.
      }
      return;
     }
   }
}

Basicamente é isso!

Entenda que estas solicitações devem ser feitas a medida que você for usando o aplicativo. Por exemplo, somente quando for necessário obter a localização (GPS) você deverá fazer todo esta verificação. E lembre-se que caso o usuário negue a permissão, você deverá desabilitar as funcionalidades, pois qualquer tentativa de utilizar a API neste caso resultaria em uma SecurityException.

Dadas estas explicações, vamos fazer um exemplo prático.

Se você possui o livro Google Android 4ª edição poderá ver que alguns exemplos podem não funcionar no Android 6.0. Na verdade se você compilar o projeto com targetSdkVersion 22 não teremos problemas, pois neste caso, o controle de permissões será feito no momento da instalação, como era antes. Mas às vezes, ao pegar os exemplos do livro, você pode alterar o código para targetSdkVersion 23 (Android 6.0), e neste caso alguns exemplos podem parar de funcionar devido ao erro de permissão SecurityException .

Para brincar um pouco, abra o projeto HelloContatos do capítulo 23 (Agenda e Contatos) dos exemplos do livro Google Android 4ª edição. Como você deve saber, este exemplo lista os contatos da agenda. Este app inclusive mostra como adicionar alguns contatos na agenda (Donald, Mickey e Pateta).

contatos

Mas agora altere o arquivo app/build.gradle para compilar o projeto com API 23.

Ao executar o projeto em um dispositivo com Android 6.0, o aplicativo vai travar, mostrando a famosa mensagem Force Close.

b

Como de costume, sempre que o aplicativo trava devemos olhar os logs no LogCat.

Neste caso o erro foi uma SecurityException (permissão negada).

Screen Shot 10-02-15 at 12.07 AM

Este erro já era esperado, então vamos corrigí-lo.

Como o projeto que lista os contatos utiliza as permissões READ_CONTACTS e WRITE_CONTACTS, precisamos pedir a permissão do usuário para utilizar a agenda de contatos.

Para facilitar a codificação, criei a classe PermissionUtils (use ela como quiser, é apenas uma sugestão). A formatação do código ficou meio zoada, então faça o download do código-fonte do arquivo aqui. PermissionUtils


&amp;amp;amp;amp;amp;amp;lt;pre&amp;amp;amp;amp;amp;amp;gt;package br.com.livroandroid.contatos;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;

import java.util.ArrayList;
import java.util.List;

/**
 * Sistemas de permissão do Android 6.0
 * &amp;amp;amp;amp;amp;amp;lt;p/&amp;amp;amp;amp;amp;amp;gt;
 * http://developer.android.com/preview/features/runtime-permissions.html
 */
public class PermissionUtils {

    /**
     * Solicita as permissões
     */
    public static boolean validate(Activity activity, int requestCode, String... permissions) {
        List&amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;gt; list = new ArrayList&amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;gt;();
        for (String permission : permissions) {
            // Valida permissão
            boolean ok = ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
            if (! ok ) {
                list.add(permission);
            }
        }
        if (list.isEmpty()) {
            // Tudo ok, retorna true
            return true;
        }

        // Lista de permissões que falta acesso.
        String[] newPermissions = new String[list.size()];
        list.toArray(newPermissions);

        // Solicita permissão
        ActivityCompat.requestPermissions(activity, newPermissions, 1);

        return false;
    }
}&amp;amp;amp;amp;amp;amp;lt;/pre&amp;amp;amp;amp;amp;amp;gt;

O método validate(…) recebe uma lista de permissões e valida se o usuário já concedeu o acesso. Caso o app ainda não tenha perguntado ao usuário, a acesso é solicitado pelo método requestPermissions(…).

Na MainActivity do projeto HelloContatos, basta adicionar estas linhas de código para validar a permissão e solicitá-la caso necessário:


// Solicita as permissões
 String[] permissoes = new String[]{
 Manifest.permission.READ_CONTACTS,
 Manifest.permission.WRITE_CONTACTS,
 };
 PermissionUtils.validate(this, 0, permissoes);

O código-fonte completo pode ser visto a seguir. Download do fonte: MainActivity

Bom, é isso :-). Se fizermos essa chamada no código vai dar boa. Ao executar o projeto no emulador do Android 6.0, vereremos o seguinte alerta solicitando a permissão do usuário para utilizar a API da agenda de contatos.

alerta

Se o usuário aceitar as permissões, tudo continuará bem e o aplicativo poderá ler os contatos.

Caso contrário, você terá que fazer algumas validações no código (if) para não utilizar as APIs que o usuário não aprovou.

Neste exemplo que fiz, caso o usuário negue a permissão, o aplicativo vai mostrar uma mensagem e sair.

nao

É isso pessoal!

Espero que este post tenha ajudado a entender um pouco sobre a nova API de permissões do Android 6.0.

Lembre-se de atualizar os seus aplicativos e validar no código se as permissões foram concedidas.

E por último, tenha atenção, pois o usuário pode revogar as permissões a qualquer momento, ou seja, ele pode alterar as configurações para permitir ou não o acesso a determinada API.

A figura abaixo mostra as configurações de um aplicativo, mostrando as opções para o usuário revogar as permissões. Portanto, lembre-se de sempre validar se a permissão foi concedida ou não antes de usar as APIs restritas, pois o usuário pode mudar as configurações a qualquer momento.

permi

Links oficiais, recomendado o estudo (leia sobre as boas práticas).

Como compilar os projetos dos livros de Android

Posted by rlecheta on setembro 25, 2015
Android, Livro Android / 9 Comments

Olá pessoal, segue dicas de como compilar os projetos baixados dos meus livros de Android, ou de qualquer outro 🙂

Depois de entrar na área de download do livro, baixe os projetos.

http://livroandroid.com.br/site/pages/downloads.php

Você verá uma pasta com vários capítulos assim:

Screen Shot 09-25-15 at 01.38 PM

Então digamos que você queira abrir o projeto de exemplo do capítulo 7.

No Android Studio, selecione o wizard > File > Open > e selecione o local do projeto.

É aqui que está o problema, e as vezes o pessoal se atrapalha para compilar o projeto.

Dependendo de suas configurações, como a versão do Android SDK e Build-Tools que você fez o download, é necessário fazer alguns ajustes no projeto.

img_150925_0144

Na janela Messages podemos ver o seguinte erro:

Error:Gradle 2.4 requires Android Gradle plugin 1.2.0 (or newer) but project is using version 1.0.1.
Please use Android Gradle plugin 1.2.0 or newer.

img_150925_0145

Para solucionar este problema abra o arquivo build.gradle que fica na raiz do Android Studio e atualize a seguinte linha para a última versão:

Qual versão deve ser? Bom, provavelmente o Android Studio vai mostrar o assistente de código e vai te ajudar. Só clique no assistente que ele deve corrigir.

classpath 'com.android.tools.build:gradle:1.3.0'

a

Outro problema frequente pode ser a versão do SDK Build-tools, que é a ferramenta utilizada para compilação do projeto. Podemos ver na figura abaixo que meu build-tools está com a versão 23.0.1.

@Obs: sempre deixe atualizado estes pacotes;

a

Isso significa que no arquivo app/build.gradle preciso colocar a versão 23.0.1 no campo buildToolsVersion. Somente assim o projeto compilará.

b

Outro ajuste que muitas vezes é necessário é configurar a API Level target do projeto.

Isso é feito nos atributos compileSdkVersion e targetSdkVersion.

Conforme mostra o print abaixo, esses atributos estão configurados com a API Level 21 (Android 5.0). Você verá que o Android Studio sinaliza em um tom de amarelo que existe uma nova versão do Android.

img_150925_0153

Como depois do livro Android 4ª edição foi lançado o Android 6.0 (API Level 23), podemos ajustar no arquivo app/build.gradle a API Level target para compilação.

Depois dos ajustes para API = 23, o resultado fica assim:

b

Outra coisa que pode acontecer, é ter sido lançada bibliotecas mais atualizadas do Android.

Isso acontece muito com as bibliotecas de compatibilidade e Google Play Services. Portanto, quando estiver lendo o livro você pode atualizá-las, caso queira.

Lá na parte das dependências, geralmente essas bibliotecas de compatibilidade seguem a nomenclatura do build-tools. Então se o build-tools está na versão 23.0.1, estas libs devem estar com a mesma versão.

Veja na figura:

c

Mas para ter certeza qual a versão da lib de compatibilidade, basta ver no SDK Manager qual versão você fez o download, lá na pasta Extras. Podemos ver que baixei a versão 23.0.1 ,e por isso no arquivo app/build.gradle a configuração é feita com a mesma numeração.

d

Não é o caso deste projeto que escolhi, mas as vezes podem ter mais libs, como a do Google Play Services.

Por exemplo, no cap 23 do livro tem o projeto de exemplo com Mapas e GPS, que usa o Google Play Services.

Ao abrir o projeto, o arquivo app/build.gradle  está assim:

Podemos ver que o Android Studio sugere que a versão da lib seja atualizada. Então basta clicar no assistente do editor, ou utilizar a tecla de atalho Ctrl+Enter para efetivar a alteração.

e

Espero que estas dicas ajudem o pessoal que está começando com Android a compilar os projetos já existentes.

Esses problemas são comuns, pois ao desenvolver o projeto você faz a compilação com a versão das libs que existem na época. Porém como as atualizações são constantes, temos estes problemas.

São coisinhas chatas do Android, mas simples de resolver e que logo agente se acostuma 🙂

Qualquer dúvida é só entrar em contato!

Brincando com Material Design

Posted by rlecheta on janeiro 16, 2015
Android, Notícias / 6 Comments

Brincando com o app dos carros e Material Design para o livro Google Android 4ª edição.

Continuo brincando, agora com a toolbar rsrs

Criando libs no Gradle com Android – Parte 3

Posted by rlecheta on janeiro 15, 2015
Android, Tutorial / 4 Comments

No terceiro e último post sobre como fazer libs com gradle e Android Studio, vamos aprender a publicar um projeto no servidor do Maven Central.

1) O que é o Maven Central?

O Maven Central é um repositório de código utilizado por diversos projetos mundialmente, e foi criado pelo pessoal da Sonatype.

Ao desenvolver um projeto Android as dependências são declaradas no arquivo build.gradle. Um exemplo disso é a declaração da biblioteca de compatibilidade v7 do Google.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
}

Mas ao declarar esta dependência de qual repositório ela é buscada?

Por padrão todas as bibliotecas são buscadas no Maven Central. Se você quiser é possível declarar o repositório mavenCentral(), mas não é preciso, pois por padrão o Gradle já o utiliza.

repositories {
    mavenCentral();
}

Então se você precisa disponibilizar uma biblioteca open-source para a comunidade você precisa disponibilizá-la no Mavel Central.

2) O site http://search.maven.org

O repositório do Maven Central está nesse link:

https://repo1.maven.org/maven2/

Mas para visualizar o conteúdo você deve buscar a biblioteca no site http://search.maven.org/.

Screenshot from 2015-01-15 14:06:37

3) Criando uma conta no JIRA da Sonatype

Chega de teoria, vamos para a parte prática. Para publicar um projeto no Maven Central você vai precisar de um login e senha que precisa ser criado no servidor Nexus da Sonatype.

Para fazer o registro é utilizado o JIRA.

1) Acesse esse link e crie uma Issue para configurar o seu projeto.

Essa Issue serve para solicitar ao pessoal do Sonatype para criar o projeto no Maven Central.

https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134

Para criar uma Issue antes você precisará fazer um cadastro e obter seu login.

Na Issue você deve descrever o seu projeto, e preencher os campos como o groupId, project URL, SCM URL (ex: URL do github), etc.

Depois de criar a Issue aguarde, pois pode levar 2 dias úteis para ela ser aprovada. Você receberá as respostas pelo próprio sistema do JIRA, basta acompanhar a issue que você criou.

4) Fazendo o deploy no Nexus da Sonatype

Uma vez que a issue com a solicitação para criar o projeto foi aprovada, você receberá um e-mail com várias informações, portanto leia tudo.

Agora estamos prontos para fazer o deploy no Maven Central, mas não podemos fazer isso diretamente. É necessário antes fazer o deploy no repositório staging do Nexus da Sonatype, pois eles vão validar se o pacote está OK antes de fazer o deploy no Maven Central.

A URL deste repositório é:

https://oss.sonatype.org/service/local/staging/deploy/maven2/

E a URL para enviar snapshots é:

https://oss.sonatype.org/content/repositories/snapshots/

Para fazer o deploy no repositório do Sonatype é preciso informar alguns parâmetros sobre o controle de versão SCM, licença do código, nome do desenvolvedor, etc, e portanto eu gosto de utilizar um script criado por Chris Banes do Google.

Segue o script que faz o deploy no Maven Central.

https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle

Para utilizar este script basta adicioná-lo na última linha do seu arquivo build.gradle.

 

apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'

task install(dependsOn: uploadArchives)

 

O script vai fazer o deploy no Repositório do Nexus da Sonatype, você só precisa informar alguns parâmetros. Para isso preencha o arquivo app/gradle.properties com as variáveis que o script precisa.

POM_NAME=LivroAndroidUtils
POM_PACKAGING=aar

VERSION_NAME=0.0.4
VERSION_CODE=1
GROUP=br.com.livroandroid
POM_ARTIFACT_ID=android-utils

POM_DESCRIPTION=Library used in the samples of Livro Android Book
POM_URL=https://github.com/rlecheta/LivroAndroidUtils
POM_SCM_URL=https://github.com/rlecheta/LivroAndroidUtils
POM_SCM_CONNECTION=scm:git@github.com:rlecheta/LivroAndroidUtils.git
POM_SCM_DEV_CONNECTION=scm:git@github.com:rlecheta/LivroAndroidUtils.git
POM_LICENCE_NAME=The Apache Software License, Version 2.0
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
POM_LICENCE_DIST=repo
POM_DEVELOPER_ID=rlecheta
POM_DEVELOPER_NAME=Ricardo Lecheta

Pronto está quase, agora você só precisa informar seu usuário e senha para fazer o deploy no Nexus da Sonatype, e também o arquivo gpg para assinar o build.

Screenshot from 2015-01-15 14:39:41

Este arquivo gradle.properties deve ser criado na pasta do usuário, portanto no meu caso o caminho é: /home/ricardo/.gradle/gradle.properties.

NEXUS_USERNAME=your_sonatype_nexus_user
NEXUS_PASSWORD=your_sonatype_nexus_password

signing.keyId=your_gpg_key
signing.password=your_gpg_password
signing.secretKeyRingFile=/home/ricardo/.gradle/your_gpg_file.gpg

Este arquivo não precisa ser colocado no controle de versão, e justamente por isso ele deve ficar na pasta do seu usuário. O gradle vai automaticamente ler esse arquivo ao fazer o build.

Note que você precisa preencher o usuário e senha do Nexus, e também precisa criar o arquivo gpg.

5) Criando o arquivo gpg para assinar o build

Para criar suas chaves abra um terminal e digite:

 gpg –gen-key

Screenshot from 2015-01-15 14:50:16

Depois execute o seguinte comando para listar suas chave:
gpg --list-keys

A primeira parte da linha da sua chave possui o padrão “pub XXXXX/YYYYYYYY <date>”.

O que você precisa é a parte YYYYYYYY, pois essa é a sua chave do arquivo gpg.

Screenshot from 2015-01-15 14:51:08

Por último você precisa enviar suas chaves para o servidor, portanto utilize o seguinte comando.

 gpg --keyserver hkp://keyserver.ubuntu.com --send-keys YYYYYYYY
 $ gpg --keyserver hkp://pgp.mit.edu --send-keys YYYYYYYY
 

6) Criando o arquivo gpg (No Windows)

Caso você utilize o Windows, você pode criar as chaves gpg utilizando o software Kleopatra (https://www.kde.org/applications/utilities/kleopatra/).

Ele é fácil de utilizar, basta ir no menu File > New Certificate. Depois de criar o certificado você pode exportá-lo para os servidores clicando na chave com o botão direito e utilizando a opção > Export Certificates to Server.

kleopatra

7) Executando o gradle install para publicar o build

Uma vez que tudo está configurado, execute o gradle install pelo Android Studio.

Lembre-se que fiz o gradle install depender do uploadArchives.

“task install(dependsOn: uploadArchives)”

Screenshot from 2015-01-15 14:54:31

Resultado.

Screenshot from 2015-01-15 14:54:42

8) Fazendo Close e Release do artefato

Depois de publicar seu artefato no Nexus, você precisa ir até o repositório staging e clicar em Close ou em Drop.

https://oss.sonatype.org/#stagingRepositories

O Drop é utilizado caso você viu que tem algo errado com um build e queira descartá-lo.

Ao fazer Close o servidor vai validar se você informou todos os parâmetros corretamente, mas se você seguiu este tutorial e utilizou o script do Chris Banes não deve ter problema.

Então selecione o seu projeto na lista e clique em Close. Depois de clicar em Close a validação vai começar, e se tudo estiver Ok, você verá na tab Activity a mensagem Repository Closed.

Screenshot from 2015-01-15 14:56:56

Depois de fechar o projeto ele está validado e pronto para ser publicado no Maven Central. Para isso selecione seu artefato e clique em Release.

Screenshot from 2015-01-15 14:57:22

Depois de alguns minutos você receberá um e-mail falando que o release foi efetuado, e agora seu projeto encontra-se disponível no repositório de release da Sonatype.

https://oss.sonatype.org/content/repositories/releases/

Mas para aparecer no site http://search.maven.org/ leva geralmente 1 dia útil.

Pronto, chegamos ao fim.

Agora que publiquei uma nova versão posso declarar a dependência no arquivo build.gradle de qualquer projeto, e pronto!

dependencies {

    . . .
    compile 'br.com.livroandroid:android-utils:0.0.4'
}

Obs: A biblioteca “br.com.livroandroid:android-utils” é simples e o objetivo é apenas auxiliar nas explicações do livro Google Android 4ª edição.

E para mostrar que a biblioteca está mesmo instalada no Maven Central, basta uma busca no site http://search.maven.org/. A biblioteca pode levar até 1 dia para aparecer ser encontrada aqui.

Screenshot from 2015-01-15 14:06:59

Atenção: Se for o seu primeiro release, você precisar entrar na Issue do Jira que você criou, e fazer um comentário indicando que você fez a release. Assim o time da Sonatype vai validar e habilitar o release automático para o Maven Central. Você só precisa fazer isso na primeira vez.

Para maiores informações, segue a documentação oficial.

Criando libs no Gradle com Android – Parte 2

Posted by rlecheta on janeiro 15, 2015
Android, Tutorial / 8 Comments

Na primeira parte do tutorial vimos como criar uma lib e fazer o deploy em uma pasta local do computador.

Mas provavelmente você precisa compartilhar suas libs com todo o seu time, portanto podemos instalar um servidor de repositório, que é o Nexus Sonatype.

Faça o download do Nexus Sonatype aqui.

Este é um servidor de Maven que atua como repositório de projetos. O legal é que ele possui o servidor web Jetty embutido, então basta um comando para subir o servidor do Sonatype.

1) Instalando o servidor Nexus

Download aqui.

Ao descompactar o Nexus você verá a seguinte pasta. No meu caso estou testando no Ubuntu.

Screenshot from 2015-01-15 09:36:09

Entre dentro da pasta do nexus até a pasta bin, e digite o seguinte comando para iniciar o servidor.

./nexus start

Screenshot from 2015-01-15 09:38:21

Por padrão o Nexus vai executar na pasta 8081, faça o teste: http://localhost:8081/nexus/

Screenshot from 2015-01-15 09:39:25

Ao clicar nos repositórios você verá a seguinte página. Para entender a estrutura de repositórios do Nexus veja a documentação oficial se precisar.

Screenshot from 2015-01-15 09:39:59

2) Fazendo deploy da lib no Nexus

Na parte 1 do tutorial fizemos o deploy em uma pasta local com a seguinte configuração.

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file:///home/ricardo/gradle/rep")

            pom.groupId = GROUP
            pom.artifactId = POM_ARTIFACT_ID
            pom.version = VERSION_NAME
        }
    }
}

Então basta substituir a URL do repositório para a URL do Nexus.

http://localhost:8081/nexus/content/repositories/releases/

O resultado fica assim:

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "http://localhost:8081/nexus/content/repositories/releases/"){
                authentication(userName: "admin", password: "admin123")
            }

            pom.groupId = GROUP
            pom.artifactId = POM_ARTIFACT_ID
            pom.version = VERSION_NAME
        }
    }
}
task install(dependsOn: uploadArchives)

Por padrão o usuário do Nexus é “admin”, senha “admin123”.

 

Feito isso execute a task install conforme fizemos na parte 1 do tutorial.
Screenshot from 2015-01-15 10:15:33
O resultado podemos ver no console do Android Studio. Eu acabei de fazer o deploy da versão 0.0.3 da lib de teste.

Screenshot from 2015-01-15 10:21:31

Depois de ter feito o deploy, abra o browser e veja o conteúdo do repositório. Você verá a pasta com o nome do pacote da sua lib.

http://localhost:8081/nexus/content/repositories/releases/

Screenshot from 2015-01-15 10:21:43

Então basta navegar dentro das pastas até chegar na lib.

Screenshot from 2015-01-15 10:21:58

3) Utilizando a lib em outro projeto

Na parte 1 do tutorial, o projeto que deseja utilizar a lib configurou o repositório para buscar a dependência assim:

repositories {
    maven {
        url "file:///home/ricardo/gradle/rep"
    }
}

Então basta alterar para buscar da URL do Nexus e pronto.

repositories {
    maven {
        url "http://localhost:8081/nexus/content/repositories/releases/"
    }
}

Aqui na Livetouch temos um servidor privado que somente os developers tem acesso, e o Nexus Sonatype ajuda muito neste controle.

Bom, é claro que no projeto você precisa declarar a dependência para a lib, então não esqueça.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'

    compile 'br.com.livroandroid:mylib:0.0.3'
}

Criando libs no Gradle com Android – Parte 1

Posted by rlecheta on janeiro 14, 2015
Android, Tutorial / 12 Comments

Parte 2

Parte 3

Se você está trabalhando com Android, provavelmente precise criar sua própria lib para usar internamente em seus projetos e empresa, ou até você gostaria de criar uma lib e disponibilizar para a comunidade utilizar.

Mas então, como criar uma lib? Como disponibilizá-la?

Nesta primeira parte do tutorial, vou criar uma lib que você fará o deploy localmente em seu computador.

O 1º passo é criar um projeto normal no Android Studio (não precisa nem de activity launcher). Eu criei um projeto chamado MyLib. Neste projeto você deve colocar suas classes utilitárias, recursos, etc. Enfim tudo o que você deseja reutilizar nos outros projetos.

No arquivo app/build.gradle você precisa indicar ao build do gradle que este projeto é uma lib, então adicione as seguintes linhas no início do arquivo.

apply plugin: 'com.android.library'
apply plugin: 'maven'

Depois você vai precisar adicionar no arquivo app/build.gradle as configurações sobre sua biblioteca e o local onde ela deve ser instalada, ou seja, o local onde fica o seu repositório. O repositório pode ser uma URL da internet (se existir um servidor), ou até mesmo uma pasta local do computador, que será o que vamos fazer agora.

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file:///home/ricardo/gradle/rep")

            pom.groupId = GROUP
            pom.artifactId = POM_ARTIFACT_ID
            pom.version = VERSION_NAME
        }
    }
}
task install(dependsOn: uploadArchives)

Nesta caso foi criada a task  uploadArchives que define o repositório onde a lib deve ser instalada.

A última linha desta configuração indica que a task install depende da task uploadArchives. Portanto se você executar a task install será feito também o upload da lib para o repositório.

Para que você não tenha dúvidas, segue o arquivo app/build.gradle completo.

Atenção: Veja que uma lib não tem as configurações do applicationId como um projeto normal. Veja o arquivo exemplo abaixo e deixe igual.


apply plugin: 'com.android.library'
apply plugin: 'maven'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 21
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

uploadArchives {
    repositories {
        mavenDeployer {
            //repository(url: "file:///C:/gradle/rep/")
            repository(url: "file:///home/ricardo/gradle/rep")

            pom.groupId = GROUP
            pom.artifactId = POM_ARTIFACT_ID
            pom.version = VERSION_NAME
        }
    }
}
task install(dependsOn: uploadArchives)

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
}

Atenção: Altere a pasta do repositório deste exemplo para uma pasta que exista em seu computador!

No arquivo app/build.gradle foi referenciado 3 propriedades importantes do build de sua lib, que é o Group, ArtifactId e Version.

pom.groupId = GROUP

pom.artifactId = POM_ARTIFACT_ID

pom.version = VERSION_NAME

Neste caso as informações podem ficar fixas no projeto, mas por questões de boas práticas são criadas estas variáveis no arquivo app/gradle.properties (se não existir crie esse arquivo).

// arquivo app/gradle.properties
POM_ARTIFACT_ID=mylib
VERSION_NAME=0.0.1
GROUP=br.com.livroandroid

O artefato id é o nome de sua lib propriamente dita, e o grupo é seu pacote. Você pode ter mais de um artefato publicado no mesmo pacote. E a versão não preciso nem explicar.

Sendo assim quando eu for utilizar essa lib em outro projeto, basta utilizar a seguinte dependência:

compile 'br.com.livroandroid:mylib:0.0.1'

Onde o formato é:

compile 'groupId:artifactId:version'

Certo mas como faço o deploy da lib?

Basicamente nesse caso posso executar a task install, pois ela depende da task uploadArchives que foi configurada no build.

Existem 3 formas simples de fazer isso:

1) Abrir um terminal no seu computador, navegar até a pasta do projeto e digitar.

gradle install

Para isso você precisa instalar o gradle no seu computador e configurá-lo no PATH para encontrar o executável. Lembre-se de instalar a versão correta que o projeto do Android Studio utiliza. Por exemplo no arquivo gradle/wrapper/gradle-wrapper.properties que está no projeto, posso ver que o Android Studio está utilizando a versão 2.2.1 do Gradle (na época deste tutorial).

// gradle/wrapper/gradle-wrapper.properties
. . .
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip

Então neste caso no meu computador eu preciso garantir que estou utilizando esta mesma versão para fazer o build.

2) Outra maneira simples de executar e que não precisa instalar o gradle no computador é utilizar o gradle que está embutido no Studio.

Para isso abra a janela > Tools > Open Terminal do Studio.

b

O resultado é a janela terminal.

terminalb

Depois digite o seguinte comando. Note que usei a notação ./ pois estou no Linux.

./gradlew install

Obs: O arquivo gradlew é gerado pelo studio e está na pasta raiz do projeto. Tenha certeza de que ao abrir o terminal você vai estar na raiz, e não dentro da pasta app.

Ao executar este comando podemos ver o seguinte resultado na janela Terminal. Veja que o arquivo foi publicado no repositório local que configurei.

terminal3

Feito isso basta você olhar no seu computador nesta pasta que a lib foi publicada.

terminal4

Sobre o formato da lib não vou explicar pois você pode dar uma procurara no Google Estou citando apenas as partes mais importantes.

3) A 3ª maneira de fazer o deploy é executar a task install visualmente pelo Android Studio.

Basta abrir a janela Gradle Tasks que fica no canto direito superior do Studio, procurar a task intsall e executar com um clique.

Feito isso bingo! A lib será publicada.

terminal5

4) Utilizando a LIB.

OK mas e agora como faço para utilizar a lib?

Neste caso como criamos um repositório local, basta configurar este repositório no seu outro projeto e declarar a dependência.

No meu caso criei outro projeto com o nome HelloLib. Para sua conferência segue o arquivo app/build.gradle deste projeto.

 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "br.com.livroandroid.hellolib"
        minSdkVersion 9
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

repositories {
    maven {
        url "file:///home/ricardo/gradle/rep"
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'

    compile 'br.com.livroandroid:mylib:0.0.1'
}

É isso aí pessoal, espero que tenham gostado do tutorial. Ainda tem as partes 2 e 3.
Parte 2

Parte 3