domingo, 27 de maio de 2012

Problemas e mais problemas...


Entreguei a versão 1.1.1 da aplicação e decidi iniciar um refactoring e uma limpeza de código para seguir para as próximas etapas. Adicionei também um comportamento de deslizar para baixo para trazer o calendário na página do dia, e uma animação da transição. Então, ao realizar um teste de integridade com o que eu havia feito, um problema sério apareceu.

O problema ocorreu quando eu mudei a versão o apk. O dialog que eu uso para definir as Metas de Pontos aparecia assim no APK 7:


e ficou desse jeito depois de trocar para o APK 13:



E isso já estava publicado em produção faz um dia. É claro que eu deveria ter testado isso, e é claro que esse comportamento não mudaria, não é mesmo? Nunca lance nada com pressa, é nesse momento que os grandes bugs nascem!

O que aconteceu não foi bem um bug da APK 13, muito pelo contrário. Eu já estava definindo a largura e altura do dialog usando o método dialog.getWindow().setLayout(200,300). O que ocorre é que estas dimensões simplesmente não eram respeitadas no APK 7. Qualquer valor que eu colocasse, a Dialog apareceria da mesma forma! Em algum momento entre a APK 7 e a 13, isso foi corrigido, e as dimensões começaram a ser respeitadas. E a lei de Murphy, por sua vez, fez com que as dimensões que eu estava utilizando fossem muito pequenas, truncando o Dialog. Isso só foi aparecer na versão corrigida da APK!

Depois de descobrir que o problema foi esse, tive de ajustar o tamnho do Dialog. Isso levou a outro problema, pois os botões de + e - ficaram descentralizados no Dialog mais largo. Aparentemente, as imagens estavam descentralizadas de forma imperceptível na imagem original, e com o aumento largura do botão, isso foi exacerbado. Tive no final de trocar as imagens por outras.

Lancei a versão 1.1.5 no market:
- Adição do gesto de deslizar para baixo para pular da listagem do dia para o calendário.
- Adição de animação ao se mudar da listagem do dia para o calendário.
- Refactoring das classes do projeto. Estou separando o comportamento dos gestos e dos intents em classes estanques, para depois ter comportamentos diferenciados quando adicionar os fragments.
- Correção do erro de layout dos Dialogs de definição de Metas de Pontos.
- Correção do erro de refresh das Metas de Pontos do dia.

Problemas de Compatibilidade e Versão

Já tenho uma base de mais de 100 pessoas que baixaram o aplicativo!

A atualização com as propagandas estava demorando demais a entrar. Resolvi checar no google play, e havia um problema de compatibilidade. A versão 1.1 estava desabilitada, e quando eu tentava habilitar, tinha esse retorno do Google Play:
Erro: os APKs compatíveis com níveis maiores de API devem ter códigos de versão superiores aos dos APKs compatíveis com níveis mais baixos de API.


O que aconteceu foi o seguinte: Quando eu coloquei as informações de versão mínima e máxima de APK no manifest, eu adicionei a seguinte entrada no xml, conforme indicado pelo AdMob:

    <uses-sdk android:minSdkVersion="8"
              android:maxSdkVersion="13"
              android:targetSdkVersion="13"/>

Mas eu não havia definido o maxSdkVersion na versão 1.1! O que resultou que a versão 1.0 tinha o APK máximo 16+ (ou seja, o máximo), e a 1.1 tinha o APK máximo 13. Isso não é aceitado pelo Google Play.

Resolvi alterar o apk, colocando o 4.0.3 (porque não?), e mudei o xml para:


    <uses-sdk android:minSdkVersion="8"
              android:targetSdkVersion="13"/>


E lancei uma versão 1.1.1, enviando o APK para o Google Play. Desta vez, funcionou sem problemas (tive de desativar a versão 1.1 - que já não estava funcionando mesmo).

Vamos ver agora o que acontece.

Semana que vem, começarei a trabalhar na versão 1.2. Vou melhorar o layout da aplicação e a usabilidade.

quarta-feira, 23 de maio de 2012

Consegui adicionar o admob no meu aplicativo. Foi relativamente simples.

- Mudei o meu sdk android para o 3.1 (estava compilando antes com o 2.1), ajustando o target de compilação para o SDK 13 (3.1). Demorei um pouco para me achar no IntelliJ (cada IDE tem as suas peculiaridades).

- Adicionei o jar do Admob, que me foi passado pelo site no classpath do projeto.

- Fiz as alterações indicadas no AndroidManifest, adicionando as permissões de acesso a INTERNET e ACCESS_NETWORK_STATE, e o mapeamento para a activity especial do AdMob.

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <activity android:name="com.google.ads.AdActivity"                  android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
Alterei também as informações do uses-sdk:
    <uses-sdk android:minSdkVersion="8"
              android:maxSdkVersion="13"
              android:targetSdkVersion="13"/>

- Depois, foi uma questão de adicionar a View do Admob nas minhas telas, passando a informação do meu id de publisher do admob (espero ter pego o id correto no site, esta parte não está muito explicada). Encapsulei isto tudo em uma método estático em uma classe nova, AdicionaPropaganda, para evitar repetição de código (prática semelhante que eu tenho feito para os outros pop-ups que utilizo, e que facilitou a minha vida):

public class AdicionaPropaganda {
    public static String MY_AD_UNIT_ID="...";
    public static void adicioneAdView(Activity activity, LinearLayout paginaDestino){
        AdView adView = new AdView(activity, AdSize.BANNER, MY_AD_UNIT_ID);
        paginaDestino.addView(adView);
        adView.loadAd(new AdRequest());
    }
}

- Então, foi só adicionar a chamada logo depois do build do layout, nas duas activities do meu projeto, como no exemplo abaixo:

        setContentView(R.layout.pagina_dia);
        AdicionaPropaganda.adicioneAdView(this, paginaDia);

Quem já conhece um pouco de android pode achar que eu pulei alguma linha entre o setContentView e o uso de paginaDia. Na verdade, o conteúdo de paginaDia é injetado pelo RoboGuice implicitamente depois do setContentView, conforme indicado no  InjectView que eu declarei juntamente com as outras declarações de classe:

    @InjectView(R.id.pagina_layout_dia) LinearLayout paginaDia;

Falo mais sobre o RoboGuice depois, mas ele realmente diminui muito o boilerplate do código!

- Regerei o pacote apk assinado, e o enviei para o market. O próximo update adicionará a propaganda e fará os centavos jorrarem em minha conta! Ou assim espero...


Conclusões: Infelizmente, o admob não funciona no android sdk 7 (2.1), o que fez o sdk mínimo do projeto subir para 8 (2.2). Queria ter sido avisado disso antes! Em último caso, espero que o market seja esperto o suficiente para não forçar este update para aqueles que possuem APIs inferiores a minSDKVersion declarada no manifest.

terça-feira, 22 de maio de 2012

Caderno Vigilantes


Publiquei hoje a minha primeira aplicação no Android Market, o Caderno Vigilantes, uma ferramenta de anotação para pessoas que controlam pontos em dietas como a Vigilantes do peso. Estou oficialmente no mundo dos fornecedores! 

Colocarei novas mensagens detalhando o processo de criação da aplicação e as minhas experiências ao tentar colocar a propaganda e monetizar a aplicação (já me inscrevi na admob, mas aparentemente, eu preciso da página da aplicação antes de me registrar). Também manterei aqui o histórico das atualizações.

Até agora, a aplicação não apareceu no Google Play. Postarei mais quando as coisas acontecerem.