Android
Dostawca treści
Szukaj…
Uwagi
Dostawcy treści zarządzają dostępem do uporządkowanego zestawu danych. Otaczają dane i zapewniają mechanizmy definiowania bezpieczeństwa danych. Dostawcy treści to standardowy interfejs, który łączy dane w jednym procesie z kodem uruchomionym w innym procesie.
Jeśli chcesz uzyskać dostęp do danych w dostawcy treści, możesz użyć obiektu ContentResolver
w Context
aplikacji do komunikacji z dostawcą jako klientem. Obiekt ContentResolver
komunikuje się z obiektem dostawcy, instancją klasy, która implementuje ContentProvider
. Obiekt dostawcy odbiera żądania danych od klientów, wykonuje żądane działanie i zwraca wyniki.
Nie musisz rozwijać własnego dostawcy, jeśli nie zamierzasz udostępniać swoich danych innym aplikacjom. Jednak potrzebujesz własnego dostawcy, aby dostarczyć niestandardowe sugestie wyszukiwania we własnej aplikacji. Potrzebujesz także własnego dostawcy, jeśli chcesz kopiować i wklejać złożone dane lub pliki z aplikacji do innych aplikacji.
Sam Android obejmuje dostawców treści, którzy zarządzają danymi, takimi jak audio, wideo, obrazy i osobiste informacje kontaktowe. Niektóre z nich można znaleźć w dokumentacji referencyjnej pakietu android.provider
. Z pewnymi ograniczeniami dostawcy ci są dostępni dla dowolnej aplikacji na Androida.
Implementowanie podstawowej klasy dostawcy treści
1) Utwórz klasę kontraktu
Klasa kontraktu definiuje stałe, które pomagają aplikacjom pracować z identyfikatorami URI treści, nazwami kolumn, celowymi działaniami i innymi funkcjami dostawcy treści. Klasy umów nie są automatycznie uwzględniane u dostawcy; deweloper dostawcy musi je zdefiniować, a następnie udostępnić innym deweloperom.
Dostawca zwykle ma jeden organ, który służy jako wewnętrzna nazwa systemu Android. Aby uniknąć konfliktów z innymi dostawcami, użyj unikalnego organu ds. Treści. Ponieważ to zalecenie dotyczy również nazw pakietów Androida, możesz zdefiniować swoje uprawnienia dostawcy jako rozszerzenie nazwy pakietu zawierającego dostawcę. Na przykład, jeśli nazwa pakietu Androida to com.example.appname
, należy nadać swojemu dostawcy uprawnienia 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";
}
Identyfikator URI to identyfikator URI, który identyfikuje dane w dostawcy. Identyfikatory URI treści obejmują symboliczną nazwę całego dostawcy (jego uprawnienia) oraz nazwę wskazującą tabelę lub plik (ścieżkę). Opcjonalna część id wskazuje na pojedynczy wiersz w tabeli. Każda metoda dostępu do danych ContentProvider ma argument URI treści jako argument; pozwala to określić tabelę, wiersz lub plik, do którego chcesz uzyskać dostęp. Zdefiniuj je w klasie kontraktowej.
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) Utwórz klasę pomocnika
Klasa pomocnicza zarządza tworzeniem bazy danych i zarządzaniem wersjami.
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) Utwórz klasę, która rozszerza klasę ContentProvider
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;
UriMatcher mapuje uprawnienie i ścieżkę na wartość całkowitą. Metoda match()
zwraca unikalną wartość całkowitą dla identyfikatora URI (może to być dowolna liczba, o ile jest unikalna). Instrukcja switch wybiera między odpytywaniem całej tabeli a zapytaniem o pojedynczy rekord. Nasz UriMatcher zwraca 100, jeśli URI jest URI treści tabeli, a 101, jeśli URI wskazuje na konkretny wiersz w tej tabeli. Możesz użyć znaku wieloznacznego #
aby dopasować dowolny numer, a *
aby dopasować dowolny ciąg.
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;
}
WAŻNE: kolejność addURI()
ma znaczenie! UriMatcher będzie wyglądał w kolejności sekwencyjnej od pierwszego dodania do ostatniego. Ponieważ symbole wieloznaczne, takie jak #
i *
są zachłanne, musisz upewnić się, że poprawnie zamówiłeś swoje URI. Na przykład:
uriMatcher.addURI(CONTENT_AUTHORITY, "/example", 1);
uriMatcher.addURI(CONTENT_AUTHORITY, "/*", 2);
jest prawidłowe uporządkowanie, ponieważ dopasowujący najpierw szuka /example
przed uciekaniem się do dopasowania /*
. Jeśli te wywołania metod zostały odwrócone, a ty uriMatcher.match("/example")
, to UriMatcher przestanie szukać dopasowań, gdy napotka ścieżkę /*
i zwróci zły wynik!
Będziesz wtedy musiał zastąpić te funkcje:
onCreate () : Zainicjuj swojego dostawcę. System Android wywołuje tę metodę natychmiast po utworzeniu dostawcy. Zauważ, że twój dostawca nie jest tworzony, dopóki obiekt ContentResolver nie spróbuje uzyskać do niego dostępu.
@Override
public boolean onCreate() {
dbhelper = new DatabaseHelper(getContext());
return true;
}
getType () : Zwraca typ MIME odpowiadający identyfikatorowi URI treści
@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 () : pobierz dane od swojego dostawcy. Użyj argumentów, aby wybrać tabelę do zapytania, wiersze i kolumny do zwrócenia oraz kolejność sortowania wyniku. Zwróć dane jako obiekt kursora.
@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;
}
Wstaw nowy wiersz do swojego dostawcy. Użyj argumentów, aby wybrać tabelę docelową i uzyskać wartości kolumn do użycia. Zwraca identyfikator URI treści dla nowo wstawionego wiersza.
@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 () : Usuń wiersze od swojego dostawcy. Użyj argumentów, aby wybrać tabelę i wiersze do usunięcia. Zwraca liczbę usuniętych wierszy.
@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 () : Zaktualizuj istniejące wiersze u swojego dostawcy. Użyj argumentów, aby wybrać tabelę i wiersze do zaktualizowania i uzyskać nowe wartości kolumn. Zwraca liczbę zaktualizowanych wierszy.
@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) Zaktualizuj plik manifestu
<provider
android:authorities="com.example.myApp"
android:name=".DatabaseProvider"/>