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

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

Manipulando contatos no Android Por José Antonio Borges.

Apresentações semelhantes


Apresentação em tema: "Manipulando contatos no Android Por José Antonio Borges."— Transcrição da apresentação:

1 Manipulando contatos no Android Por José Antonio Borges

2 Parece fácil acessar e manipular contatos, mas não é... Contatos são representados por uma base da dados em SqlLite. Então em princípio seria questão de conhecer e acessar esta base. O problema é que os dados gerados por uma aplicação não podem ser lidos por outra. A forma de comunicar é um mecanismo chamado “content provider”. – Padrão geral não tão simples assim – Permite, em princípio, executar CRUD (create, read, update, delete).

3 Mas há outros probleminhas Teremos que mostrar e manipular parte destes dados na tela, provavelmente a partir de uma “lista visual”, contendo elementos selecionados, trazidos para a memória da aplicação. Veremos alguns detalhes iniciais para que depois tudo se torne mais simples.

4 Listas em Java ArrayList é uma forma organizada de pensar num array dinâmico É um tipo abstrato de dados: representa um array de tamanho variável, contendo “sei lá o que”. Construtor: ArrayList amigos = new ArrayList (); Nota: String, foi só um exemplo, qualquer classe serve. Alguns métodos clear, add ou add(posicao,...) remove, size, get(posicao), indexOf(conteúdo)

5 ArrayList bandas = new ArrayList (); bandas.add("Renato e seus Blue Caps"); bandas.add("Beatles"); bandas.add("Iron Maiden"); System.out.println( Arrays.toString( bandas.toArray() ) ); System.out.println( "Quem está na índice 0 é “, bandas.get(0) ); bandas.add( bandas.indexOf(“Beatles"), "Tiririca"); System.out.println( "Número de elementos na lista:, bandas.size() ); bandas.remove("Tiririca"); bandas.clear();

6 Adapters em Java Adapter (Adaptador) é um padrão de projeto que permite que um objeto seja utilizado com um contrato diferente do seu. – O contrato é o conjunto de métodos, parâmetros e funcionalidades públicos. O Padrão Adapter é utilizado quando temos uma classe existente cuja interface não é adequada para as suas necessidades.

7 ArrayAdapters são muito usados para produzir listas na tela do Android Similar aos “listbox” de Windows. Ex.: String[] items = {"Antonio", “Pedro", “Tomás", “Liane", “Tiago" }; ListView listView1 = (ListView) findViewById(R.id.listView1); ArrayAdapter adapter = new ArrayAdapter (this, android.R.layout.simple_list_item_1, items); listView1.setAdapter(adapter); Listview: Método principal de callback: – protected void onListItemClick (ListView l, View v, int position, long id)ListViewView

8 import android.view.View;... public class MainActivity extends Activity implements OnItemClickListener, OnClickListener { private ListView lvLista; private TextView tEscolha; private static final String[] items = {"Antonio", "Pedro", "Tomás", “Liane", "Tiago" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tEscolha = (TextView) findViewById(R.id.t_escolha); lvLista = (ListView) findViewById(R.id.lv_lista); lvLista.setAdapter(new ArrayAdapter (this, android.R.layout.simple_list_item_1, items)); lvLista.setOnItemClickListener(this); tEscolha.setOnClickListener(this); }

9 @Override public void onClick(View v) { Toast.makeText(this, “Escolha a pessoa", Toast.LENGTH_SHORT).show(); Intent it = new Intent(this, OutraListBox.class); startActivity(it); } @Override public void onItemClick(AdapterView parent, View v, int position, long id) { String s = lvLista.getItemAtPosition(position).toString(); Toast.makeText(this, s, Toast.LENGTH_SHORT).show(); }

10 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="${packageName}.${activityClass}" > <TextView android:id="@+id/t_escolha" android:layout_width="match_parent" android:layout_height="40dp" android:text="@string/escolha_o_sensor" android:textSize="32sp" /> <ListView android:id="@+id/lv_lista" android:layout_width="fill_parent" android:layout_height="match_parent" />

11 ListActivity Variante de Activity que exibe unicamente uma lista de Strings Usos mais comuns: com ArrayAdapter e CursorAdapter (para SqlLite) package de.vogella.android.listactivity; import android.app.ListActivity;.... public class MyListActivity extends ListActivity { String[] values = new String[] { "Android", "iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2" }; public void onCreate(Bundle bundle) { super.onCreate(bundle); ArrayAdapter adapter = new ArrayAdapter (this, android.R.layout.simple_list_item_1, values); setListAdapter(adapter); }

12 Contatos no Android, só parece, mas não é simples Há muitas nuances, e vamos começar pelo mais fácil: – Era uma vez um mundo calmo, com poucas coisas para atrapalhar, um mundo hoje obsoleto... – Eram poucas informações, e elas eram consistentes, provenientes de uma mesma fonte de geração. – Então as coisas começaram a ficar lentas... – Causa principal: queries realizados na UI thread

13 Não se pode acessar impunemente Os Contatos são guardados numa Base de dados de fora da aplicação: não podem ser abertos diretamente. Android fornece 2 classes para ajudar nisso: – ContentProvider provê uma abstração do SQLite database, controlando segurança e oferecendo uma interface padrão Existem apenas dois provedores de conteúdo no SDK do Android para os contactos: Contacts e ContactsContract – ContentResolver aceita solicitações de clientes, e resolve essas solicitações, direcionando-os para o provedor de conteúdo como uma “ponte autorizada”, permitindo uma forma simples e segura de acessar provedores de conteúdo de outros aplicativos.

14 Como se programava Incluir no manifest: <uses-permission android:name="android.permission.READ_CONTACTS" /> getContentResolver – ponte entre meu programa e o ContactsContract startManagingCursor(Cursor) – pedia ao sistema para gerenciar um cursor. Usar um CursorAdapter – para exibir. – Preenchido com as informações geradas por um Query

15 ContentResolver.query Cursor query ( Uri uri, // ContentProvider Uri String[] projection, // Columns to retrieve String selection, // SQL selection pattern String[] selectionArgs, // SQL pattern args String sortOrder // Sort order ) Retorna um Cursor para iteração sobre o conjunto de resultados

16 O que acontece numa Query? getContentResolver ().Query (Uri, String, String, String, String) Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) o ContentResolver analisa o argumento Uri e extrai a sua autoridade, e então direciona o pedido para o método de consulta do provedor de conteúdo registrado como essa autoridade (exclusivo). O Provedor de Conteúdo realiza a consulta e um cursor é retornado (ou uma exceção é lançada). Para uma mesma aplicação podem existir diversos ContentProvider que usam queries específicas e têm comportamentos distintos.

17 Cursor Adapter Android fornece duas classes de adaptador específicas para exibir dados de uma consulta de banco de dados SQLite: SimpleCursorAdapter – muito simples de usar. – Semelhante a um ArrayAdapter porque pode ser utilizado sem subclasses. Basta fornecer os parâmetros necessários (um cursor e informações de layout) no construtor e, em seguida, atribuir a um ListView. Cuidado, um dos construtores foi “deprecated”. CursorAdapter – alto desempenho – Controle mais detalhado da exibição – Mais difícil de usar

18 Programando, versão antiga… public class MainActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Cursor cur = getContentResolver().query(People.CONTENT_URI, null, null, null, null);// People está deprecated... startManagingCursor(cur);// Processamento na UI Thread ListAdapter adapter = new SimpleCursorAdapter( this, android.R.layout.simple_list_item_1, cur, new String[] {People.NAME}, // campos a exibir new int[] {android.R.id.text1}, // onde exibir 0);// flags setListAdapter(adapter); }

19 Hoje: usar ContactsContract Possui três camadas: Uma linha na tabela ContactsContract.Data pode armazenar qualquer tipo de dados pessoais, como um número de telefone ou endereços de email. – O conjunto de tipos de dados que podem ser armazenados nesta tabela fica em aberto. – Há um conjunto predefinido de tipos comuns, mas qualquer aplicativo pode adicionar seus próprios tipos de dados. Uma linha na tabela de ContactsContract.RawContacts representa um conjunto de dados que descrevem uma pessoa e associado a uma única conta – por exemplo, uma das contas de Gmail do usuário. Uma linha na tabela ContactsContract.Contacts representa um agregado de um ou mais RawContacts presumivelmente descrevem a mesma pessoa. – Quando os dados em ou associados com o quadro de RawContacts é alterada, os contatos agregados afetados são atualizados conforme necessário.

20 public class ContactsListExample extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ContentResolver cr = getContentResolver(); Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI, new String[] {ContactsContract.Contacts.DISPLAY_NAME}, null, null, null); List contacts = new ArrayList (); if (c.moveToFirst()) { do { contacts.add(c.getString(c.getColumnIndex (ContactsContract.Contacts.DISPLAY_NAME))); } while (c.moveToNext()); } ArrayAdapter adapter = new ArrayAdapter (this, R.layout.list_item, contacts); setListAdapter(adapter); }

21 Layout: list_item.xml <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent“ android:layout_height="fill_parent“ android:padding="10dp" android:textSize="16sp" >

22 Dicas de query para ContactsContract e outras informações http://www.app-solut.com/blog/2011/03/working- with-the-contactscontract-to-query-contacts-in- android/

23 E o que colocar na URI? – A URI irá variar de acordo com os requisitos de aplicação, em geral, contendo a “autoridade” com o nome da tabela de banco de dados, anexado ao final. Toda URI tem a forma content:// / / » Autority: nome do content provider ou qualificador completo. Ex.: content://contacts/people/5 Ex.: content://com.android.contacts/contacts/lookup/0r7-2C46 Muitas vezes, tem constantes pré-definidas – Ex: ContactsContract.Contacts.CONTENT_URI

24 Formatação específica com BaseAdapter Permite formatação diferenciada para os registros da listView A cada registro, o XML do modelo escolhido é inflado

25 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:background="#cccccc" android:orientation="horizontal"> <TextView android:id="@+id/textName" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:paddingLeft="5dp" android:text="Fulaninho de Tal" android:textColor="#333333" android:textSize="18sp" android:textStyle="bold" /> <TextView android:id="@+id/textPhoneNumber" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="9-9999-9999" android:textSize="18sp" android:textColor="#009900" android:paddingLeft="5dp" android:textStyle="bold" /> Manifest:

26 ... import android.provider.ContactsContract; public class MainActivity extends ListActivity { private contacts = new ArrayList (); @Override protected void onCreate (Bundle savedInstanceState){ super.onCreate (savedInstanceState); preenche_contacts(); setListAdapter (new ContactAdapter (MainActivity.this, contacts)); } private void preenche_contacts() { ContentResolver cr = getContentResolver(); Cursor cursor = cr.query (ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.DATA1 }, ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'", null, ContactsContract.Data.DISPLAY_NAME + " COLLATE NOCASE" );...

27 class Contact { private String name; private String phoneNumber; Contact (String name, String phoneNumber) { this.name = name; this.phoneNumber = phoneNumber; } String getName () { return name; } String getPhoneNumber () { return phoneNumber; }

28 class ContactAdapter extends BaseAdapter { private Context context; private List contacts; ContactAdapter (Context context, List contacts) { this.context= context; this.contacts = contacts; } @Override public int getCount () { return contacts.size(); } @Override public Object getItem (int position) { return contacts.get (position); } @Override public long getItemId (int position) { return position; }...

29 @Override public View getView (int position, View convertView, ViewGroup parent) { Contact contact = contacts.get (position); LayoutInflater inflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate (R.layout.contact, null); String name = contact.getName(); TextView textName = (TextView)view.findViewById (R.id.textName); textName.setTextColor (Color.BLUE); textName.setText (name); TextView textPhoneNumber = (TextView)view.findViewById (R.id.textPhoneNumber); textPhoneNumber.setTextColor (Color.RED); textPhoneNumber.setText (contact.getPhoneNumber()); return view; }

30 A questão do desempenho Problema maior: não se pode computar na UI Android 3.0 introduziu as classes: – Loader – LoaderManager O Loader garante que todas as operações do cursor sejam feitas de forma assíncrona, eliminando assim a possibilidade de bloquear a aplicação. – Usa uma AsyncTack O Loader monitora a fonte de dados subjacente para atualizações, re- examinando automaticamente quando os dados são alterados. Quando administrado pelo LoaderManager, um Loader retém seus dados de cursor quando uma reconfiguração ocorre (por exemplo, girar o celular).

31 Programando com Cursor Loader Implemente a interface LoaderManager.LoaderCallbacks Crie e inicialize um Cursor Loader Loader initLoader( int id, Bundle args, LoaderCallbacks callback)

32 Implemente (@Override) 3 callbacks onCreateLoader (int id, Bundle args) – Chamado para instanciar e retornar um novo Loader para esta ID especificada onLoadFinished(Loader loader, D data) – Chamada quando o Loader terminar de carregar onLoaderReset (Loader loader) – Chamado quando o Loader for resetado.

33 Exemplos ContentProviderWithCursorLoader Pegue em http://intervox.nce.ufrj.br/~antonio2/ Outros exemplos: Veja no site do Oswaldo http://intervox.nce.ufrj.br/~oswaldo/android

34 Outros métodos dos ContentResolver int delete (Uri url, String where, String[] selectArgs) – Retorna o número de linhas removidas Uri insert (Uri url, ContentValues values) – Retorna a Uri da linha inserida int update(Uri url, ContentValues values, String where, String[] selectionArgs) – Retorna o número de linhas atualizadas

35 Exemplo Veja nos fontes distribuídos: – ContentProviderInsertContacts

36 Sugestões de leitura Criação de um contact provider http://developer.android.com/guide/topics/provide rs/content-provider-creating.html – Foi distribuído um fonte com um pequeno exemplo de provedor e respectivo cliente.


Carregar ppt "Manipulando contatos no Android Por José Antonio Borges."

Apresentações semelhantes


Anúncios Google