Onde está meu carro - Web App e PhoneGap App

O código fonte para este exemplo pode ser encontrado em: https://github.com/gomobile/sample-where-is-my-car.

Uma característica única na aplicação Onde está meu carro é que ela usa um único código fonte que pode ser distribuído tanto como uma aplicação web tradicional quanto como um app para dispositivos embarcada com a API Apache Cordova*  (versões anteriores são conhecidas como API PhoneGap*) o que irá permitir que ela seja executada como uma aplicação nativa de primeira classe.

Funcionalmente, a app é muito simples. Imediatamente após estacionar o seu caro, você pede ao app para se lembrar da sua localização atual (onde o seu carro está estacionado).

Depois, quando você tiver terminado o que tem para fazer e precisar encontrar seu carro, a app pode ser aberta novamente para buscar a última localização que ela armazenou.

Os Arquivos

Antes de mergulhar nos detalhes deste app, dê uma olhada em seus arquivos. Existem dois que vão se comportar de forma não usual: phonegap.js e fauxgap.js.

O arquivo phonegap.js incluído no projeto é um arquivo stub. Ele garante que o evento deviceready seja chamado quando o app for entregue como uma aplicação web, bem como quando for distribuído como um app híbrido, um app Apache Cordova* (PhoneGap). Você pode usar este arquivo stub  phonegap.js em outros projetos para te ajudar a unificar tratamento de eventos de ready entre distribuições como web app ou app híbrido. Não existem problemas em incluír ele nos projetos que você empacota usando as ferramentas do Intel® HTML5 Development Environment; quando você envia a sua aplicação para que seja feito o build ela usando o serviço Adobe* PhoneGap Build* qualquer arquivo phonegap.js incluído no projeto é sobrescrito pelo serviço de build. Entretanto, se você optar por fazer o build da sua aplicação híbrida usando as bibliotecas do PhoneGap e as ferramentas do SDK da plataforma alvo, você vai precisar substituir este arquivo stub pelo arquivo phonegap.js apropriado.

O arquivo fauxgap.js é outro arquivo stub. Ele provê uma implementação dummy de toda a API Apache Cordova*. Dependendo do que você estiver fazendo, você pode achar este arquivo útil ou não. Se você quiser utiliza-lo, modifique a declaração do seu <script src="phonegap.js"></script> para apontar para o fauxgap.js. Ele não irá conflitar com o Emulador Ripple. Entretanto, ele não deve absolutamente ser empacotado quando você fizer o build de sua aplicação. Por isso, lembre-se de substituir a linha que inclui o fauxgap.js se você decidir utiliza-lo.

As Técnicas

Este projeto de exemplo utiliza diversas técnicas diferentes que você pode utilizar para o desenvolvimento de sua própria aplicação.

As Páginas

Existem duas páginas na interface gráfica: a página inicial e a página de busca. Estas páginas são implementadas simplesmente como blocos div diferentes dentro do mesmo documento HTML. Um div tem sua propriedade CSS display setada para none. Uma função JavaScript toggle_pages é usada para garantir que somente um dos divs esteja visível em um determinado momento.

O HTML:

<body>
  <div id="startpage">
   ...
   </div>
   <div id="findpage">
   ...
  </div>
</body>

O CSS:

#findpage{ display:none; }

O JAVASCRIPT:

function toggle_panes(show_find)
{
    var page = byId("startpage");
    page.style.display = show_find ? "none" : "block";
    page = byId("findpage");
    page.style.display = show_find ? "block" : "none";
}

Os Estilos

Os botões e o cabeçalho utilizam gradientes CSS3 para obter seus efeitos. Eles foram intencionalmente modelados para se parecerem com controles do Apple iOS*. Você vai encontrar os estilos para as classes básicas CSS .header e .button no arquivo ios_styles.css, dentro do diretório css do projeto.

O Layout

Este app utiliza intencionalmente um layout muito simples. Quase todos os elementos são simplesmente inseridos dentro do HTML depois de seu vizinho, com no width setado no seu estilo de CSS. Isso colocará todos os elementos de bloco dentro de uma coluna vertical. (Elementos de bloco são o <div> e <p>; enquanto os elementos em linha, como <span> e <label>, irão fazer o wrap). Isto também tem o efeito de que os elementos possuem uma largura de viewport de navegador completo, independente do navegador em que eles estarão presentes, ou da orientação da visualização apresentada no dispositivo móvel (retrato ou paisagem).

As exceções desta regra são o botão voltar e os ícones do carro e do usuário. Regras de estilos de margem são utilizadas para espaçar os elementos, e o padding é usado quando sua caixa de borda padrão precisa ser extendida um pouco para fora do elemento. Por último, margens com 0px são aplicadas nas tags <html> e <body> no CSS, para que não exista um intervalo entre o cabeçalho e a borda do viewport.

Metadados

Como a página contém suporte a layout líquido (ex. ela se ajusta a qualquer largura de viewport), o meta identificador de viewport é simples. Não é necessário se determinar uma largura inicial específica.

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />

Para mais informações sobre os metadados de viewport meta, veja https://developer.mozilla.org/en-US/docs/Mobile/Viewport_meta_tag.

Adicionalmente, se você está planejando que seu app web possa ser adicionado à tela principal de um iPhone* da Apple, existem valores adicionais de metadados que você pode configurar para avisar ao navegador móvel Safari da Apple se a página deve ser vista em tela cheia e sobre qual é o ícone que deve ser colocado na tela principal. O trecho de código a seguir provê esta informação. Mais informações sobre esta técnica pode ser encontrada no Site de desenvolvedores da Apple.

<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<!-- ícone e tela inicial -->
<link rel="apple-touch-icon" href="images/small-car-icon.png"/>

A Inicialização

Uma web app tipicamente possui rotinas de inicialização que devem ser disparadas quando o DOM é carregado. Isto é comumente feito usando o método (document).ready( ... ) do jQuery, ou com alguma coisa como <body onload="....">. Porém, se sua aplicação usa qualquer API do Apache Cordova* (Phonegap), então os eventos de carga do DOM serão disparados muito cedo. As APIs do Cordova só podem ser chamadas depois que o evento ondeviceready for disparado. Porém, o deviceready só é disparado se sua aplicação tiver sido compilada pelo PhoneGap Build (ou por um serviço similar); e ele inclusive nunca dispara em uma aplicação web tradicional, mesmo quando estiver sendo visualizada em um navegador móvel.

Isto significa que se você quiser escrever um app que pode ser tanto uma aplicação web quanto um app compilado pelo PhoneGap Build, você precisa negociar duas estratégias diferentes de inicialização (dois eventos ready competindo entre si). A melhor solução que encontramos até o momento, é usando um arquivo  phonegap.js dummy. Este arquivo está incluído neste projeto de exemplo.

Este arquivo dummy phonegap.js garante que o deviceready seja sempre chamado. Ele será chamado quando o DOM carregar para uma aplicação web tradicional, ou será chamado pelo Cordova quando a função device ready tiver sido completada.

Por isso, dentro da sua aplicação web, você sua o arquivo dummy phonegap.js e aguarda pelo evento deviceready ao invés de $(document).ready(...) ou outro ponto de entrada típico.

/* Para manter as coisas simples, nós queremos exatamente uma rotina de inicialização.
* nosso phonegap.js fake que estamos usando neste projeto irá disparar 
* o evento PhoneGap deviceready quando a página carregar.
*/
function onDeviceReady()
{
  .... // o código de inicialização vai aqui
}
document.addEventListener("deviceready", onDeviceReady, false);

Cordova ou Web App

Se você quiser lançar sua aplicação tanto como uma aplicação Cordova e uma aplicação web HTML5 tradicional, existirão momentos em que será necessário resolver a ambiguidade do ambiente de execução. Em outras palavras, você vai precisar responder a questão: o código está sendo executado com o Cordova em um dispositivo móvel ou em um navegador ?

A maneira mais simples de detectar isso é simplesmente olhar para a variável global device. Quando o Cordova estiver presente, window.device será inicializado e device será uma variável global utilizável.  Por exemplo:

// É o PhoneGap ou uma Web App ? 
if(typeof device !== "undefined")
{
   // PHONEGAP/CORDOVA ESTÁ PRESENTE
}
else
{
  //WEB APP. PHONEGAP/CORDOVA NÃO ESTÁ PRESENTE.
}

Dispositivos Testados:

  • Apple iPhone* OS 4.2.1
  • Apple iPad* 2, OS 5.1.1
  • Samsung Galaxy Player* 5.0,
Para obter informações mais completas sobre otimizações do compilador, consulte nosso aviso de otimização.