A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Curso de Android Fevereiro de 2011 Cristiano Expedito Ribeiro

Apresentações semelhantes


Apresentação em tema: "Curso de Android Fevereiro de 2011 Cristiano Expedito Ribeiro"— Transcrição da apresentação:

1 Curso de Android Fevereiro de 2011 Cristiano Expedito Ribeiro
Fabrício Firmino de Faria

2 Agenda das próximas aulas [excluir]
Intent filter BroadcastReceiver, Threads, Services e Notification AlarmManager e Handler Banco de Dados e ContentProvider Mapas e GPS Sockets e Web Services Projeto

3 Agenda da Aula 2 Intent filter Aplicações em segundo plano Handler
BroadcastReceiver Threads e Services Notification AlarmManager Handler Persistência Arquivos e preferências Banco de Dados SQLite ContentProvider Mapas e GPS

4 Intent Filter Criação de filtros que determinam quais Intents devem ser executadas para cada mensagem <activity android:name=".HelloActivity" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> Action = MAIN Diz que activity é um ponto de partida, semelhante ao public static void main() da Java Category = LAUNCHER Indica que o ícone da activity deverá aparecer na tela pode ser aberta pelo usuário

5 IntentFilter - Exercício 17
Volte ao projeto LayoutSamples Abra o AndroidManifest.xml Remova o elemento <action> e salve Tente rodar a aplicação pelo eclipse Tente rodar a aplicação pelo menu do emulador Desfaça a remoção (Ctrl+Z) Remove o elemento <category> e salve Tente rodar a aplicação Tente rodar a aplicação. Apenas com os dois elementos que a aplicação rodará normalmente.

6 Ações de Intent úteis Lembra das ações “nativas” do Android? Action
URI - chamar Uri.parse(uri) Descrição ACTION_VIEW Abre browser na página ACTION_VIEW ACTION_EDIT content://com.android.contacts/contacts/1 Mostra ou edita o contato solicitado geo:0,0?q=Presidente+Vargas,Rio+de+Janeiro Busca no Google Maps ACTION_CALL ACTION_DIAL tel: Liga ou apenas disca para o número ACTION_INSERT content://com.android.contacts/contacts Abre activity padrão para inserir contatos ACTION_PICK ContactsContract.Contacts.CONTENT_URI Abre lista de contatos do celular ACTION_SET_WALLPAPER - Abre lista para escolha de papéis de parede

7 Ações de Intent – Exercício 18
Crie um novo projeto chamado IntentFilterTest Experimente chamar activities usando a tabela anterior Exemplo: Uri uri = Uri.parse("content://com.android.contacts/contacts"); Intent intent = new Intent(Intent.ACTION_INSERT, uri); startActivity(intent); intent = new Intent(Intent.ACTION_SET_WALLPAPER); Experimente também: Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); intent.putExtra(SearchManager.QUERY, "Maria"); Sim, você pode passar parâmetros via Intent, dependendo de qual ação está sendo executada!

8 Ações de Intent – Exercício 18
ACTION_CALL não irá funcionar pois é necessário pedir permissão através do AndroidManifest.xml Adicione esta permissão e tente novamente <uses-permission android:name="android.permission.CALL_PHONE”/> Outras permissões úteis android.permission.READ_CONTACTS android.permission.VIBRATE android.permission.INTERNET android.permission.BATTERY_STATS android.permission.BLUETOOTH android.permission.CAMERA android.permission.REBOOT android.permission.SEND_SMS Além disso, para usar o Google Maps é necessário rodar o emulador com Google Maps.

9 Categorias e parâmetros para Intent
Algumas vezes Ação e URI não são suficientes É possível adicionar tantas categorias e parâmetros extras quanto forem necessários, além de outros dados: Os métodos setData() e setType() são antagônicos, ou seja, chamar um deles implica em limpar o outro. Método da Intent Descrição addCategory(String) Adiciona mais uma categoria à Intent putExtra(String, ...) Adiciona um parâmetro à Intent setData(Uri) Define o Uri. Equivalente ao parâmetro URI do construtor setType(String) Define o tipo MIME: text/plain, image/jpeg, etc setFlags(int) addFlags(int) Define os flags da Intent. Um flag útil é o FLAG_ACTIVITY_NEW_TASK, que faz a activity iniciar numa nova tarefa setAction(String) Define a ação desta intent. Note que, diferentemente de categorias e extras, apenas uma ação pode ser definida por intent.

10 Substituindo ações nativas
Tecla Home <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> Tecla discar (call) <action android:name="android.intent.action.CALL_BUTTON" /> Intent.ACTION_SEARCH <action android:name="android.intent.action.SEARCH" /> Intent.ACTION_WEB_SEARCH <action android:name="android.intent.action.WEB_SEARCH" />

11 Ações nativas - Exercícios 19 e 20
Crie um projeto IntentFilterNativeSubst Modifique o manifest e rode a aplicação para cada exemplo do slide anterior Exercício 20 Após o último exemplo (web search) edite o projeto IntentFilterTest para chamar web search: intent = new Intent(Intent.ACTION_WEB_SEARCH); intent.putExtra(SearchManager.QUERY, "Maria"); startActivity(intent); Execute IntentFilterTest Veja que o emulador irá perguntar qual aplicação executar

12 Ações e categorias próprias e filtragem
Para criar as próprias ações e categorias, faça: Configurá-las no manifest usando <intent-filter> Criar a Intent e executá-la Isto pode ser feito na mesma aplicação ou não Filtragem Ao executar uma Intent, uma activity só rodará caso seu intent-filter satisfaça a ação e todas as categorais definidas na Intent. Exemplos: Considere intent-filter: ACAO1, CATEG1, CATEG2 Intent: ACAO1, CATEG1  Executa Intent: ACAO1, CATEG1, CATEG2  Executa Intent: ACAO1, CATEG3  Não executa!

13 Ações próprias e filtragem – Exercício 21
No manifest de IntentFilterNativeSubst <action android:name="com.example.intentfilter.nativesubst.ACTION" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="com.example.intentfilter.nativesubst.CATEG1" /> <category android:name="com.example.intentfilter.nativesubst.CATEG2" /> Dê play na aplicação IntentFilterNativeSubst para instalá-la, note que nada rodará na tela, pois não há MAIN e LAUNCHER Em IntentFilterTest intent = new Intent("com.example.intentfilter.nativesubst.ACTION"); intent.addCategory("com.example.intentfilter.nativesubst.CATEG1"); intent.addCategory("com.example.intentfilter.nativesubst.CATEG2"); startActivity(intent); Rode IntentFilterTest e IntentFilterNativeSubst rodará Remova CATEG2 do manifest e repita a operação...

14 Intent filter e permissões
Caso um <intent-filter> não seja definido para uma activity apenas a própria aplicação poderá iniciá-la Mas é possível exportá-la <activity ... android:exported=“true” > ... Mesmo assim, é necessário que a aplicação que queira iniciá-la use Intent.setComponentName() ou setClassName() e conheça o nome da classe completo Exemplo: “com.example.application.ActivityName” O uso de <intent-filter> no manifest exporta a activity automaticamente Usar setClassName() ou setComponentName() para iniciar uma activity não exportada lançará uma SecurityException

15 Intent filter e permissões
É possível criar sua própria permissão <manifest ... > <permission android:name="application_package.PERMISSION_NAME" /> <application ... > <activity ... android:exported="true" android:permission="application_package.PERMISSION_NAME" > </activity> </application> </manifest> Se uma aplicação diferente quiser acessar esta activity será necessário usar um elemento <uses-permission> para a permissão definida pela aplicação <uses-permission android:name="application_package.PERMISSION_NAME"/>

16 BroadcastReceiver Chamado pelo Android para reagir a mensagens broadcast Usado para executar tarefas rápidas em segundo plano Não interromper o usuário por meio de activities Use notificações! (Serão explicadas em breve) O que são mensagens broadcasts? São mensagens enviadas pelo Android quando ocorre algum evento do sistema ou de uma aplicação Interceptada pelos BroadcastReceiver’s apropriados Definido pelos <intent-filter>

17 Tipos de broadcast Ordered ou Síncrono Normal ou Assíncrono
Os receivers são executados em sequência e a falha de um interrompe o processamento dos demais Não está no escopo deste curso Normal ou Assíncrono Todos os receivers executam simultaneamente em paralelo e de forma independente Método para disparar: Context.sendBroadcast(Intent) BroadcastReceiver1 Mensagem Evento ... BroadcastReceiverN

18 Configurando um receiver
É necessário adicionar o elemento <receiver> dentro de <aplication> no AndroidManifest.xml <receiver android:name="NomeReceiver"> <intent-filter> <action android:name="com.example.broadcastreceiver.ACTION"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </receiver> Implementar uma classe filha de BroadcastReceiver com o callback onReceive(Context, Intent) public class NomeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // ... } Atenção: onReceive deve retornar em menos de 10 s.

19 Disparando mensagens broadcast
Criar uma Intent com a mensagem Enviar via Context.sendBroadcast(Intent) Context é uma classe base de activity, logo o método pode ser chamado diretamente Intent intent = new Intent("com.example.broadcastreceiver.ACTION"); sendBroadcast(intent);

20 Broadcast Receiver – Exercício 22
Crie um projeto chamado ReceiverTest Crie um broadcast conforme slide anterior Dentro do método onReceive escreva algo no log Edite o projeto IntentFilterTest para enviar o broadcast

21 Mensagens broadcast do sistema
Mensagens broadcast enviadas apenas pelo sistema Não podem ser enviadas pelo método sendBroadcast() * Requer permissão android.permission.RECEIVE_BOOT_COMPLETED ** Não podem ser usados com <intent-filter> serão mostrados em breve android.intent.action Condição de envio (pelo sistema) WALLPAPER_CHANGED Papel de parece alterado BOOT_COMPLETED* Sistema concluiu o bootstrap ACTION_SHUTDOWN Sistema está desligando (antes de desligar o aparelho) BATTERY_CHANGED** Estado de carga da bateria mudou BATTERY_LOW Estado de carga da bateria baixo BATTERY_OKAY Estado de carga da bateria voltou a níveis normais ACTION_POWER_CONNECTED Carregador conectado ACTION_POWER_DISCONNECTED Carregador desconectado

22 Mensagens broadcast do sistema
** Não podem ser usados com <intent-filter> serão mostrados em breve android.intent.action.* Condição de envio (pelo sistema) TIME_SET Data e/ou hora do sistema foram alterados TIMEZONE_CHANGED Fuso horário foi modificado TIME_TICK** Hora do sistema mudou normalmente (enviado a cada minuto) SCREEN_ON Tela do dispositivo acendeu (estava inativa, mas usuário ativou) SCREEN_OFF Tela do dispositivo apagou (normal para economizar bateria) PACKAGE_ADDED Uma nova aplicação foi instalada no dispositivo PACKAGE_REMOVED Uma aplicação foi removida do dispositivo PACKAGE_REPLACED Uma aplicação foi substituída. Normalmente por upgrade de versão. PACKAGE_RESTARTED Uma aplicação foi reiniciada, tendo seus processados terminados. PACKAGE_DATA_CLEARED Dados de uma aplicação foram apagados. Enviado após PACKAGE_RESTARTED

23 Broadcast de sistema – Exercício 23
Adicione mais um receiver no projeto ReceiverTest <receiver android:name="WallpaperReceiver"> <intent-filter> <action android:name="android.intent.action.WALLPAPER_CHANGED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver> Adicione o seguinte no callback onReceive() Log.i(this.getClass().getCanonicalName(), intent.getAction()); Instale a aplicaçao Tenta mudar o papel de parede no emulador Menu > Wallpaper > Wallpapers Analise o LogCat.

24 Configuração de receivers via código
Indicado quando um receiver deve executar apenas quando uma acitivity está executando É possível registrar dinamicamente via código registerReceiver(BroadcastReceiver, Intent) unregisterReceiver(BroadcastReceiver) Recomendável: Registrar em Activity.onCreate() ou onResume() Desregistrar no Activity.onDestroy() ou onPause() Note que são necessários para actions TIME_TICK e BATTERY_CHANGED da tabela

25 Threads São linhas ou fluxos de execução de código que rodam em “paralelo” numa mesma aplicação Usadas para executar tarefas independentes entre si. Sempre há uma thread inicial ou principal Interface gráfica sempre executa nesta thread Exemplo: Uma aplicação pode usar 3 threads, assim distribuídas: Interface gráfica Reprodução de música Download de arquivo da Internet

26 Exemplo de aplicação multithread

27 Classe Thread e Interface Runnable
Métodos da classe Thread * Cuidado ao chamar métodos bloqueantes em threads que recebem callbacks, pois estes devem retornar rapidamente. Objetos modificados por mais de uma thread: synchronized (objeto) { // modifica objeto } Thread(Runnable) Construtor de thread que recebe um objeto Runnable contendo o código a ser executado static void sleep(long milis)* Faz thread que chamar este dormir milis milissegundos. void start() Inicia thread void join(long milis, int nanos)* Aguarda término da thread por tantos milissegundo. Ambos os argumentos são opcionais. bool isAlive() Retorna true se thread ainda está em execução void run() Deve ser implementado com o código da thread. A interface Runnable também possui este método. Não chamar diretamente.

28 Usando threads Em um método qualquer (criação e execução)
Runnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); Em outro método (aguardar término) try { thread.join(1000); } catch (InterruptedException e) {} Classe que contém o código class MyRunnable implements Runnable { public void run() { // codigo da thread que pode ser um loop ou não }

29 Threads e interfaces gráficas
Callbacks sempre rodam na thread principal da aplicação Todos os objetos de View e subclasses são atrelados à thread que o criou também conhecida como UI Thread Chamar um método de View que a modifique resultará no lançamento de uma exceção ViewRoot.CalledFromWrongThreadException: Apenas a thread que criou a view pode modificá-la Para isso deve-se usar um Handler que será mostrado posteriormente

30 Serviços Usado para executar tarefas em segundo plano
Estas tarefas não possuem um tempo definido de execução (podendo ser demoradas) Não deve iniciar activities: use notificações (em breve) Configuração no AndroidManifest.xml <application ... > <service android:name="ServiceName"> <intent-filter> <action android:name="com.example.serviceapp.ACTION" /> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </service> </application> Caso se queira iniciar o serviço de outra aplicação sem um <intent-filter> deve-se usar android:exported="true"

31 Formas de iniciar um serviço
Pode ser iniciado de dentro de activity, broadcast receiver ou outro serviço Duas formas: Desacoplado: serviço é iniciado e fica independente do contexto (activity, receiver ou serviço) chamador Com conexão: serviço é iniciado, retorna uma interface de acesso e fica associado ao contexto chamador. Usado quando precisa-se “conversar” com o serviço. Métodos para inicialização (classe Context) Método Descrição startService(Intent) Inicia um serviço desacoplado bindService(Intent, ServiceConnection, flags) Inicia um serviço conectado. O segundo parâmetro é um objeto com métodos callbacks para notificar conexão e desconexão

32 Ciclo de vida de um serviço

33 Classe Service Classe base para qualquer serviço
public class MyService extends Service { @Override public IBinder onBind(Intent arg0) { return null; } public void onCreate() { super.onCreate(); // Inicializar varíaves e criar uma thread (opcional) public void onDestroy() { super.onDestroy(); // Terminar a thread aqui, caso esteja rodando

34 Compatibilidade com versões anteriores
// Método onStart antigo que é chamado nas // plataformas anteriores a public void onStart(Intent intent, int startId) { processaStart(intent); } // Método chamado a partir da plataforma 2.0 public int onStartCommand(Intent intent, int flags, int startId) { // Retorne isto para que o serviço rode até ser // explicitamente terminado return START_STICKY; // Método para onde onStart e onStartCommand converge protected void processaStart(Intent intent) { // Processa independente de versão de plataforma

35 Inicialização de serviços desacoplados
Método startService(Intent) Inicia o serviço determinado pela intent. O serviço roda independente do chamador e por tempo indeterminado Se o contexto chamador terminar o serviço continua rodando normalmente Pode ser chamado inúmeras vezes Apenas na primeira o callback onCreate() é chamado O método onStart/onStartCommand sempre é chamado Método stopService(Intent) Termina o serviço chamando onDestroy() Não importa quantas vezes startService() foi chamado, uma única chamada a este encerra o serviço

36 Como e quando terminar serviços
Método stopSelf() Chamar quando serviço terminar o processamento Boa prática para evitar consumo de bateria Caso queira que o serviço volte a executar de forma automática no futuro usar AlarmManager (em breve)

37 Serviços - Exercício 24 Crie um projeto chamado ServiceTest sem activitty Adicione uma classe ServiceTest que extenda Service Implemente onCreate() e onDestroy() escrevendo no LogCat uma mensagem dizendo em qual deles está No manifest, coloque um <intent-filter> dentro de <service> com o seguinte par action-category: "com.example.servicetest.SERVICE“ "android.intent.category.DEFAULT" No projeto ReceiverTest, adicione as seguintes linhas no final do método WallpaperReceiver.onReceive() intent = new Intent("com.example.servicetest.SERVICE"); context.startService(intent); Instale, mude o papel de parede e olhe o LogCat

38 Serviços e threads – Exercício 25
Ainda na classe ServiceTest Implemente a interface Runnable Crie uma thread e a inicie no onCreate() Ela deve incrementar um contador a cada 250 ms até 40 Ao terminar chamar stopSelf() dentro de run() Instale o serviço No emulador, mude o papel de parede Olhe o LogCat e veja que, deta vez, o método onDestroy() será chamado (em aproximadamente 10s)

39 Serviços e permissões – Exercício 26
No manifest de ServiceTest adicione <permission> <permission android:name="com.example.servicetest.permission.SERVICE" /> Note que android:label deve ser um recurso string No elemento <service> Remova <intent-filter> Adicione android:exported=“true” android:permission <service android:exported="true" android:permission="com.example.servicetest.permission.SERVICE" > No manifest do projeto ReceiverTest adicione <uses-permission android:name="com.example.servicetest.permission.SERVICE”/> (continua)

40 Serviços e permissões – Exercício 26
Em WallpaperReceiver.java altera a linha que cria intent por intent = new Intent(); intent.setClassName("com.example.servicetest", "com.example.servicetest.ServiceTest"); Instale ambas as aplicações No emulador mude o papel de parede Veja pelo LogCat que o serviço foi normalmente criado e finalizado Remova o elemento <uses-permission> do manifest Veja agora que ao mudar o papel de parede é lançado um SecurityException

41 Uso de serviços com conexão
Método bindService(Intent, ServiceConnection, flags) Associa o contexto ao serviço, ou seja, serviço é útil até que o contexto termine ou chame unbindService() Se o serviço não estiver rodando e flags for igual a BIND_AUTO_CREATE o serviço será iniciado Não pode ser chamado de um BroadcastReceiver Chama onCreate() e onBind() mas não chama onStartCommand() nem onStart() Método unbindService(ServiceConnection) Desconecta o contexto atual do serviço Se não houver outras aplicações conectadas ao serviço nem startService() tiver sido usado então o método onDestroy() será chamado e o serviço terminado

42 Interface ServiceConnection
É uma interface com métodos callback para notificar a aplicação sobre conexão e desconexão do serviço Método callback Descrição onServiceConnected(ComponentName, IBinder) Evento: foi estabelecida uma nova conexão ao serviço definido pelos argumentos do método. Ação: fazer type cast para a classe Binder do serviço e obter sua interface. onServiceDisconnected(ComponentName name) Evento: a conexão com o serviço foi perdido devido a uma chamada a unbindService() ou o término do serviço. No segundo caso, a associação ao serviço continua ativa e caso o serviço volte a executar o método onServiceConnected será chamado novamente. Ação: remover todas as referências para a interface obtida anteriormente.

43 Classe Binder e interface IBinder
IBinder é usada apenas como retorno de onBind() e argumento de onServiceConnected() Binder é uma classe que implementa os métodos de IBinder para simplificar a criação de binders por parte dos serviços Binder deve ser usada como classe base para o binder do serviço quando este não é remoto (em breve)

44 Serviços com conexão – Exercício 27
No projeto ServiceTest Crie uma interface chamada Contador com os métodos int get(), void set(int) e void reset() Crie uma nova classe nomeada ServiceBindTest Faça-a estender ServiceTest e implementar Contador Crie um classe interna chamada ContadorBinder Faça-a estender Binder Crie um método Contador getInterface() que retorna a intância do serviço Crie um campo para guardar a instância de ContadorBinder e crie o método onBind() que a retorne Implemente os métodos get, set e reset que alteram a variável de contagem da classe ServiceTest

45 Serviços com conexão – Exercício 27
Adicione um <service> para o novo serviço no manifest Legal o serviço está pronto, mas como conectar-se à interface? Uma activity! Crie uma activity chamada ServiceBinderActivity Pegue o arquivo de XML de layout do próximo slide Adicione um <activity> no manifest Crie um campo para guardar a interface do serviço Contador contador; Pegue o código de onCreate() dos slide seguintes Herde de ServiceConnection e adicione seus métodos

46 Exercício 27 – XML de layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:text="Conectar ao serviço" android:layout_width="wrap_content“ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> <Button android:text="Desconectar do serviço" <Button android:text="Zerar contador" <Button android:text="Ler contador“ <TextView android:text="0" </LinearLayout>

47 Exercício 27 - Método onCreate()
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView text = (TextView) findViewById(R.id.valorContador); Button btnBind = (Button) findViewById(R.id.btnBind); btnBind.setOnClickListener(new OnClickListener() public void onClick(View v) { // bindService } }); Button btnUnbind = (Button) findViewById(R.id.btnUnbind); btnUnbind.setOnClickListener(new OnClickListener() { // unbindService

48 Exercício 27 - Método onCreate()
Button btnGet = (Button) findViewById(R.id.btnLerContador); btnGet.setOnClickListener(new OnClickListener() public void onClick(View v) { // ler contador aqui int count = 0; text.setText("" + count); } }); Button btnReset = (Button) findViewById(R.id.btnZerarContador); btnReset.setOnClickListener(new OnClickListener() { // zerar contador aqui } // Fim onCreate()

49 Exercício 27 – Conclusão Adicione códigos necessários nos callbacks onClick() bindService(intent,ServiceBinderActivity.this,BIND_AUTO_CREATE); unbindService(ServiceBinderActivity.this); int count = contador.get(); contador.reset(); Implemente os métodos de ServiceConnection onServiceConnected(ComponentName, IBinder service) ContadorBinder binder = (ContadorBinder) service; contador = binder.getInterface(); onServiceDisconnected(ComponentName) contador = null; Instale a aplicação e execute sua activity

50 Serviços remotos e AIDL
Serviços remotos são aqueles executados em uma aplicação diferente da que chama bindService() Necessário dizer ao Android qual é a interface do serviço Android Interface Definition Language (AIDL) Criar uma interface com extensão *.aidl Ao criar a interface AIDL no projeto, o eclipse cria automaticamente uma classe de mesmo nome Esta classe não pode ser alterada O serviço deve herdar da classe interna Stub e implementar os métodos definidos pela interface AIDL A aplicação que se conectar ao serviço deve conhecer apenas a interface AIDL

51 Serviços remotos - Exercício 28
No projeto ServiceTest, crie ContadorRemoto.aidl O package pode ser com.example.servicetest.aidl Os métodos devem ser os mesmo da interface Contador Não é possível usar extends com AIDL Na classe ServiceBindTest Crie um classe interna que herde ContadorRemoto.Stub Chame-a de ContadorRemotoBinder Crie construtor que guarde uma instância de Contador Implemente os métodos de ContadorRemoto usando a instância de Contador obtida Crie campo para uma instância de ContadorRemotoBinder No método onBind(), retorne esta instância

52 Serviços remotos – Exercício 28
Crie um projeto chamado ActivityForRemoteService Copie o layout de ServiceTest para main.xml do novo projeto Substitua o conteúdo da nova activity pelo existente na ServiceBinderActivity Corrija os erros de nome de activity (ficam destacados) Faça-a implementar ServiceConnection Substitua o tipo do contador para ContadorRemoto Copie o pacote com.example.servicetest.aidl de ServiceTest para a pasta src do novo projeto Adicione try...catch nas chamadas do ContadorRemoto

53 Serviços remotos – Exercício 28
Substitua o código de onServiceConnected void onServiceConnected(ComponentName name, IBinder service) { contador = ContadorRemoto.Stub.asInterface(service); } No manifest do projeto ServiceTest remova <intent- filter> da activity Instale ServiceTest novamente Execute ActivityForRemoteService Pelo LogCat pode-se ver que o resultado é igual, mas a activity roda em uma aplicação e o serviço em outra. Note que este método também pode ser usado com activity e serviço na mesma aplicação, permitindo criação de interfaces de serviço genéricas

54 Notificações Mensagem que aparece na barra de status
Permite avisar o usuário sobre algo sem pertubá-lo Pode disparar uma intent ao ser selecionada Motivo para usar Não pertubar o usuário com a apresentação de uma Activity O usuário só irá abrir a activity quando e se quiser

55 Classe NotificationManager
Classe responsável por gerenciar notificações Cada notificação é identificada por um par (tag, id) Id é um identificador inteiro Tag é uma string que pode ser null Usar getSystemService(NOTIFICATION_SERVICE) Método Descrição notify(int id, Notification) Adiciona uma notificação à barra de status associando-a ao id notify(tag, id, Notification) Semelhante ao anterior, porém associa a notificação a um par (tag, id) cancel(id) Cancela uma notificação, ou seja, remove da barra da status cancel(tag, id) Semalhante ao anterior, porém a notifacação precisa ter sido criado com notify(tag, id, Notification) cancelAll() Cancela todas as notificações

56 Classe PendingIntent Permite definir que uma intent seja executada por alguma aplicação no futuro Métodos Descrição static PendingIntent getActivity(Context, int requestCode, Intent, flags) Retorna uma PendingIntent que iniciará uma activity quando for disparada. Semelhante a startActivity(Intent) static PendingIntent getBroadcast(Context, requestCode, Intent, flags) Retorna uma PendingIntent que ativará um broadcast quando for disparada. Semelhante a sendBroadcast(Intent) static PendingIntent getService(Context, int requestCode, Intent, flags) Retorna uma PendingIntent que iniciará um serviço quando for disparada. Semelhante a startService(Intent) void send() Dispara esta PendingIntent. FLAG_CANCEL_CURRENT FLAG_UPDATE_CURRENT FLAG_NO_CREATE FLAG_ONE_SHOT

57 Classe Notification Representa a notificação propriamente dita
Construtor Notification(int icon, textoBarraStatus, long when) Construtor que define o ícone e o texto que aparece na barra de status durante alguns segundos. Além do instante em que a notificação deve aparecer baseado em System.currentTimeMillis(). Método setLatestEventInfo (Context, titulo, mensagem, PendingIntent) Define o conteúdo da mensagem: título, mensagem e a PendingIntent que será disparada caso o usuário selecione a notificação Campo public int flags Flags: FLAG_INSISTENT ou FLAG_AUTO_CANCEL public int defaults Define o que fazer quando a notificação aparece na barra de status: DEFAULT_SOUND, DEFAULT_LIGHTS, DEFAULT_VIBRATE, DEFAULT_ALL public long [] vibrate Define padrão de vibração: sequência de números inteiros de definem tempo de vibração e parada Notification.FLAG_INSISTENT Vibração e/ou áudio contínuos Notification.FLAG_AUTO_CANCEL Cancela notificação quando usuário seleciona

58 Etapas para mostrar uma notificação
Criar um Intent para activity, service ou broadcast Obter uma PendingIntent associada à intent Criar uma instância de Notification Configurar a notificação com setLatestEventInfo(), flags e defaults Obter a intância NotificationManager (nm) Chamar nm.notify(...) Quando o usuário selecionar a notificação a intent definida será disparada (activity, service ou broadcast) O alvo da intent pode cancelar a notificação se esta não for mais necessária ou colocar FLAG_AUTO_CANCEL no flags da notificação antes de chamar nm.notify()

59 Notificação – Exercício 29
Criar uma aplicação que cria uma notificação A notificação deverá abrir uma segunda activity quando selecionada Expanda o exercício para enviar parâmetros para a segunda activity usando Intent.putExtra() ou putExtras Você pode usar flags e defaults (embora algumas funcionalidades não possam ser vistas no emulador)

60 AlarmManager Permite agendar intents paras serem executadas
Em um momento futuro, ou Em intervalos regulares Agendamentos são preservados enquanto dispositivo estiver ligado (em uso ou stand-by) mas são cancelados quando é desligado e ligado novamente ou é reiniciado (reboot) Para obter a instância classe use AlarmManger am = (AlarmManager)getSystemService(ALARM_SERVICE)

61 Classe AlarmManager set(int tipo, long instante, PendingIntent)
Agenda um alarme para ser disparado no instante especificado e a intent que será disparada. setRepeating(int tipo, long instante, long intervalo, PendingIntent) Agenda um alarme para ser disparado no instante especificado e o intervalo para disparos subsequentes. cancel(PendingIntent) Cancela um alarme previamente configurado Tipo Instante de tempo do alarme Acorda o dispositivo? ELAPSED_REALTIME Relativo Sim ELAPSED_REALTIME_WAKEUP Não RTC Absoluto RTC_WAKEUP Absoluto Baseado em SystemClock.elapsedRealtime(), i.e, milissegundos desde o boot. Relativo Baseado em System.currentTimeMillis(), i.e, milissegundos desde 01/01/1970 Acorda Caso o dispositivo esteja dormindo será acordado para tratar o alarme. Não acorda Caso o dispositivo esteja dormindo ele não será acordado e o alarme será disparado apenas quando o dispositivo acordar normalmente.

62 AlarmManager – Exercício 30
Criar um alarme para iniciar ServiceTest e reativá-lo a cada 30 segundos Na activity WallpaperReceiver do projeto ReceiverTest Aproveite a intent que inicia o serviço Crie uma PendingIntent para serviço usando a intent Obtenha o AlarmManager via getSystemService() Chame setRepeating para agendar o alarme Instale a aplicação ReceiverTest No emulador, altere o papel de parede Observe o LogCat por 1 min para ver as mensagens O serviço reiniciará e terminará infinitamente até que o agendamento seja cancelado ou o emulador reiniciado

63 Handler Threads têm filas de mensagens para comunicação
Um Handler se associa à fila de uma thread e permite enfileirar mensagens nesta fila Enfileira para execução imediata ou agendada Estas mensagens serão executadas na thread associada As mensagens podem ser enviadas de qualquer thread Tipos de mensagens java.lang.Runnable O método void run() será executado android.os.Message Necessário estender Handler e implementar void handleMessage(Message) para executar a mensagem

64 Hander com Message Message guarda informações da mensagem Forma de uso
Necessário estender Handler Implementar handMessage(Message), e Interpretar o atributo what da mensagem Campo int what O código da mensagem definido pelo usuário. int arg1, arg2 Argumentos que podem ser definidos para não precisar definir objetos complexos de dados. Método setData(Bundle) Bundle getData() Usado quando os parâmetros a serem passados não podem ser representados como inteiros em arg1 e arg2. long getWhen() Retorna o instante, em milisegundos, em que a mensagem será entregue.

65 Métodos de Handler sendMessage(Message)
Envia mensagem para ser processada assim que possível. sendMessageDelayed(Message, long delay) Envia mensagem para ser processada após o tempo indicado ter decorrido. sendMessageAtTime(Message, long time) Envia mensagem para ser processada apenas no instante de tempo informado. sendEmptyMessage(int what) Cria uma mensagem apenas com o campo what preenchido e adiciona na fila para ser processada assim que possível. sendEmptyMessageDelayed(int what, Semelhante ao anterior mas processa mensagem apenas após o tempo indicado ter decorrido. sendEmptyMessageAtTime(int what, long time) Semelhante ao anterior mas processa mensagem apenas no instante informado. post(Runnable) Envia Runnable para ser executado assim que possível. postDelayed(Runnable, long delay) Envia Runnable para ser executado após o tempo indicado ter decorrido. postAtTime(Runnable, long time) Envia Runnable para ser executado apenas no instante de tempo informado.

66 Handler – Exercício 31 Na activity do projeto ActivityForRemoteService
Crie um campo para armazenar um handler para a interface gráfica Handler handler = new Handler(); Criar uma thread que atualiza a View que mostra o contador a cada 1000 ms Crie uma classe interna chamada ContadorThread que estenda Thread. No método run() faça um loop que poste um Runnable Thread.sleep(1000) handler.post(new Runnable() { ... } ) O Runnable deve atualizar o TextView com o valor do contador Nos exemplos existe um brinde que não usa thread!

67 Persistência Existem 3 formas de armazenar dados no dispositivo
Arquivos comuns (texto ou binário) Classes FileInputStream e FileOutputStream Armazenados em /data/data/<pacote>/files Arquivos de preferências Classe SharedPreferences Bancos de Dados usando SQLite Classes SQLiteDatabase, SQLiteOpenHelper Armazenados em /data/data/<pacote>/databases

68 Classe Environment Acessar varíaveis ambientais do dispositivo
static File getDataDirectory() Retorna o diretório de dados do Android. static File getDownloadCacheDirectory() Retorna o diretório onde o Android salva os downloads e cache. static File getExternalStorageDirectory() Retorna o diretório de armazenamento externo (p.ex. cartão de memória) static File getExternalStoragePublicDirectory(tipo) Retorna o diretório público de armazenamento externo para um tipo de arquivo. Tipo pode ser DIRECTORY_DCIM, DIRECTORY_DOWNLOADS, DIRECTORY_MOVIES, DIRECTORY_MUSIC, DIRECTORY_PICTURES, etc. static String getExternalStorageState() Retorna o estado do dispositivo de armazenamento externo principal. Retorno pode ser MEDIA_MOUNTED (disponível para uso leitura e escrita), MEDIA_MOUNTED_READ_ONLY (disponível apenas para leitura), MEDIA_REMOVED (dispositivo não presente), MEDIA_SHARED (dispositivo presente, não montado e compartilhado via USB). Outros: MEDIA_UNMOUNTABLE, MEDIA_UNMOUNTED, MEDIA_BAD_REMOVAL, MEDIA_CHECKING static boolean isExternalStorageRemovable() Se o dispositivo externo de armazenamento é removível ou não. Acessar varíaveis ambientais do dispositivo

69 Arquivos comuns Métodos da classe Context
FileInputStream contém métodos para ler bytes FileOutputStream contém métodos para escrever bytes InputStreamReader pode ser construído a partir de um FileInputStream e contém métodos para ler caracteres OutputStreamWriter pode ser construído a partir de um FileOuputStream e contém métodos para escrever caracteres FileInputStream openFileInput(String name) Abre um arquivo privado associado a aplicação para leitura. Argumento name não pode conter ‘/’. FileOutputStream openFileOutput(String name, int mode) Abre um arquivo privado associado a aplicação para escrita. Argumento mode pode ser Context.MODE_PRIVATE ou Context.MODE_APPEND

70 Arquivos comuns Exemplo de escrita try {
FileOutputStream fis = openFileOutput(“dados”, MODE_PRIVATE); OutputStreamWriter isr = new OutputStreamWriter(fis); isr.write("Nome: " + nome + "\n"); isr.write(" " + + "\n"); isr.close(); } catch (FileNotFoundException e) { } catch (IOException e) { }

71 SharedPreferences Classe para armazenar preferências ou configurações da aplicação. É possível usar quantas quiser, desde que associadas a um nome de arquivo Guarda informações na forma de pares chave-valor Para obter a instância desta classe associada ao nome de arquivo “preferencias” faça SharedPreferences pref = Context.getSharedPreferences(“preferencias”, 0); Se o arquivo ainda não existir será criado Para editar usar a classe SharedPreferences.Editor SharedPreferences.Editor editor = prefs.edit();

72 ShardPreferences Métodos boolean contains(String key)
Retorna true caso a chave key exista. boolean getBoolean(String key, boolean) float getFloat(String key, float) int getInt(String key, int) long getLong(String key, long) String getString(String key, String) Retorna o valor de uma chave. O segundo parâmetro indica o valor default que deve ser retornado caso a chave não exista. Note que é necessário que o desenvolvedor saiba o tipo do dado armazenado na chave. Caso a chave exista mas o tipo seja diferente do especificado no método será lançado um ClassCastException. SharedPreferences.Edit edit() Retorna um editor para as preferências que permite editar e salvar informações.

73 SharedPreferences.Editor
Usada para editar as preferências boolean commit() Salva as preferências no objeto SharedPreferences associado e em disco. Operação síncrona, ou seja, só retorna após ter salvo em disco retornando true em caso de sucesso, ou false senão. void apply() Aplica os novos valores das preferências ao objeto em memória e retorna. O armazenamento em disco será feito de forma assíncrona, ou seja, não é possível saber se houve algum error durante o armazenamento. clear() Remove todos os valores de preferências do objeto. putBoolean(String key, boolean) putFloat(String key, float) putInt(String key, int) putLong(String key, long) putString(String key, String) Adiciona ou altera o valor de uma chave. O nome do método e o segundo parâmetro indicam o tipo do valor da chave. remove(String key) Remove a chave definida por key e consequentemente o seu valor.

74 Banco de Dados Consiste em tabelas onde dados podem inseridos, modificados ou excluídos De forma simplória uma tabela pode ser vista como uma planilha do Excel As colunas da planilha equivalem aos campos da tabela As linhas da planilha equivalem aos registros da tabela Esta analogia acaba quando consideram-se índices e relações entre registros. Não é o escopo do curso No Android, é utilizado SQLite para gerenciar as tabelas de bancos de dados

75 SQL - Structured Query Language
Linguagem padrão para consulta a bancos de dados Construções básicas SELECT Campo1, Campo2, ... FROM Tabela1, Tabela2 WHERE <condição> ORDERBY CampoX; INSERT INTO Tabela(Campo1, Campo2, ...) VALUES (Valor1, Valor2, ...); DELETE FROM Tabela WHERE <condição>; UPDATE Tabela SET Campo1 = <expressao1>, Campo2 = <expressao2> WHERE <condição>; Criação e exclusão de tabelas []=opcional CREATE TABLE Tabela ( id INTEGER PRIMARY KEY AUTOINCREMENT, Campo1 Tipo1 [[UNIQUE] NOT NULL], Campo2 Tipo2 [NOT] NULL, ); DROP TABLE IF EXISTS Tabela

76 SQL Exemplos de <expressão> Exemplos de <condição> Tipos
Preço – Taxas LENGTH(Tabela.Nome) Tabela.Idade IS [NOT] NULL Exemplos de <condição> (Nome = “Maria” OR Nome = “João”) AND Idade <= 40 AND Idade >= 18 LENGTH(Nome) > 4 Preço – Taxas > 10.0 Tipos INTEGER, REAL, TEXT

77 Criação do banco de dados
API do Android (executar SQL) Adotado aqui pois permite criar pela aplicação Cliente gráfico do SQLite SQLite Expert Personal (gratuito) Usando SQL via linha de comando Programa na pasta do SDK do Android <pasta_android>\android-sdk-windows\tools\sqlite3.exe Nos 2 últimos, após criar, é preciso mover o arquivo para a pasta /data/data/<pacote>/databases do emulator No eclipse (com emulador aberto): Window > Show view > Other... > FileExplorer

78 Classe SQLiteOpenHelper
Auxilia abertura e criação de um banco de dados SQLiteOpenHelper(Context, String name, SQLiteDatabase.CursorFactory, int version) Cria um objeto para auxiliar no gerenciamento da base de dados. SQLiteDatabase getReadableDatabase() Cria ou abre um banco de dados apenas para leitura. SQLiteDatabase getWritableDatabase() Cria ou abre um banco de dados para leitura e escrita. void onCreate(SQLiteDatabase db) Chamado quando o banco de dados precisa ser criado, ou seja, não existe. void onOpen(SQLiteDatabase db) Chamado quando o banco de dados é aberto. void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) Chamado quando a versão do banco de dados sendo aberto é diferente da versão existente.

79 Classe SQLiteDatabase
Representa o banco de dados e executa operações de consulta, inclusão, alteração e exclusão de registros static SQLiteDatabase openDatabase(String path, CursorFactory factory, flags) Abre banco de dados de acordo com os flags: OPEN_READWRITE, OPEN_READONLY, CREATE_IF_NECESSARY, NO_LOCALIZED_COLLATORS. openOrCreateDatabase(String path, CursorFactory factory) openOrCreateDatabase(File file, Abre ou cria banco de dados. Equivalente a usar openDatabase(…) com flags = CREATE_IF_NECESSARY boolean isOpen() Verifica se está aberto void close() Fecha banco de dados void execSQL(String sql) Executa script SQL que não seja SELECT. Exemplo: CREATE TABLE, INSERT, UPDATE, etc.

80 Classe SQLiteDatabase
Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) Cursor query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit) Cursor query(boolean distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, String limit) Mostra e executa um SQL de consulta na forma: SELECT <distinct> <columns> FROM <table> WHERE <selection+selectionArgs> GROUP BY <groupBy> HAVING <having> ORDER BY <orderBy> LIMIT <limit> long insert(table, null, ContentValues values) Insere um registro e retorna o id. INSERT INTO <table> (values) VALUES (values) int update(table, ContentValues values, whereClause, whereArgs) Altera registro(s) e retorna quantidade de linhas modificadas. UPDATE <table> SET <values> WHERE <whereClause+whereArgs> int delete(table, whereClause, whereArgs) Deleta registro(s) e retorna quantidade de linhas modificadas. DELETE FROM <table>

81 Classes ContentValues e Cursor
Usado para armazenar o conteúdo de um registro para uma operação Equivalente a um HashMap put(String key, valor) Cursor Equivalente a um ResultSet no JDBC Lista de resultados de uma consulta no banco Exercício: importar e entender o exemplo

82 Provedores de conteúdo
Provedor de conteúdo Permite tornar dados de uma aplicação disponível para outras Usa uma interface padronizada Declarar no manifest com <provider> Classe ContentProvider Baseado em URIs content://com.android.contacts/contacts/1 Prefixo – content:// Autoridade – com.android.contacts Caminho - /contacts/ Id do registro (opcional) – 1 Classe UriMatcher para validar URIs

83 ContentProvider Exemplo de uso nos exemplos
Para constuir é necessário implementar os métodos a seguir (procedimento complexo, ver exemplo) public String getType(Uri uri); Retorna o tipo do URI public boolean onCreate(); Chamado pelo Android quando provider é criado public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder); Realiza uma consulta e retorna ao usuário public Uri insert(Uri uri, ContentValues values); Insere um novo registro e retorna seu URI public int update(Uri uri, ContentValues values, String where, String[] whereArgs); Atualiza um ou mais registros existentes. public int delete(Uri uri, String where, String[] whereArgs); Exclui um registro.

84 Mapas e GPS

85 JARs no projeto

86 WebServices

87 Câmera


Carregar ppt "Curso de Android Fevereiro de 2011 Cristiano Expedito Ribeiro"

Apresentações semelhantes


Anúncios Google