Android
ContentProvider
Zoeken…
Opmerkingen
Contentproviders beheren toegang tot een gestructureerde set gegevens. Ze bevatten de gegevens en bieden mechanismen voor het definiëren van gegevensbeveiliging. Inhoudsproviders zijn de standaardinterface die gegevens in het ene proces verbindt met code die in een ander proces wordt uitgevoerd.
Wanneer u toegang wilt tot gegevens in een inhoudsprovider, gebruikt u het ContentResolver
object in de Context
van uw toepassing om met de provider te communiceren als een client. Het ContentResolver
object communiceert met het providerobject, een instantie van een klasse die ContentProvider
implementeert. Het providerobject ontvangt gegevensverzoeken van clients, voert de gevraagde actie uit en retourneert de resultaten.
U hoeft uw eigen provider niet te ontwikkelen als u niet van plan bent uw gegevens met andere applicaties te delen. U heeft echter wel uw eigen provider nodig om aangepaste zoeksuggesties te geven in uw eigen applicatie. U hebt ook uw eigen provider nodig als u complexe gegevens of bestanden van uw toepassing naar andere toepassingen wilt kopiëren en plakken.
Android zelf omvat contentproviders die gegevens beheren zoals audio, video, afbeeldingen en persoonlijke contactinformatie. U kunt een aantal daarvan zien in de referentiedocumentatie voor het android.provider
pakket. Met enkele beperkingen zijn deze providers toegankelijk voor elke Android-applicatie.
Implementeren van een basisclassificatieprovider
1) Creëer een contractklasse
Een contractklasse definieert constanten die toepassingen helpen werken met de inhoud-URI's, kolomnamen, intentie-acties en andere functies van een inhoudprovider. Contractklassen worden niet automatisch opgenomen bij een aanbieder; de ontwikkelaar van de provider moet deze definiëren en vervolgens beschikbaar maken voor andere ontwikkelaars.
Een provider heeft meestal een enkele autoriteit, die dient als interne naam voor Android. Gebruik een unieke contentautoriteit om conflicten met andere providers te voorkomen. Omdat deze aanbeveling ook geldt voor Android-pakketnamen, kunt u de machtiging van uw provider definiëren als een uitbreiding van de naam van het pakket met de provider. Als uw Android-pakketnaam bijvoorbeeld com.example.appname
, moet u uw provider de autoriteit com.example.appname.provider
.
public class MyContract {
public static final String CONTENT_AUTHORITY = "com.example.myApp";
public static final String PATH_DATATABLE = "dataTable";
public static final String TABLE_NAME = "dataTable";
}
Een content-URI is een URI die gegevens in een provider identificeert. Inhoud-URI's bevatten de symbolische naam van de hele provider (de autoriteit ervan) en een naam die verwijst naar een tabel of bestand (een pad). Het optionele id-gedeelte verwijst naar een afzonderlijke rij in een tabel. Elke gegevenstoegangsmethode van ContentProvider heeft een inhoud-URI als argument; hiermee kunt u de toegang tot de tabel, rij of het bestand bepalen. Definieer deze in de contractklasse.
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DATATABLE).build();
// define all columns of table and common functions required
2) Maak de Helper Class
Een helperklasse beheert het maken van databases en versiebeheer.
public class DatabaseHelper extends SQLiteOpenHelper {
// Increment the version when there is a change in the structure of database
public static final int DATABASE_VERSION = 1;
// The name of the database in the filesystem, you can choose this to be anything
public static final String DATABASE_NAME = "weather.db";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// Called when the database is created for the first time. This is where the
// creation of tables and the initial population of the tables should happen.
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Called when the database needs to be upgraded. The implementation
// should use this method to drop tables, add tables, or do anything else it
// needs to upgrade to the new schema version.
}
}
3) Maak een klasse die de ContentProvider-klasse uitbreidt
public class MyProvider extends ContentProvider {
public DatabaseHelper dbHelper;
public static final UriMatcher matcher = buildUriMatcher();
public static final int DATA_TABLE = 100;
public static final int DATA_TABLE_DATE = 101;
Een UriMatcher wijst een autoriteit en pad toe aan een geheel getal. De methode match()
retourneert een unieke gehele waarde voor een URI (dit kan elk willekeurig getal zijn, zolang het uniek is). Een schakelinstructie kiest tussen het doorzoeken van de hele tabel en het doorzoeken van een enkel record. Onze UriMatcher retourneert 100 als de URI de inhoud-URI van tabel is en 101 als de URI naar een specifieke rij in die tabel verwijst. U kunt het jokerteken #
om te matchen met elk nummer en *
om te matchen met elke string.
public static UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE, DATA_TABLE);
uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE + "/#", DATA_TABLE_DATE);
return uriMatcher;
}
BELANGRIJK: het bestellen van addURI()
roept op! De UriMatcher ziet er in opeenvolgende volgorde vanaf de eerste toegevoegd tot de laatste. Omdat jokertekens zoals #
en *
hebzuchtig zijn, moet u ervoor zorgen dat u uw URI's correct hebt besteld. Bijvoorbeeld:
uriMatcher.addURI(CONTENT_AUTHORITY, "/example", 1);
uriMatcher.addURI(CONTENT_AUTHORITY, "/*", 2);
is de juiste volgorde, omdat de matcher eerst naar /example
zal zoeken voordat hij zijn toevlucht neemt tot de /*
match. Als deze methode-aanroepen waren teruggedraaid en je uriMatcher.match("/example")
gebeld, zal de UriMatcher stoppen met zoeken naar wedstrijden zodra het het pad /*
tegenkomt en het verkeerde resultaat retourneren!
U moet dan deze functies overschrijven:
onCreate () : initialiseer uw provider. Het Android-systeem roept deze methode onmiddellijk aan nadat deze uw provider heeft gemaakt. Merk op dat uw provider niet is gemaakt totdat een ContentResolver-object toegang probeert te krijgen.
@Override
public boolean onCreate() {
dbhelper = new DatabaseHelper(getContext());
return true;
}
getType () : Retourneer het MIME-type dat overeenkomt met een inhoud-URI
@Override
public String getType(Uri uri) {
final int match = matcher.match(uri);
switch (match) {
case DATA_TABLE:
return ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + MyContract.CONTENT_AUTHORITY + "/" + MyContract.PATH_DATATABLE;
case DATA_TABLE_DATE:
return ContentResolver.ANY_CURSOR_ITEM_TYPE + "/" + MyContract.CONTENT_AUTHORITY + "/" + MyContract.PATH_DATATABLE;
default:
throw new UnsupportedOperationException("Unknown Uri: " + uri);
}
}
query () : gegevens ophalen van uw provider. Gebruik de argumenten om de tabel te selecteren die moet worden opgevraagd, de rijen en kolommen die moeten worden geretourneerd en de sorteervolgorde van het resultaat. Retourneer de gegevens als een cursorobject.
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor retCursor = dbHelper.getReadableDatabase().query(
MyContract.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
Voeg een nieuwe rij in uw provider in. Gebruik de argumenten om de doeltabel te selecteren en de te gebruiken kolomwaarden te verkrijgen. Retourneer een inhoud-URI voor de nieuw ingevoegde rij.
@Override
public Uri insert(Uri uri, ContentValues values)
{
final SQLiteDatabase db = dbHelper.getWritableDatabase();
long id = db.insert(MyContract.TABLE_NAME, null, values);
return ContentUris.withAppendedId(MyContract.CONTENT_URI, ID);
}
delete () : rijen verwijderen van uw provider. Gebruik de argumenten om de tabel en de te verwijderen rijen te selecteren. Retourneer het aantal verwijderde rijen.
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsDeleted = db.delete(MyContract.TABLE_NAME, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
update () : update bestaande rijen in uw provider. Gebruik de argumenten om de bij te werken tabel en rijen te selecteren en om de nieuwe kolomwaarden op te halen. Retourneer het aantal bijgewerkte rijen.
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsUpdated = db.update(MyContract.TABLE_NAME, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
4) Update manifestbestand
<provider
android:authorities="com.example.myApp"
android:name=".DatabaseProvider"/>