یک ارائه دهنده محتوای خرد ایجاد کنید
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
چارچوب آداپتور همگامسازی برای کار با دادههای دستگاه که توسط چارچوب ارائهدهنده محتوای انعطافپذیر و بسیار ایمن مدیریت میشود، طراحی شده است. به همین دلیل، چارچوب آداپتور همگامسازی انتظار دارد که برنامهای که از چارچوب استفاده میکند، قبلاً یک ارائهدهنده محتوا برای دادههای محلی خود تعریف کرده باشد. اگر چارچوب آداپتور همگامسازی سعی کند آداپتور همگامسازی شما را اجرا کند و برنامه شما ارائهدهنده محتوا نداشته باشد، آداپتور همگامسازی شما خراب میشود.
اگر در حال توسعه یک برنامه جدید هستید که داده ها را از یک سرور به دستگاه منتقل می کند، باید قویاً ذخیره داده های محلی را در یک ارائه دهنده محتوا در نظر بگیرید. علاوه بر اهمیت آنها برای آداپتورهای همگام، ارائه دهندگان محتوا مزایای امنیتی مختلفی را ارائه می دهند و به طور خاص برای مدیریت ذخیره سازی داده ها در سیستم های Android طراحی شده اند. برای کسب اطلاعات بیشتر در مورد ایجاد یک ارائه دهنده محتوا، به ایجاد یک ارائه دهنده محتوا مراجعه کنید.
با این حال، اگر قبلاً دادههای محلی را به شکل دیگری ذخیره میکنید، همچنان میتوانید از یک آداپتور همگامسازی برای مدیریت انتقال داده استفاده کنید. برای ارضای نیاز چارچوب آداپتور همگامسازی برای ارائهدهنده محتوا، یک ارائهدهنده محتوای خرد به برنامه خود اضافه کنید. یک ارائهدهنده خرد کلاس ارائهدهنده محتوا را پیادهسازی میکند، اما همه روشهای مورد نیاز آن null
یا 0
را برمیگردانند. اگر ارائهدهنده خرد اضافه کنید، میتوانید از یک آداپتور همگامسازی برای انتقال دادهها از هر مکانیزم ذخیرهسازی که انتخاب میکنید استفاده کنید.
اگر قبلاً یک ارائهدهنده محتوا در برنامه خود دارید، نیازی به ارائهدهنده محتوای خرد ندارید. در این صورت، می توانید این درس را رد کرده و به درس ایجاد یک آداپتور همگام سازی بروید. اگر هنوز ارائهدهنده محتوا ندارید، این درس به شما نشان میدهد که چگونه یک ارائهدهنده محتوای خرد اضافه کنید که به شما امکان میدهد آداپتور همگامسازی خود را به چارچوب وصل کنید.
یک ارائه دهنده محتوای خرد اضافه کنید
برای ایجاد یک ارائه دهنده محتوای خرد برای برنامه خود، کلاس ContentProvider
را گسترش دهید و روش های مورد نیاز آن را حذف کنید. قطعه زیر نحوه ایجاد ارائه دهنده خرد را به شما نشان می دهد:
کاتلین
/*
* 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
}
جاوا
/*
* 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;
}
}
ارائه دهنده را در مانیفست اعلام کنید
چارچوب آداپتور همگامسازی تأیید میکند که برنامه شما یک ارائهدهنده محتوا دارد، با بررسی اینکه آیا برنامه شما ارائهدهندهای را در مانیفست برنامه خود اعلام کرده است. برای اعلام ارائه دهنده خرد در مانیفست، یک عنصر <provider>
با ویژگی های زیر اضافه کنید:
-
android:name="com.example.android.datasync.provider.StubProvider"
- نام کاملاً واجد شرایط کلاسی را که ارائهدهنده محتوای خرد را پیادهسازی میکند، مشخص میکند.
-
android:authorities="com.example.android.datasync.provider"
- یک مرجع URI که ارائهدهنده محتوای خرد را شناسایی میکند. این مقدار را با نام بسته برنامه خود با رشته ".provider" اضافه کنید. حتی اگر شما ارائه دهنده خرد خود را به سیستم اعلام می کنید، هیچ چیزی سعی نمی کند به خود ارائه دهنده دسترسی پیدا کند.
-
android:exported="false"
- تعیین می کند که آیا برنامه های دیگر می توانند به ارائه دهنده محتوا دسترسی داشته باشند یا خیر. برای ارائهدهنده محتوای خرد خود، مقدار را روی
false
تنظیم کنید، زیرا نیازی به اجازه دادن به برنامههای دیگر برای دیدن ارائهدهنده وجود ندارد. این مقدار بر تعامل بین چارچوب آداپتور همگامسازی و ارائهدهنده محتوا تأثیری ندارد. -
android:syncable="true"
- پرچمی را تنظیم می کند که نشان می دهد ارائه دهنده قابل همگام سازی است. اگر این پرچم را روی
true
تنظیم کنید، نیازی نیست که setIsSyncable()
در کد خود فراخوانی کنید. پرچم به چارچوب آداپتور همگامسازی اجازه میدهد تا انتقال داده را با ارائهدهنده محتوا انجام دهد، اما انتقالها تنها در صورتی اتفاق میافتد که آنها را به صراحت انجام دهید.
قطعه زیر به شما نشان می دهد چگونه عنصر <provider>
را به مانیفست برنامه اضافه کنید:
<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>
اکنون که وابستگیهای مورد نیاز چارچوب آداپتور همگامسازی را ایجاد کردهاید، میتوانید مؤلفهای را ایجاد کنید که کد انتقال داده شما را کپسوله میکند. این کامپوننت آداپتور همگام سازی نامیده می شود. درس بعدی به شما نشان می دهد که چگونه این مؤلفه را به برنامه خود اضافه کنید.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],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."]]