Usando Content Provider em Memória Secundária e Primária – Parte 1
Content Provider é uma interface que pode ser utilizada para encapsular recursos de armazenamento de dados. Ao usar herança da classe de Content Provider os dados podem ser compartilhados entre aplicações diferentes. É por isso que no sistema Android podemos facilmente acessar mensagens recebidas ou ler os dados de um contato na agenda. Usualmente programadores decidem armazenar seus dados em Content Providers que acessam memória secundária, tais como banco de dados (Podemos citar o SQLite que vem nativo no Android), arquivos texto, entre outros. Algumas situações podem demandar uso de Content Provider em memória primária. Em especial podemos citar aplicações em tempo real nas quais dependendo dos requisitos de tempo, o acesso à memória secundária pode ser gargalo no sistema. Neste caso, pode ser indicado o uso de memória primária ao invés de secundária para armazenamento dos dados. A desvantagem dessa abordagem é se a aplicação em questão demanda persistência em memória secundária, já que os dados podem ser perdidos em caso de desligamento do sistema. Ainda deve ser levando em consideração que dispositivos móveis podem ser considerados como escassos em poder de processamento e memória. Nesse artigo mostraremos como criar um Content Provider em memória secundária usando o Banco SQLite nativo no Android. Na segunda parte mostraremos como construir um Content Provider usando memória primária. A interface de Content Provider demanda implementação de alguns métodos, onde alguns deles destacamos:
- query(Uri, String[], String, String[], String)- usado para recuperar dados.
- insert(Uri, ContentValues) – usado para inserir dados.
- update(Uri, ContentValues, String, String[]) – usado para atualizar dados.
- delete(Uri, String, String[]) – usado para deletar dados.
Observe que o parâmetro URI está presente em todos os métodos. Uma URI é o que determina identidade de um provedor de dados. Por exemplo, a URI “content://sms/inbox” pode ser usada para acessar as mensagens contidas no inbox do dispositivo.
Classe de Banco de dados
A classe de Banco de dados deve herdar a classe SQLiteOpenHelper e os métodos onCreate() e onUpgrade() devem ser chamados. Na primeira vez que essa classe é executada (após a instalação do aplicativo) o método onCreate() é chamado. Sua implementação consiste em criar o banco de dados. Em caso de reinstalação do aplicativo o método onUpgrade() é chamado. Nessa implementação, decidiu-se eliminar o banco de dados já existente.
A listagem 1 mostra a implementação da classe.
[sourcecode language=”java”]
public class ImobilisDataBase extends SQLiteOpenHelper {
public ImobilisDataBase(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
private static final String TAG = "TutListDatabase";
private static final int DB_VERSION = 1;
private static final String DB_NAME = "imobilis_data";
public static final String TABLE_CONTACTS = "contact_mail";
public static final String ID = "_id";
public static final String COL_NAME = "name";
public static final String COL_MAIL = "mail";
private static final String CREATE_TABLE_TUTORIALS = "create table " + TABLE_CONTACTS
+ " (" + ID + " integer primary key autoincrement, " + COL_NAME
+ " text not null, " + COL_MAIL + " text not null);";
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_TUTORIALS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
onCreate(db);
}
}
[/sourcecode]
Essa classe contém atributos com propriedades de banco e da tabela que está sendo usada. A tabela chama-se “contact_mail” e possui “_id”, “name” e “mail” como atributos.
Classe Content Provider
Essa classe deverá herdar Content Provider e implementar os métodos conforme mencionado anteriormente. O principais atributos dessa classe são “mDB” do tipo ImobilisDataBase no qual corresponde ao objeto de manipulação do banco. Uma String “AUTHORITY” usada para formação da URI e outra String “CONTENT_BASE_PATH” na qual irá definir o caminho da tabela.
A listagem 2 mostra a implementação da classe.
[sourcecode language=”java”]</pre>
public class ImobilisContentProvider extends ContentProvider{
private ImobilisDataBase mDB;
private static final String AUTHORITY = "com.example.imobiliscontentprovider";
private static final String CONTACTS_BASE_PATH = "contacts";
public static final int CONTACTS_CODE = CONTACTS_BASE_PATH.hashCode();
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + CONTACTS_BASE_PATH);
private static final UriMatcher sURIMatcher = new UriMatcher(
UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, CONTACTS_BASE_PATH, CONTACTS_CODE);
}
@Override
public boolean onCreate() {
mDB = new ImobilisDataBase(getContext());
return true;
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mDB.getWritableDatabase();
int count = db.delete(ImobilisDataBase.TABLE_CONTACTS, where, whereArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (sURIMatcher.match(uri) != CONTACTS_CODE) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
SQLiteDatabase db = mDB.getWritableDatabase();
long rowId = db.insert(mDB.TABLE_CONTACTS, ImobilisDataBase.COL_NAME, values);
if (rowId > 0) {
Uri uriContact = ContentUris.withAppendedId(CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(uriContact, null);
return uriContact;
}
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(ImobilisDataBase.TABLE_CONTACTS);
queryBuilder.appendWhere(ImobilisDataBase.ID + "="
+ uri.getLastPathSegment());
Cursor cursor = queryBuilder.query(mDB.getReadableDatabase(),
projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
}
<pre>[/sourcecode]
Por fim é necessário declarar o provider criado no manifiest da aplicação
[sourcecode language=”xml”]</pre>
<provider android:name=<em>"com.example.imobiliscontentprovider.contentprovider"</em> android:authorities=<em>" com.example.imobiliscontentprovider.contentprovider"</em> />
<pre>[/sourcecode]
Conclusão Neste artigo mostramos como criar um Content Provider no Android para persistência em banco de dados usando SQLite. No próximo artigo mostraremos como fazer um Content Provider para armazenar dados em memória primária.