Antigamente a gente observou a mesma tela de relógio analógico durante às décadas. Mas agora já é outra coisa. Logo após de abrir a caixa do seu primeiro relógio de Android, se vai testar cada tela de relógio com esperança de achar “sua favorita”. Uma vai ter informação sobre previsão de tempo, outra sobre distância passada ou vai ter uma imagem bonita… E se não vai conseguir o que precisa, pode desenvolver a sua própria e exibir qualquer informação de previsão de tempo, curso de moedas ou contador de dias até aniversário do seu gato. Hoje nós vamos te ajudar realizar isso!
Esse tipo de aplicativo podemos desenvolver, por exemplo, por meios de Eclipse ou Android Studio. Meu preferido é segundo porque essa ferramenta já tem padrões e exemplos prontos, além disso, o Google recomenda e apoia ela. Pode desenvolver aplicativo só para o relógio mas pode aquilo que vai transferir informação para smartfone. Neste caso na final das contas, conseguirmos um arquivo APK para smartfone que dentro vai ter outro APK. Extração vai ocorrer automaticamente na primeira instalação.
Arquitetura de relógio
A cara do relógio (WatchFace) que fica na tela principal é um serviço (herdeiro de CanvasWatchFaceService) que no momento certo desenha tela.
A lista de estilos disponíveis pode observar mesmo no relógio e também na smartfone conectado através de aplicativo Android Wear.
Para notificar sistema sobre estado de relógio, você tem que descrever serviço no manifest do aplicativo. Programando você precisa levar a conta as caracteristicas de tela (redondo ou retangular).
Um exemplo de descrição de serviço no manifest:
<service android:name=".BatteryWatchFace" android:label="@string/my_digital_name" android:permission="android.permission.BIND_WALLPAPER" > <meta-data android:name="android.service.wallpaper" android:resource="@xml/watch_face" /> <meta-data android:name="com.google.android.wearable.watchface.preview" android:resource="@drawable/preview_digital" /> <meta-data android:name="com.google.android.wearable.watchface.preview_circular" android:resource="@drawable/preview_digital_circular" /> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService" /> <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" /> </intent-filter> </service>
A tela de relógio pode ser com configurações e sem.
Para configurar indicador de relógio você tem que criar uma classe separada Activity e descrever no manifest do aplicativo. Configurações podem ser chamadas pelo relógio ou criar uma classe de configurações para smartfone.
A descrição das configurações é disponível aqui e aqui.
Troca de dados
Para troca de dados foi usada uma camada especial de dados (Wearable Data Layer). Tecnicamente a troca ocorre via Bluetooth 4.0 e WiFi.
Para poder operar dessa maneira, o smartfone tem que ter o sistema operacional não inferior do que o Android 4.3 (API nível 18).
A troca de dados pode ser implementada através de três métodos:
- Itens de dados. Um objeto comum estado do quê é automaticamente sincronizado entre aparelhos.
- Mensagem enviadas entre si.
- O recurso. Um objeto grande para o envio de dados binários (por exemplo, uma imagem), que está anexado a um objeto do tipo Data Items.
Considere a troca de mensagens entre dispositivos com mais detalhes.
Para ouvir os eventos foi usado o SpecialableListenerService.
Deve ser descrito no manifesto:
<service android:name=".ListenerService"> <intent-filter> <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> </intent-filter> </service>
O serviço vai receber mensagens e processar elas através de método onMessageReceived.
Exemplo:
@Override public void onMessageReceived(MessageEvent messageEvent) { if (messageEvent.getPath().equals(WEAR_MESSAGE_PATH)) { final String message = new String(messageEvent.getData()); if (message.equals("get_level")) { WatchFace.sendMessage(this, getBatteryLevel(this)); return; } // Transmitir mensagem para atividade portável para exibição Intent messageIntent = new Intent(); messageIntent.setAction(Intent.ACTION_SEND); messageIntent.putExtra("message", message); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } else { super.onMessageReceived(messageEvent); } }
Para enviar mensagens, primeiramente, você tem que para camada de dados.
Conexão à camada:
googleClient = new GoogleApiClient.Builder(this) .addApi(Wearable.API) .build(); googleClient.connect();
Então, no um segmento separado da interface do usuário pode enviar uma mensagem.
Enviando mensagem:
if (googleClient.isConnected()) { new Thread(new Runnable() { @Override public void run() { NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await(); for (Node node : nodes.getNodes()) { Wearable.MessageApi.sendMessage(googleClient, node.getId(), WEAR_MESSAGE_PATH, param1.getBytes()).await(); } } }).start();
Apresentando data
Para criar seu próprio indicador é suficiente usar um designer de projetos de padrão em Android Studio. E depois disso você já pode modificar em acordo com suas necessidades. Um projeto pronto de indicador que apresenta o tempo e nível de carga do aparelho, eu compartilhei com vocês no site github.
A base do indicador é classe CanvasWatchFaceService.
Neste método onCreateEngine vai ser criada sua própria instância da classe Engine (o sucessor para CanvasWatchFaceService.Engine).
Em seguida, vai iniciar um temporizador cíclico que vai atualizar os valores de tempo.
O método de exibição de informação na tela é implementado no onDraw(Canvas canvas, Rect bounds). Aqui nós determinamos paletas e definimos seus limites. Processando daqui, vamos determinar se nosso indicador é redondo ou retangular. É necessário desenhar tudo que a gente quer (texto, imagens e primitivos gráficos).
Um trabalho simelhante a gente já fez quando usou ferramentas de padrão para desenhar o jogo Xonix numa aula anterior.
Deve ser anotado que o relógio tem dois estados: ativo e simplificado. Isso é realizado para economizar energia, assim, neste modo não vamos desenhar elementos. Para detectar estes parâmetros há evento onAmbientModeChanged(boolean inAmbientMode) onde um parâmetro de entrada é um marcador lógico inAmbientMode.
Arquitetura de projeto
Finalmente conseguimos o projeto de dois módulos: um é para smartfone e outro para o relógio. O módulo de smartfone vai controlar um serviço que vai receber e enviar mensagens sobre nível de carga da bateria. Neste módulo você pode implementar qualquer funcionalidade de maneira segura, como por exemplo baixar da internet a previsão de tempo e enviar para relógio. No módulo de relógio a gente vai ter dois serviços: um para as mensagens e outro para indicador.