Android
ContentProvider
Sök…
Anmärkningar
Innehållsleverantörer hanterar åtkomst till en strukturerad uppsättning data. De kapslar in data och tillhandahåller mekanismer för att definiera datasäkerhet. Innehållsleverantörer är standardgränssnittet som ansluter data i en process med kod som körs i en annan process.
När du vill få åtkomst till data i en innehållsleverantör använder du ContentResolver
objektet i applikationens Context
att kommunicera med leverantören som klient. ContentResolver
objektet kommunicerar med leverantörsobjektet, en instans av en klass som implementerar ContentProvider
. Leverantörsobjektet tar emot dataförfrågningar från klienter, utför den begärda åtgärden och returnerar resultaten.
Du behöver inte utveckla din egen leverantör om du inte tänker dela dina data med andra applikationer. Du behöver dock din egen leverantör för att tillhandahålla anpassade sökförslag i din egen applikation. Du behöver också din egen leverantör om du vill kopiera och klistra in komplexa data eller filer från din applikation till andra applikationer.
Android själv innehåller innehållsleverantörer som hanterar data som ljud, video, bilder och personlig kontaktinformation. Du kan se några av dem i referensdokumentationen för android.provider
paketet. Med vissa begränsningar är dessa leverantörer tillgängliga för alla Android-applikationer.
Implementera en grundläggande innehållsleverantörsklass
1) Skapa en kontraktsklass
En kontraktsklass definierar konstanter som hjälper applikationer att arbeta med innehålls-URI: er, kolumnnamn, avsiktshandlingar och andra funktioner hos en innehållsleverantör. Avtalsklasser ingår inte automatiskt hos en leverantör; leverantörens utvecklare måste definiera dem och sedan göra dem tillgängliga för andra utvecklare.
En leverantör har vanligtvis en enda myndighet som fungerar som sitt Android-interna namn. Använd en unik innehållsmyndighet för att undvika konflikter med andra leverantörer. Eftersom denna rekommendation också gäller för Android-paketnamn, kan du definiera din leverantörsbehörighet som en förlängning av namnet på paketet som innehåller leverantören. Om ditt Android-paketnamn till exempel är com.example.appname
, bör du ge din leverantör behörigheten 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";
}
En innehålls-URI är en URI som identifierar data i en leverantör. Innehålls-URI: er inkluderar det symboliska namnet på hela leverantören (dess myndighet) och ett namn som pekar på en tabell eller fil (en sökväg). Den valfria ID-delen pekar på en enskild rad i en tabell. Varje datatillgångsmetod för ContentProvider har en innehålls-URI som ett argument; Detta gör att du kan bestämma tabellen, raden eller filen för åtkomst. Definiera dessa i kontraktsklassen.
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) Skapa Helper Class
En hjälparklass hanterar databasskapande och versionhantering.
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) Skapa en klass som utvidgar ContentProvider-klassen
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;
En UriMatcher kartlägger en myndighet och sökväg till ett heltalvärde. Metodmatchningen match()
returnerar ett unikt heltal för en URI (det kan vara valfritt valfritt antal, så länge det är unikt). Ett switch-uttalande väljer mellan fråga hela tabellen och fråga efter en enda post. Vår UriMatcher returnerar 100 om URI är innehålls-URI för tabell och 101 om URI pekar på en specifik rad i tabellen. Du kan använda #
jokertecken för att matcha med valfritt nummer och *
att matcha med valfri sträng.
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;
}
VIKTIGT: beställning av addURI()
kallar frågor! UriMatcher kommer att se i sekvensordning från första tillagd till sist. Eftersom jokertecken som #
och *
är giriga, måste du se till att du har beställt dina URI: er korrekt. Till exempel:
uriMatcher.addURI(CONTENT_AUTHORITY, "/example", 1);
uriMatcher.addURI(CONTENT_AUTHORITY, "/*", 2);
är rätt beställning, eftersom matcharen kommer att leta efter /example
först innan han använder sig till /*
-matchen. Om dessa uriMatcher.match("/example")
vändes och du ringde uriMatcher.match("/example")
, kommer UriMatcher att sluta leta efter matchningar när den möter sökvägen /*
och returnerar fel resultat!
Du måste då åsidosätta dessa funktioner:
onCreate () : Initiera din leverantör. Android-systemet anropar denna metod omedelbart efter det att din leverantör skapats. Lägg märke till att din leverantör inte skapas förrän ett ContentResolver-objekt försöker komma åt det.
@Override
public boolean onCreate() {
dbhelper = new DatabaseHelper(getContext());
return true;
}
getType () : Returnera MIME-typen som motsvarar en innehålls-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);
}
}
fråga () : Hämta data från din leverantör. Använd argumenten för att välja tabellen att fråga, raderna och kolumnerna som ska returneras och sorteringsordningen för resultatet. Returnera data som ett markörobjekt.
@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;
}
Sätt in en ny rad i din leverantör. Använd argumenten för att välja destinationstabellen och få kolumnvärden att använda. Returnera en innehålls-URI för den nyinförda raden.
@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);
}
radera () : Radera rader från din leverantör. Använd argumenten för att välja tabellen och raderna för att radera. Returnera antalet rader som har tagits bort.
@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;
}
uppdatering () : Uppdatera befintliga rader i din leverantör. Använd argumenten för att välja tabell och rader för att uppdatera och för att få de nya kolumnvärdena. Returnera antalet rader uppdaterade.
@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) Uppdatera manifestfil
<provider
android:authorities="com.example.myApp"
android:name=".DatabaseProvider"/>