The Social Project: configurando o servidor de CI

Padrão

Se você ainda não conhece as motivações deste projeto, leia o primeiro artigo aqui.

No post anterior, criamos o repositório com um projeto vazio e configuramos o repositório com as branches persistentes que farão parte do nosso Git Flow.

Para essa tarefa, escolherei o CircleCI. Por quê? Primeiramente pelo seu suporte a Docker, o que facilita e muito na hora de fazer o setup do ambiente, caso a gente precise customizar o tooling. Além disso, ele possui uma cota gratuita generosa não só para projetos open-souce (que está sendo o caso deste daqui), mas também para projetos privados no Github ou Bitbucket.

Bom, primeiramente faremos o login no CircleCI com a nossa conta do Github e faremos o setup do nosso repositório.

Na tela seguinte, selecionamos uma máquina Linux e o Gradle como ferramenta de build. Nessa mesma tela, será oferecido um arquivo de configuração default, a ser colocado na pasta .circleci do repositório, com o nome de config.yml. O conteúdo inicial do arquivo é:

# Java Gradle CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-java/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/openjdk:8-jdk
      
      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/postgres:9.4

    working_directory: ~/repo

    environment:
      # Customize the JVM maximum heap limit
      JVM_OPTS: -Xmx3200m
      TERM: dumb
    
    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "build.gradle" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      - run: gradle dependencies

      - save_cache:
          paths:
            - ~/.gradle
          key: v1-dependencies-{{ checksum "build.gradle" }}
        
      # run tests!
      - run: gradle test

A partir desse modelo, faremos algumas alterações. A primeira delas é mudar a imagem do docker para uma que já contenha todo o setup para que possamos buildar apps Android – temos uma lista das imagens mantidas pelo próprio CircleCI aqui. Além disso, configuramos a versão da JDK a ser utilizada e configuramos o cache de dependências (para que não precise ser baixadas novamente, caso não haja mudança nos arquivos do Gradle). Colocamos também uma task preventiva (Accept licenses) para evitar que o processo de build quebre por conta de licenças não aceitas.

Na task de build, configuramos a execução do Lint (através da task check), a compilação e execução de testes locais (através da task build) e, por enquanto, a compilação dos testes instrumentados (através da task assembleAndroidTest) – posteriormente faremos a delegação da execução desses testes para o Firebase Test Lab.

O arquivo final fica assim:

version: 2
jobs:
  build:
    docker:
      - image: circleci/android:api-27-alpha

    working_directory: ~/social-app

    environment:
      JVM_OPTS: -Xmx3200m
      CIRCLE_JDK_VERSION: oraclejdk8

    steps:
      - checkout

      - restore_cache:
          key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}

      - run:
          name: Accept licenses
          command: yes | sdkmanager --licenses || true

      - run:
          name: Build
          command: ./gradlew clean check build assembleAndroidTest

      - save_cache:
          paths:
            - ~/.gradle
          key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}

Feito isso, também colocarei um badge no README.md do repositório, indicando o atual status da nossa build. Tudo isso será então commitado em uma branch chamada rt/setup-ci e então um pull request será aberto.

Como sou administrador, eu poderia simplesmente ignorar o fluxo e eu mesmo mergear meu Pull Request. Porém, iria quebrar o fluxo que eu mesmo estou propondo! 🙂

Para fazer o review do meu PR, adicionei a Elessandra como revisora. No caso, a pessoa que revisa o PR pode fazer apontamentos e, caso esteja tudo certo, aprovar e mergear.

Como nem tudo são flores, eu commitei o arquivo com alguns erros de digitação na primeira tentativa. Como ainda não tínhamos o CI integrado para validar o arquivo de configuração, os olhos humanos deixaram passar. Com isso, fui obrigado a fazer outro PR revertendo a modificação. Pela própria interface do Github é possível solicitar desfazer o PR.

Corrigidos os erros (e, após algumas tentativas), finalmente consegui configurar o CI corretamente.

Como foram vários commits de tentativa e erro, o PR ficou com vários commits. Para esse caso, o ideal é que se faça o Squash (juntar todos os commits em um único), evitando assim que o histórico do Git seja poluído.

Por fim, após o merge é importante excluir a branch de origem, já que ela não é uma branch persistente. Assim, mantemos o repositório limpo e organizado 🙂

Por hoje é isso. O repositório já com as modificações está disponível aqui.

The Social Project: setup do repositório

Padrão

Se você ainda não conhece as motivações deste projeto, leia o primeiro artigo aqui.

(Como o Medium está me trollando e não me deixa fazer upload de imagens, aparentemente por conta do Cloudflare, vou postar essa série por aqui).

O primeiro passo aqui é decidir onde vamos hospedar o nosso código. Essa decisão é importante, pois vai impactar em toda a suíte de code review, pull requests, etc.

Pensando em um projeto privado, gosto bastante do Gitlab, porém o Bitbucket geralmente possui mais integrações (CI, por exemplo). Como este nosso projeto será totalmente opensource, vou optar pelo Github.

O link do repositório será https://github.com/rafaeltoledo/social-app

Com o projeto criado, utilizei o wizard do Android Studio (atualmente na versão 3.0.1) e criei um template de projeto vazio. Não configurei uma Activity inicial, nem a opção de Kotlin, pois quero configurar o projeto passo a passo e organizá-lo melhor do que o template inicial.

Nesse ponto, vale salientar que não estou utilizando versões Canary pois é um projeto que deve ser publicado em produção. Quando se desenvolve profissionalmente é sempre importante levar isso em consideração. Nas máquinas que utilizo (tanto em casa quanto no trabalho), sempre mantenho a versão estável para desenvolver projetos e a versão Preview do Android Studio para fazer experimentos, verificar novas funcionalidades, etc.

Bom, feito isso, subi o projeto para o Github.

O último passo relativo ao repositório será configurarmos as nossas branches persistentes. Elas serão as branches que não aceitarão commits de forma direta e serão observadas pelo nosso (futuro) servidor de CI.

Aqui, além da branch master, vou criar a branch develop. Inicialmente, só derivei essa branch da master e subi para o repositório. A ideia é que o código que esteja na branch master corresponda ao código do aplicativo atualmente em produção (Google Play) e a branch develop o que esteja atualmente nas mãos dos stakeholders e alpha testers do projeto. Para o nosso aplicativo, a ideia é que essas builds sejam disponibilizadas no canal Alpha do Google Play para um grupo fechado de testers.

Vamos também fazer algumas configurações para essas branches, como exigir aprovação nos Pull Requests (PRs), exigir que PRs estejam sincronizados e que estejam passando nas verificações (vamos em breve integrar linters, testes e etc.)

Feito isso, vou salvar as configurações e pronto!


No próximo post pretendo configurar o CI para buildar esse projeto inicial, e plugá-lo nos checks de Pull Request do Github.

Ainda estou na busca de designers interessados em ajudar, principalmente nessa primeira fase do projeto! Se você quiser contribuir ou souber de alguém que gostaria de participar, me indique aqui nos comentários 🙂

The Social Project: implementando um projeto do zero com Kotlin e Firebase

Padrão

Fala pessoal, tudo bem?

Sempre que estudamos determinada tecnologia, ou mesmo quando trabalhamos em um projeto, nem sempre conseguimos nos aprofundar em determinados assuntos. Outro problema que quase sempre acontece, é que não temos possibilidade de aprofundar o suficiente em determinado assunto, restringindo a parte prática muitas vezes a um simples “hello world” ou uma prova de conceito.

Pensando nisso, estou começando uma série (que deve se estender por todo esse ano) em que vamos trabalhar um aplicativo do zero, utilizando duas das grandes “buzzwords” hoje quando se fala de desenvolvimento Android: Kotlin & Firebase. Não necessariamente ser uma buzzword é um problema, mas ao longo deste processo vamos descobrir não só o que é muito bom, mas também o que às vezes não funciona como o esperado e vermos que nem sempre tudo são flores.

Este projeto tem um objetivo bastante arrojado: criar uma rede social “padrão”, criando um aplicativo Android com Kotlin (incluindo ferramentas de qualidade, testes, Material Design, acessibilidade, etc.), dentro de um pipeline automatizado e organizado (Git flow, linters nos Pull Requests, releases automatizadas no Google Play, Integração Contínua), utilizando um Backend as a Service (Autenticação, Storage, Push Notifications, etc.), implementando features bem comuns para redes sociais (feed, amigos, upload de fotos, comentários, chat, etc.).

Arrojado, não?

Potencialmente (e provavelmente) eu talvez não consiga fazer tudo sozinho. Dessa forma, quem tiver vontade de contribuir, principalmente designers nesse primeiro momento, toda ajuda será bem-vinda — até para entendermos como o fluxo de design poderia entrar nesse pipeline.

Bom, por enquanto ainda não tem nada muito concreto. Aguardem os próximos posts com novidades!

Layouts e Resources – Tutorial Android 4

Padrão

Olá pessoal! No último post criamos a nossa primeira Activity, e entendemos um pouco sobre Intents! No post de hoje vamos entender um pouco mais sobre resources no Android e criar um layout para a nossa Activity. Preparados?

Para o tutorial de hoje, vamos trabalhar majoritariamente com a pasta res, que fica localizada no caminho app/src/main/res. É nela que ficam todos os recursos do seu projeto, que não são necessariamente código Java. O projeto, no momento, deve ter algumas pastas, como drawable (vazia), mipmap (em algumas versões com sufixos estranhos) e values.

Um projeto Android padrão costuma ter várias outras, que entraremos em mais detalhes a medida que forem necessárias. Essas pastas separam os tipos de recursos que temos em nosso projeto. Por exemplo, drawable, conterá qualquer tipo de coisa desenhável, desde formas, a imagens e seletores. A mipmap contém somente o ícone do aplicativo. A pasta values contém valores em gerais, desde inteiros, até strings, cores, dimensões, estilos e etc.

Se você abrir cada uma das pastas (mipmap-hdpimipmap-mdpimipmap-xhdpi, etc), você verá que temos o ícone do aplicativo em diferentes tamanhos. Isso ocorre porque os dispositivos Android possuem diversas configurações. Configuração diz respeito a tudo no dispositivo, desde idioma, até o que chamamos de densidade da tela. Uma maior densidade, quer dizer que aquele dispositivo tem mais pixels em uma menor área física. Exemplo: um dispositivo que tem uma tela de 4,7″ e uma resolução de 480×800 pixels tem uma densidade mais baixa (hdpi) do que um device que tem a mesma tela de 4,7″, porém uma resolução de 1080×1920 (xxhdpi). Exatamente por suportar uma diversidade grande de tamanhos de tela, é que no Android não trabalhamos com pixels, e sim com density pixels. Assim, um botão tende a ter sempre “mais ou menos o mesmo tamanho”, independente da resolução da tela. Para aprender mais sobre isso, dê uma olhada na documentação do Android (que agora também possui versão em português!).

E como essa mágica é feita? Não é mágica. Ao colocar um qualificador na pasta, o Android, na hora que estiver executando, conhece a configuração do dispositivo e usa o recurso específico para a sua configuração. Assim, não precisamos fazer várias condições em nosso código. É importante lembrar que podemos ter vários tipos de qualificadores ou mesmo adicionar pastas com mais de um qualificador. Veremos alguns casos em outros posts ?

Assim, resumindo, Supondo que estou em dispositivo xhdpi e preciso do resource mipmap/ic_launcher, o Android automaticamente buscará em mipmap-xhdpi/ic_launcher. Caso não exista uma versão específica para a configuração, ele busca a opção mais genérica, sem nenhum sufixo.

Bom, agora que já estamos mais familiarizados com o mecanismo de resources e pastas no Android, vamos criar uma nova pasta dentro de res, chamada layout. Essa pasta, como o próprio nome sugere, guardará arquivos que representam os layouts das nossas telas. Vamos criar um arquivo chamado activity_main.xml. A grande maioria dos resources no Android utilizam a notação de XML.

Neste arquivo, primeiramente colocaremos um container, o LinearLayout. Os containers servem para organizar os elementos na tela. No caso do LinearLayout, ele organiza os elementos alinhados, um após o outro, utilizando a orientação vertical ou horizontal. Adicionando o LinearLayout, o arquivo activity_main.xml fica assim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

</LinearLayout>

Você pode perceber que, além da orientação, também configuramos a largura (width) e a altura (height) do elemento. Para essas dimensões, podemos utilizar um valor ou as constantes match_parentwrap_contentmatch_parent indica que o elemento adotará para essa dimensão, a mesma dimensão que seu elemento pai. No caso, como o LinearLayout é o primeiro elemento da nossa hierarquia de views, ele adotará o tamanho de seu pai (algum container do Android que representa a tela). Assim, temos um LinearLayout do tamanho da tela ?

Vamos agora adicionar dois campos de texto e um botão ao nosso layout.

Os campos de entrada de texto no Android são conhecidos como EditText. Além da altura e da largura, também especificamos o id e a propriedade hint. Ids no Android são identificadores, o que nos permitirá referenciar este elemento em outros lugares (seja no XML, seja nas nossas classes Java). A notação @+id indica que estamos criando este recurso caso ele não exista. Sempre que você ver a notação @ em um XML, significa que estamos referenciando um recurso. O + indica a criação e id indica que é um resource do tipo id. Já o hint indica um texto de sugestão que será exibido quando o campo estiver vazio, indicando ao usuário o que deve ser inserido. Também estamos utilizando a notação de recurso, dessa vez referenciando um recurso do tipo string (que terá um valor correspondente dentro de res/values/strings.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:orientation="vertical">

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/name" />

    <EditText
        android:id="@+id/address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/address" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/save" />

</LinearLayout>
<!-- Arquivo strings.xml -->
<resources>
    <string name="app_name">Tutorial</string>
    <string name="save">Save</string>
    <string name="address">Address</string>
    <string name="name">Name</string>
</resources>

No caso do Button, temos atributos semelhantes, com a diferença de que utilizamos a propriedade text em vez de hint. Com a propriedade text, teremos um texto no botão.

Com o arquivo de layout criado, vamos voltar a nossa classe MainActivity e definir este arquivo de layout, vinculando-o a Activity. Para isso, vamos utilizar ainda o método onCreate() que é chamado sempre que a Activity é criada. Nele, vincularemos o nosso layout XML a Activity. Fazemos isso chamando o método setContentView(). Este método pode receber um objeto do tipo View ou uma referência a um resource de layout. Note o uso da classe R. Esta classe é gerada automaticamente a cada build do projeto, e é uma referência a todos os resources que temos no projeto, para uso no nosso código Java. Vamos também, remover os Logs que adicionamos anteriormente. O método fica assim:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Com esse XML, caso execute o aplicativo, nossa tela fica com o seguinte layout:

Para uma experiência mais agradável, poderíamos centralizar os elementos verticalmente. Para isso, podemos adicionar a propriedade gravity com o valor center_vertical. Essa propriedade indica como os filhos do container vão se comportar, conforme forem adicionados. Assim, temos a tela final:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:orientation="vertical">

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/name" />

    <EditText
        android:id="@+id/address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/address" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/save" />

</LinearLayout>

E é isso pessoal! No próximo post veremos o mecanismo de binding de views e callbacks no Android! Caso deseje baixar o projeto que desenvolvemos até agora, você pode encontrar no Github.

Até o próximo post!

Entendendo a Activities e Intents – Tutorial Android 3

Padrão

Olá pessoal! Dando prosseguimento a nossa série de tutoriais, hoje vamos criar a nossa primeira Activity, entender o que ela é e como funciona, além de uma noção geral sobre Intents! Vamos lá?

No último post criamos um projeto no famoso estilo Hello World. Para este, vamos criar um projeto que será evoluído ao longo de toda a série. Para isso, crie um novo projeto seguindo o tutorial anterior, com a diferença de que, em vez de selecionar Empty Activity, selecione a opção Add No Activity. Assim, podemos controlar melhor o que é criado e entender o que está acontecendo.

Algumas configurações iniciais serão realizadas e um modelo básico de projeto será criado. A princípio não se preocupe, vamos focar nos pontos um a um ao longo desta série. Assim que o projeto é criado, você verá à esquerda da IDE, na árvore do projeto, as opções appGradle Scripts. Isso ocorre porque estamos utilizando a visão Android, que agrupa muitas coisas e mostra os arquivos de uma forma mais significativa para Android. Ok, um pouco de mágica e esses “açúcares” são bons, mas no início, quando estamos entendendo o que de fato está acontecendo, é melhor ver as coisas na sua forma mais crua, para que a mágica deixe de ser mágica. Sempre que tiver algo “mágico”, vamos trabalhar pra entender como a mágica é feita. Quebra um pouco o encanto, mas te possibilita de fazer suas próprias mágicas depois ?

Vamos então mudar a visão de Android para Project, que exibirá a estrutura real de pastas do projeto.

Vamos navegar então até a pasta java, no caminho app/src/main/java. O caminho para a pasta tem este formato devido a estrutura de um projeto Gradle. O Gradle uma ferramenta bastante popular que nos ajuda a gerenciar todo o ciclo de build do projeto, incluindo suas dependências e a orquestração das ferramentas de compilação e tooling em geral. Em um momento oportuno analisaremos o Gradle mais a fundo. Nesta pasta você pode ver, por enquanto, apenas a declaração do pacote do aplicativo. Vamos criar então, a nossa primeira Activity. Clique com o botão direito sobre o pacote (no meu caso, net.rafaeltoledo.tutorial) e selecionar a opção New -> Java Class e nomear a classe a ser criada de MainActivity.

Activities no Android são a representação de uma tela. É através dela que conteúdo das telas é exibido e as interações de interface são executadas. Dentre os principais componentes do Android, é o que corresponde a UI dos aplicativos.

Para que esta classe se torne uma Activity, ela deve estender da classe Activity do Android. Porém, para o nosso caso, vamos fazer a nossa classe estender AppCompatActivity. Por quê? A AppCompatActivity é uma versão da Activity que garante um comportamento uniforme a partir da versão 7 (2.1) do Android. Essa classe faz parte das bibliotecas de suporte, que conheceremos e entenderemos mais a fundo em um post futuro.

Para que a nossa Activity esteja disponível no launcher do dispositivo, na forma de um ícone na lista de aplicativos, precisamos configurar o nosso Android Manifest. O Android Manifest é um arquivo que corresponde a uma espécie de índice do nosso aplicativo. Nele é que serão descritas, dentre outras informações, quais Activities nosso aplicativo possui e quais permissões ele necessita para ser executado.

No caso, como não selecionamos a criação automática da Activity quando criamos o projeto, temos apenas a descrição básica do nosso aplicativo no arquivo AndroidManifest.xml, localizado na pasta app/src/main (podem haver pequenas diferenças, dependendo da versão do Android Studio que você estiver usando):

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.rafaeltoledo.tutorial">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    </application>

</manifest>

Basicamente, temos aqui duas informações importantes:

  • A declaração do nó principal manifest com o atributo package. Esse atributo é importante, pois ele indica em qual pacote Java está a classe R. Esta classe, gerada automaticamente a cada compilação, é um índice com todos os recursos do nosso aplicativo que não são código Java. Veremos recursos muito em breve.
  • A declaração do nó application, que configura e descreve o nosso aplicativo. Dentre as informações principais, temos aqui o ícone, o label (que será o nome do aplicativo no launcher do sistema) e o tema.

Para adicionarmos a nossa Activity, vamos adicionar um novo nó dentro do nó application, dessa forma:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.rafaeltoledo.tutorial">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

Neste nó, estamos adicionando uma Activity com o nome .MainActivity. Este caminho pode ser absoluto (net.rafaeltoledo.tutorial.MainActivity) ou, como é o caso, relativo ao package que temos na raiz do manifesto. Perceba que temos também uma configuração dentro do nó activity, chamada de intent-filter.

O Android possui um mecanismo de troca de mensagens conhecido como Intents. Uma intent indica a intenção de se fazer alguma coisa, seja enviar uma mensagem para um componente, seja iniciar um componente. Essa intent pode conter diversas informações, como o destinatário, uma ação (action), uma categoria (category) e outras várias informações extras.

Lembra que quase todo aplicação que a gente escreve em qualquer linguagem sempre começa com um método main()? A ideia é parecida aqui: quando o ícone do aplicativo no launcher é tocado, é disparada uma Intent para a Activity configurada, com a categoria android.intent.category.LAUNCHER e a ação android.intent.action.MAIN, indicando que o aplicativo deve foi iniciado a partir do launcher do sistema. Existem, inclusive, aplicativos que possuem mais de um ícone na lista de apps do launcher.

Para vermos isso acontecendo na prática, vamos ver esse Intent chegando para a nossa Activity. Para isso, vamos sobrescrever o método onCreate() da nossa Activity MainActivity. Como estendemos de AppCompatActivity, herdamos vários métodos que nos permitem fazer diversas coisas no Android. O método onCreate() é um dos callbacks do ciclo de vida de uma Activity. Como você pode perceber, não chamamos o construtor da Activity diretamente, quem faz esse gerenciamento é o próprio Android. Então, somos apenas notificados quando cada coisa acontece. Você pode ver o ciclo de vida da Activity completo aqui, mas não se preocupe muito com isso por enquanto. Cada um desses estados vai fazer sentido mais adiante 🙂

No método onCreate(), vamos então pegar as informações que vieram da Intent que dispararam a nossa Activity. Para isso, vamos escrever no log do Android (conhecido como LogCat) algumas informações da Intent, como a ação, a categoria e o componente que foi lançado. O código fica assim:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        Log.d("MA::Action", intent.getAction());
        for (String category : intent.getCategories()) {
            Log.d("MA::Category", category);
        }
        Log.d("MA::Component", intent.getComponent().getClassName());
    }
}

Repare que, para exibir informação no Logcat, em vez do padrão System.out do Java, utilizamos a classe Log do Android. Com essa classe, temos melhores mecanismos para controlar o nível do log (error, warning, debug, etc) e podemos adicionar uma tag (primeiro parâmetro) para que fique mais fácil de encontrarmos o que queremos 🙂

Agora, se você executar o aplicativo e clicar na aba Android Monitor (na parte inferior do Android Studio), poderá conferir o log do seu aplicativo, exibindo as informações da Intent:

Bom, por hoje é só isso pessoal! No próximo post vamos entender melhor os resources do Android e criar nosso primeiro layout para a MainActivity!

Ah, sim, o projeto completo desenvolvido até aqui pode ser encontrado no Github! 🙂

Criando um Novo Projeto e Criando um Emulador no Android Studio – Tutorial Android 2

Padrão

Olá pessoal! No último post sobre Android, vimos como configurar o ambiente para programarmos, utilizando o Android Studio. Neste post, vamos ver como criar um projeto no famoso estilo Hello World, e um dispositivo virtual para a executarmos o aplicativo. Assim, você não precisa necessariamente de um celular com Android para começar a desenvolver para a plataforma, apesar de ser bastante recomendado 🙂

Ao abrir o Android Studio, vamos selecionar a opção Start a new Android Studio project. O guia que será aberto em seguida, nos auxiliará a criar um projeto sem muito esforço. Logo na primeira tela, vamos informar alguns dados básicos, como o nome do aplicativo (que utilizaremos Hello World) e o Company Domain, que nada mais é que um domínio que você tenha. Isso ajudará a criar um identificador único para seu aplicativo. No meu caso, vou colocar rafaeltoledo.net, mas você pode, por exemplo, utilizar seu nome no Github e criar o seu próprio domínio (por exemplo, rafaeltoledo.github.io). Para este projeto, não selecionaremos o suporte a C++. Vamos guardar isso para um tutorial mais avançado 🙂

Na tela seguinte, vamos configurar os módulos que nosso projeto terá, além das versões suportadas do Android. No momento que escrevo este tutorial, a minha recomendação é utilizar a API 16 como Minimum SDK. Assim, nosso aplicativo executará em mais de 97% dos dispositivos Android atualmente ativos. Você pode acompanhar a evolução das versões neste site, atualizado mensalmente.

Neste primeiro momento, vamos selecionar apenas a opção Phone and Tablet. Também vamos deixar os outros módulos, como Wear, TV e Auto para outras oportunidades e tutoriais futuros.

Na tela seguinte, vamos selecionar a opção Basic Activity. Você perceberá que muita coisa será gerada e criada, mas não se preocupe, vamos entender o que é cada coisa ao seu tempo. Avance utilizando a opção Next.

Por fim, vamos manter o nome da Activity como MainActivity, deixando as opções padrão como estão. Clique em Finish para finalizarmos o wizard.

Aguarde alguns momentos até que as dependências do projeto sejam iniciadas e a primeira compilação seja realizada.

Para executarmos este projeto, vamos criar um emulador, conhecido como AVD (Android Virtual Device). Para isso, clique no botão AVD Manager na barra de ferramentas do Android Studio.

Na janela que aparecer, selecione a opção Create Virtual Device…, que iniciará o wizard para a criação de um novo emulador.

Na tela seguinte, será exibida uma série de modelos de celular e tablet, que servirá como base para o nosso emulador. Escolha qualquer um que desejar, como por exemplo o Nexus 5. Clique em Next para avançar.

Na tela seguinte, escolheremos a imagem que utilizaremos em nosso dispositivo. A imagem contém o sistema operacional em si. A minha recomendação é escolher uma versão mais recente, e, caso seu processador e sistema operacional seja 64 bits (provavelmente é), escolha a opção x86_64 e com as APIs do Google (with Google APIs). Para este caso, estou selecionando a versão 7.1.1. Caso a imagem ainda não tenha sido baixada, clique na opção Download.

Na última tela, temos algumas opções do dispositivo, como câmera, memória e armazenamento. Por enquanto, mantenha as opções padrão e finalize.

Feche a janela do AVD Manager e clique para executar o projeto, no botão com o formato de um play na barra de ferramentas do Android Studio.

Feito isso, aguarde alguns instantes até que o emulador seja carregado e o aplicativo compilado, e então você verá seu primeiro aplicativo Android sendo executado! 🙂

E é isso pessoal! No próximo post vamos entender melhor a estrutura de um projeto Android e começar, de fato, a colocar a mão na massa! Até lá!