Membuat penyedia konten stub
Tetap teratur dengan koleksi
Simpan dan kategorikan konten berdasarkan preferensi Anda.
Framework adaptor sinkronisasi didesain untuk bekerja dengan data perangkat yang dikelola oleh
penyedia konten yang sangat aman. Karena alasan ini, framework adaptor
sinkronisasi mengharapkan
bahwa aplikasi yang menggunakan kerangka kerja sudah mendefinisikan penyedia konten untuk data lokalnya.
Jika framework adaptor sinkronisasi mencoba menjalankan adaptor sinkronisasi, dan aplikasi Anda tidak memiliki
penyedia konten, adaptor sinkronisasi
Anda akan macet.
Jika Anda mengembangkan aplikasi baru yang mentransfer data dari server ke perangkat, Anda harus
sebaiknya simpan data lokal dalam penyedia konten. Selain peran penting
mereka untuk
adaptor sinkronisasi, penyedia konten menawarkan
berbagai manfaat keamanan dan secara khusus
dirancang untuk menangani penyimpanan
data pada sistem Android. Untuk mempelajari lebih lanjut cara membuat konten
penyedia konten, lihat Membuat Penyedia Konten.
Namun, jika Anda sudah menyimpan data lokal dalam bentuk lain, Anda masih dapat menggunakan
untuk menangani transfer data. Untuk memenuhi persyaratan framework adaptor sinkronisasi untuk
penyedia konten, tambahkan penyedia konten stub ke aplikasi Anda. Penyedia stub menerapkan
class penyedia konten, tetapi semua metode yang diperlukan akan menampilkan null
atau 0
. Jika Anda
menambahkan penyedia stub, Anda kemudian dapat menggunakan
adaptor sinkronisasi untuk mentransfer data dari penyimpanan mana pun
mekanisme yang Anda pilih.
Jika sudah memiliki penyedia konten di aplikasi, Anda tidak memerlukan penyedia konten stub.
Jika demikian, Anda dapat melewati pelajaran ini dan melanjutkan ke pelajaran
Membuat Adaptor Sinkronisasi. Jika Anda belum memiliki
penyedia konten, pelajaran ini menunjukkan cara menambahkan penyedia konten stub yang memungkinkan Anda
menyambungkan adaptor sinkronisasi Anda ke dalam kerangka kerja.
Menambahkan penyedia konten stub
Untuk membuat penyedia konten stub bagi aplikasi Anda, perluas class
ContentProvider
dan menghentikan metode yang diperlukan. Hal berikut
cuplikan ini menunjukkan cara membuat penyedia stub:
Kotlin
/*
* Define an implementation of ContentProvider that stubs out
* all methods
*/
class StubProvider : ContentProvider() {
/*
* Always return true, indicating that the
* provider loaded correctly.
*/
override fun onCreate(): Boolean = true
/*
* Return no type for MIME type
*/
override fun getType(uri: Uri): String? = null
/*
* query() always returns no results
*
*/
override fun query(
uri: Uri,
projection: Array<String>,
selection: String,
selectionArgs: Array<String>,
sortOrder: String
): Cursor? = null
/*
* insert() always returns null (no URI)
*/
override fun insert(uri: Uri, values: ContentValues): Uri? = null
/*
* delete() always returns "no rows affected" (0)
*/
override fun delete(uri: Uri, selection: String, selectionArgs: Array<String>): Int = 0
/*
* update() always returns "no rows affected" (0)
*/
override fun update(
uri: Uri,
values: ContentValues,
selection: String,
selectionArgs: Array<String>
): Int = 0
}
Java
/*
* Define an implementation of ContentProvider that stubs out
* all methods
*/
public class StubProvider extends ContentProvider {
/*
* Always return true, indicating that the
* provider loaded correctly.
*/
@Override
public boolean onCreate() {
return true;
}
/*
* Return no type for MIME type
*/
@Override
public String getType(Uri uri) {
return null;
}
/*
* query() always returns no results
*
*/
@Override
public Cursor query(
Uri uri,
String[] projection,
String selection,
String[] selectionArgs,
String sortOrder) {
return null;
}
/*
* insert() always returns null (no URI)
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
/*
* delete() always returns "no rows affected" (0)
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
/*
* update() always returns "no rows affected" (0)
*/
public int update(
Uri uri,
ContentValues values,
String selection,
String[] selectionArgs) {
return 0;
}
}
Mendeklarasikan penyedia di manifes
Framework adaptor sinkronisasi memastikan bahwa aplikasi Anda memiliki penyedia konten dengan memeriksa bahwa
aplikasi telah mendeklarasikan penyedia dalam manifes aplikasinya. Untuk mendeklarasikan penyedia stub dalam
tambahkan elemen <provider>
dengan atribut berikut:
-
android:name="com.example.android.datasync.provider.StubProvider"
-
Menentukan nama class yang sepenuhnya memenuhi syarat yang menerapkan penyedia konten stub.
-
android:authorities="com.example.android.datasync.provider"
-
Otoritas URI yang mengidentifikasi penyedia konten stub. Jadikan nilai ini milik aplikasi Anda
nama paket dengan string ".provider" ditambahkan ke dalamnya. Meskipun Anda mendeklarasikan
penyedia stub ke sistem, tidak ada yang mencoba
mengakses penyedia itu sendiri.
-
android:exported="false"
-
Menentukan apakah aplikasi lain dapat mengakses penyedia konten. Untuk konten stub Anda
penyedia, setel nilai ke
false
, karena tidak perlu mengizinkan aplikasi lain untuk melihat
penyedia. Nilai ini tidak memengaruhi interaksi antara framework adaptor sinkronisasi
dan penyedia konten.
-
android:syncable="true"
-
Menetapkan tanda yang menunjukkan bahwa penyedia dapat disinkronkan. Jika Anda mengatur penanda ini ke
true
, Anda tidak perlu memanggil setIsSyncable()
dalam kode Anda. Flag tersebut memungkinkan framework adaptor sinkronisasi membuat data
transfer dengan penyedia konten, namun transfer
hanya terjadi jika Anda melakukannya secara eksplisit.
Cuplikan berikut menunjukkan cara menambahkan atribut
<provider>
ke manifes aplikasi:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.network.sync.BasicSyncAdapter"
android:versionCode="1"
android:versionName="1.0" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
...
<provider
android:name="com.example.android.datasync.provider.StubProvider"
android:authorities="com.example.android.datasync.provider"
android:exported="false"
android:syncable="true"/>
...
</application>
</manifest>
Setelah membuat dependensi yang diperlukan oleh framework adaptor sinkronisasi, Anda bisa
buat komponen yang
mengenkapsulasi kode transfer data Anda. Komponen ini disebut
{i>synchronize<i}. Tutorial berikutnya akan menjelaskan cara menambahkan komponen ini ke aplikasi Anda.
Konten dan contoh kode di halaman ini tunduk kepada lisensi yang dijelaskan dalam Lisensi Konten. Java dan OpenJDK adalah merek dagang atau merek dagang terdaftar dari Oracle dan/atau afiliasinya.
Terakhir diperbarui pada 2025-07-27 UTC.
[[["Mudah dipahami","easyToUnderstand","thumb-up"],["Memecahkan masalah saya","solvedMyProblem","thumb-up"],["Lainnya","otherUp","thumb-up"]],[["Informasi yang saya butuhkan tidak ada","missingTheInformationINeed","thumb-down"],["Terlalu rumit/langkahnya terlalu banyak","tooComplicatedTooManySteps","thumb-down"],["Sudah usang","outOfDate","thumb-down"],["Masalah terjemahan","translationIssue","thumb-down"],["Masalah kode / contoh","samplesCodeIssue","thumb-down"],["Lainnya","otherDown","thumb-down"]],["Terakhir diperbarui pada 2025-07-27 UTC."],[],[],null,["# Create a stub content provider\n\nThe sync adapter framework is designed to work with device data managed by the flexible and\nhighly secure content provider framework. For this reason, the sync adapter framework expects\nthat an app that uses the framework has already defined a content provider for its local data.\nIf the sync adapter framework tries to run your sync adapter, and your app doesn't have a\ncontent provider, your sync adapter crashes.\n\n\nIf you're developing a new app that transfers data from a server to the device, you should\nstrongly consider storing the local data in a content provider. Besides their importance for\nsync adapters, content providers offer a variety of security benefits and are specifically\ndesigned to handle data storage on Android systems. To learn more about creating a content\nprovider, see [Creating a Content Provider](/guide/topics/providers/content-provider-creating).\n\n\nHowever, if you're already storing local data in another form, you can still use a sync\nadapter to handle data transfer. To satisfy the sync adapter framework requirement for a\ncontent provider, add a stub content provider to your app. A stub provider implements the\ncontent provider class, but all of its required methods return `null` or `0`. If you\nadd a stub provider, you can then use a sync adapter to transfer data from any storage\nmechanism you choose.\n\n\nIf you already have a content provider in your app, you don't need a stub content provider.\nIn that case, you can skip this lesson and proceed to the lesson\n[Creating a Sync Adapter](/training/sync-adapters/creating-sync-adapter). If you don't yet have a\ncontent provider, this lesson shows you how to add a stub content provider that allows you to\nplug your sync adapter into the framework.\n\nAdd a stub content provider\n---------------------------\n\n\nTo create a stub content provider for your app, extend the class\n[ContentProvider](/reference/android/content/ContentProvider) and stub out its required methods. The following\nsnippet shows you how to create the stub provider: \n\n### Kotlin\n\n```kotlin\n/*\n * Define an implementation of ContentProvider that stubs out\n * all methods\n */\nclass StubProvider : ContentProvider() {\n /*\n * Always return true, indicating that the\n * provider loaded correctly.\n */\n override fun onCreate(): Boolean = true\n\n /*\n * Return no type for MIME type\n */\n override fun getType(uri: Uri): String? = null\n\n /*\n * query() always returns no results\n *\n */\n override fun query(\n uri: Uri,\n projection: Array\u003cString\u003e,\n selection: String,\n selectionArgs: Array\u003cString\u003e,\n sortOrder: String\n ): Cursor? = null\n\n /*\n * insert() always returns null (no URI)\n */\n override fun insert(uri: Uri, values: ContentValues): Uri? = null\n\n /*\n * delete() always returns \"no rows affected\" (0)\n */\n override fun delete(uri: Uri, selection: String, selectionArgs: Array\u003cString\u003e): Int = 0\n\n /*\n * update() always returns \"no rows affected\" (0)\n */\n override fun update(\n uri: Uri,\n values: ContentValues,\n selection: String,\n selectionArgs: Array\u003cString\u003e\n ): Int = 0\n}\n```\n\n### Java\n\n```java\n/*\n * Define an implementation of ContentProvider that stubs out\n * all methods\n */\npublic class StubProvider extends ContentProvider {\n /*\n * Always return true, indicating that the\n * provider loaded correctly.\n */\n @Override\n public boolean onCreate() {\n return true;\n }\n /*\n * Return no type for MIME type\n */\n @Override\n public String getType(Uri uri) {\n return null;\n }\n /*\n * query() always returns no results\n *\n */\n @Override\n public Cursor query(\n Uri uri,\n String[] projection,\n String selection,\n String[] selectionArgs,\n String sortOrder) {\n return null;\n }\n /*\n * insert() always returns null (no URI)\n */\n @Override\n public Uri insert(Uri uri, ContentValues values) {\n return null;\n }\n /*\n * delete() always returns \"no rows affected\" (0)\n */\n @Override\n public int delete(Uri uri, String selection, String[] selectionArgs) {\n return 0;\n }\n /*\n * update() always returns \"no rows affected\" (0)\n */\n public int update(\n Uri uri,\n ContentValues values,\n String selection,\n String[] selectionArgs) {\n return 0;\n }\n}\n```\n\nDeclare the provider in the manifest\n------------------------------------\n\n\nThe sync adapter framework verifies that your app has a content provider by checking that your\napp has declared a provider in its app manifest. To declare the stub provider in the\nmanifest, add a [\u003cprovider\u003e](/guide/topics/manifest/provider-element) element with the following attributes:\n\n\n`android:name=\"com.example.android.datasync.provider.StubProvider\"`\n:\n Specifies the fully-qualified name of the class that implements the stub content provider.\n\n\n`android:authorities=\"com.example.android.datasync.provider\"`\n:\n A URI authority that identifies the stub content provider. Make this value your app's\n package name with the string \".provider\" appended to it. Even though you're declaring your\n stub provider to the system, nothing tries to access the provider itself.\n\n\n`android:exported=\"false\"`\n:\n Determines whether other apps can access the content provider. For your stub content\n provider, set the value to `false`, since there's no need to allow other apps to see\n the provider. This value doesn't affect the interaction between the sync adapter framework\n and the content provider.\n\n\n`android:syncable=\"true\"`\n:\n Sets a flag that indicates that the provider is syncable. If you set this flag to\n `true`, you don't have to call [setIsSyncable()](/reference/android/content/ContentResolver#setIsSyncable(android.accounts.Account, java.lang.String, int)) in your code. The flag allows the sync adapter framework to make data\n transfers with the content provider, but transfers only occur if you do them explicitly.\n\n\nThe following snippet shows you how to add the\n[\u003cprovider\u003e](/guide/topics/manifest/provider-element) element to the app manifest: \n\n```xml\n\u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.example.android.network.sync.BasicSyncAdapter\"\n android:versionCode=\"1\"\n android:versionName=\"1.0\" \u003e\n \u003capplication\n android:allowBackup=\"true\"\n android:icon=\"@drawable/ic_launcher\"\n android:label=\"@string/app_name\"\n android:theme=\"@style/AppTheme\" \u003e\n ...\n \u003cprovider\n android:name=\"com.example.android.datasync.provider.StubProvider\"\n android:authorities=\"com.example.android.datasync.provider\"\n android:exported=\"false\"\n android:syncable=\"true\"/\u003e\n ...\n \u003c/application\u003e\n\u003c/manifest\u003e\n```\n\n\nNow that you have created the dependencies required by the sync adapter framework, you can\ncreate the component that encapsulates your data transfer code. This component is called a\nsync adapter. The next lesson shows you how to add this component to your app."]]