| page.title=Creating a Sync Adapter | |
| trainingnavtop=true | |
| @jd:body | |
| <div id="tb-wrapper"> | |
| <div id="tb"> | |
| <h2>This lesson teaches you to</h2> | |
| <ol> | |
| <li> | |
| <a href="#CreateSyncAdapter" | |
| >Create the Sync Adapter Class</a> | |
| </li> | |
| <li> | |
| <a href="#CreateSyncAdapterService">Bind the Sync Adapter to the Framework</a> | |
| </li> | |
| <li> | |
| <a href="#CreateAccountTypeAccount" | |
| >Add the Account Required by the Framework</a> | |
| </li> | |
| <li> | |
| <a href="#CreateSyncAdapterMetadata">Add the Sync Adapter Metadata File</a> | |
| </li> | |
| <li> | |
| <a href="#DeclareSyncAdapterManifest">Declare the Sync Adapter in the Manifest</a> | |
| </li> | |
| </ol> | |
| <h2>You should also read</h2> | |
| <ul> | |
| <li> | |
| <a href="{@docRoot}guide/components/bound-services.html">Bound Services</a> | |
| </li> | |
| <li> | |
| <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> | |
| </li> | |
| <li> | |
| <a href="{@docRoot}training/id-auth/custom_auth.html">Creating a Custom Account Type</a> | |
| </li> | |
| </ul> | |
| <h2>Try it out</h2> | |
| <div class="download-box"> | |
| <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a> | |
| <p class="filename">BasicSyncAdapter.zip</p> | |
| </div> | |
| </div> | |
| </div> | |
| <p> | |
| The sync adapter component in your app encapsulates the code for the tasks that transfer | |
| data between the device and a server. Based on the scheduling and triggers you provide in | |
| your app, the sync adapter framework runs the code in the sync adapter component. To add a | |
| sync adapter component to your app, you need to add the following pieces: | |
| <dl> | |
| <dt> | |
| Sync adapter class. | |
| </dt> | |
| <dd> | |
| A class that wraps your data transfer code in an interface compatible with the sync adapter | |
| framework. | |
| </dd> | |
| <dt> | |
| Bound {@link android.app.Service}. | |
| </dt> | |
| <dd> | |
| A component that allows the sync adapter framework to run the code in your sync adapter | |
| class. | |
| </dd> | |
| <dt> | |
| Sync adapter XML metadata file. | |
| </dt> | |
| <dd> | |
| A file containing information about your sync adapter. The framework reads this file to | |
| find out how to load and schedule your data transfer. | |
| </dd> | |
| <dt> | |
| Declarations in the app manifest. | |
| </dt> | |
| <dd> | |
| XML that declares the bound service and points to sync adapter-specific metadata. | |
| </dd> | |
| </dl> | |
| <p> | |
| This lesson shows you how to define these elements. | |
| </p> | |
| <h2 id="CreateSyncAdapter">Create a Sync Adapter Class</h2> | |
| <p> | |
| In this part of the lesson you learn how to create the sync adapter class that encapsulates the | |
| data transfer code. Creating the class includes extending the sync adapter base class, defining | |
| constructors for the class, and implementing the method where you define the data transfer | |
| tasks. | |
| </p> | |
| <h3>Extend the base sync adapter class AbstractThreadedSyncAdapter</h3> | |
| <p> | |
| To create the sync adapter component, start by extending | |
| {@link android.content.AbstractThreadedSyncAdapter} and writing its constructors. Use the | |
| constructors to run setup tasks each time your sync adapter component is created from | |
| scratch, just as you use {@link android.app.Activity#onCreate Activity.onCreate()} to set up an | |
| activity. For example, if your app uses a content provider to store data, use the constructors | |
| to get a {@link android.content.ContentResolver} instance. Since a second form of the | |
| constructor was added in Android platform version 3.0 to support the {@code parallelSyncs} | |
| argument, you need to create two forms of the constructor to maintain compatibility. | |
| </p> | |
| <p class="note"> | |
| <strong>Note:</strong> The sync adapter framework is designed to work with sync adapter | |
| components that are singleton instances. Instantiating the sync adapter component is covered | |
| in more detail in the section | |
| <a href="#CreateSyncAdapterService">Bind the Sync Adapter to the Framework</a>. | |
| </p> | |
| <p> | |
| The following example shows you how to implement | |
| {@link android.content.AbstractThreadedSyncAdapter}and its constructors: | |
| </p> | |
| <pre style="clear: right"> | |
| /** | |
| * Handle the transfer of data between a server and an | |
| * app, using the Android sync adapter framework. | |
| */ | |
| public class SyncAdapter extends AbstractThreadedSyncAdapter { | |
| ... | |
| // Global variables | |
| // Define a variable to contain a content resolver instance | |
| ContentResolver mContentResolver; | |
| /** | |
| * Set up the sync adapter | |
| */ | |
| public SyncAdapter(Context context, boolean autoInitialize) { | |
| super(context, autoInitialize); | |
| /* | |
| * If your app uses a content resolver, get an instance of it | |
| * from the incoming Context | |
| */ | |
| mContentResolver = context.getContentResolver(); | |
| } | |
| ... | |
| /** | |
| * Set up the sync adapter. This form of the | |
| * constructor maintains compatibility with Android 3.0 | |
| * and later platform versions | |
| */ | |
| public SyncAdapter( | |
| Context context, | |
| boolean autoInitialize, | |
| boolean allowParallelSyncs) { | |
| super(context, autoInitialize, allowParallelSyncs); | |
| /* | |
| * If your app uses a content resolver, get an instance of it | |
| * from the incoming Context | |
| */ | |
| mContentResolver = context.getContentResolver(); | |
| ... | |
| } | |
| </pre> | |
| <h3>Add the data transfer code to onPerformSync()</h3> | |
| <p> | |
| The sync adapter component does not automatically do data transfer. Instead, it | |
| encapsulates your data transfer code, so that the sync adapter framework can run the | |
| data transfer in the background, without involvement from your app. When the framework is ready | |
| to sync your application's data, it invokes your implementation of the method | |
| {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()}. | |
| </p> | |
| <p> | |
| To facilitate the transfer of data from your main app code to the sync adapter component, | |
| the sync adapter framework calls | |
| {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} with the | |
| following arguments: | |
| </p> | |
| <dl> | |
| <dt> | |
| Account | |
| </dt> | |
| <dd> | |
| An {@link android.accounts.Account} object associated with the event that triggered | |
| the sync adapter. If your server doesn't use accounts, you don't need to use the | |
| information in this object. | |
| </dd> | |
| <dt> | |
| Extras | |
| </dt> | |
| <dd> | |
| A {@link android.os.Bundle} containing flags sent by the event that triggered the sync | |
| adapter. | |
| </dd> | |
| <dt> | |
| Authority | |
| </dt> | |
| <dd> | |
| The authority of a content provider in the system. Your app has to have access to | |
| this provider. Usually, the authority corresponds to a content provider in your own app. | |
| </dd> | |
| <dt> | |
| Content provider client | |
| </dt> | |
| <dd> | |
| A {@link android.content.ContentProviderClient} for the content provider pointed to by the | |
| authority argument. A {@link android.content.ContentProviderClient} is a lightweight public | |
| interface to a content provider. It has the same basic functionality as a | |
| {@link android.content.ContentResolver}. If you're using a content provider to store data | |
| for your app, you can connect to the provider with this object. Otherwise, you can ignore | |
| it. | |
| </dd> | |
| <dt> | |
| Sync result | |
| </dt> | |
| <dd> | |
| A {@link android.content.SyncResult} object that you use to send information to the sync | |
| adapter framework. | |
| </dd> | |
| </dl> | |
| <p> | |
| The following snippet shows the overall structure of | |
| {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()}: | |
| </p> | |
| <pre> | |
| /* | |
| * Specify the code you want to run in the sync adapter. The entire | |
| * sync adapter runs in a background thread, so you don't have to set | |
| * up your own background processing. | |
| */ | |
| @Override | |
| public void onPerformSync( | |
| Account account, | |
| Bundle extras, | |
| String authority, | |
| ContentProviderClient provider, | |
| SyncResult syncResult) { | |
| /* | |
| * Put the data transfer code here. | |
| */ | |
| ... | |
| } | |
| </pre> | |
| <p> | |
| While the actual implementation of | |
| {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} is specific to | |
| your app's data synchronization requirements and server connection protocols, there are a few | |
| general tasks your implementation should perform: | |
| </p> | |
| <dl> | |
| <dt> | |
| Connecting to a server | |
| </dt> | |
| <dd> | |
| Although you can assume that the network is available when your data transfer starts, the | |
| sync adapter framework doesn't automatically connect to a server. | |
| </dd> | |
| <dt> | |
| Downloading and uploading data | |
| </dt> | |
| <dd> | |
| A sync adapter doesn't automate any data transfer tasks. If you want to download | |
| data from a server and store it in a content provider, you have to provide the code that | |
| requests the data, downloads it, and inserts it in the provider. Similarly, if you want to | |
| send data to a server, you have to read it from a file, database, or provider, and send | |
| the necessary upload request. You also have to handle network errors that occur while your | |
| data transfer is running. | |
| </dd> | |
| <dt> | |
| Handling data conflicts or determining how current the data is | |
| </dt> | |
| <dd> | |
| A sync adapter doesn't automatically handle conflicts between data on the server and data | |
| on the device. Also, it doesn't automatically detect if the data on the server is newer than | |
| the data on the device, or vice versa. Instead, you have to provide your own algorithms for | |
| handling this situation. | |
| </dd> | |
| <dt> | |
| Clean up. | |
| </dt> | |
| <dd> | |
| Always close connections to a server and clean up temp files and caches at the end of | |
| your data transfer. | |
| </dd> | |
| </dl> | |
| <p class="note"> | |
| <strong>Note:</strong> The sync adapter framework runs | |
| {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} on a | |
| background thread, so you don't have to set up your own background processing. | |
| </p> | |
| <p> | |
| In addition to your sync-related tasks, you should try to combine your regular | |
| network-related tasks and add them to | |
| {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()}. | |
| By concentrating all of your network tasks in this method, you conserve the battery power that's | |
| needed to start and stop the network interfaces. To learn more about making network access more | |
| efficient, see the training class <a href="{@docRoot}training/efficient-downloads/index.html" | |
| >Transferring Data Without Draining the Battery</a>, which describes several network access | |
| tasks you can include in your data transfer code. | |
| </p> | |
| <h2 id="CreateSyncAdapterService">Bind the Sync Adapter to the Framework</h2> | |
| <p> | |
| You now have your data transfer code encapsulated in a sync adapter component, but you have | |
| to provide the framework with access to your code. To do this, you need to create a bound | |
| {@link android.app.Service} that passes a special Android binder object from the sync adapter | |
| component to the framework. With this binder object, the framework can invoke the | |
| {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} method and | |
| pass data to it. | |
| </p> | |
| <p> | |
| Instantiate your sync adapter component as a singleton in the | |
| {@link android.app.Service#onCreate onCreate()} method of the service. By instantiating | |
| the component in {@link android.app.Service#onCreate onCreate()}, you defer | |
| creating it until the service starts, which happens when the framework first tries to run your | |
| data transfer. You need to instantiate the component in a thread-safe manner, in case the sync | |
| adapter framework queues up multiple executions of your sync adapter in response to triggers or | |
| scheduling. | |
| </p> | |
| <p> | |
| For example, the following snippet shows you how to create a class that implements the | |
| bound {@link android.app.Service}, instantiates your sync adapter component, and gets the | |
| Android binder object: | |
| </p> | |
| <pre> | |
| package com.example.android.syncadapter; | |
| /** | |
| * Define a Service that returns an {@link android.os.IBinder} for the | |
| * sync adapter class, allowing the sync adapter framework to call | |
| * onPerformSync(). | |
| */ | |
| public class SyncService extends Service { | |
| // Storage for an instance of the sync adapter | |
| private static SyncAdapter sSyncAdapter = null; | |
| // Object to use as a thread-safe lock | |
| private static final Object sSyncAdapterLock = new Object(); | |
| /* | |
| * Instantiate the sync adapter object. | |
| */ | |
| @Override | |
| public void onCreate() { | |
| /* | |
| * Create the sync adapter as a singleton. | |
| * Set the sync adapter as syncable | |
| * Disallow parallel syncs | |
| */ | |
| synchronized (sSyncAdapterLock) { | |
| if (sSyncAdapter == null) { | |
| sSyncAdapter = new SyncAdapter(getApplicationContext(), true); | |
| } | |
| } | |
| } | |
| /** | |
| * Return an object that allows the system to invoke | |
| * the sync adapter. | |
| * | |
| */ | |
| @Override | |
| public IBinder onBind(Intent intent) { | |
| /* | |
| * Get the object that allows external processes | |
| * to call onPerformSync(). The object is created | |
| * in the base class code when the SyncAdapter | |
| * constructors call super() | |
| */ | |
| return sSyncAdapter.getSyncAdapterBinder(); | |
| } | |
| } | |
| </pre> | |
| <p class="note"> | |
| <strong>Note:</strong> To see a more detailed example of a bound service for a sync adapter, | |
| see the sample app. | |
| </p> | |
| <h2 id="CreateAccountTypeAccount">Add the Account Required by the Framework</h2> | |
| <p> | |
| The sync adapter framework requires each sync adapter to have an account type. You declared | |
| the account type value in the section | |
| <a href="creating-authenticator.html#CreateAuthenticatorFile" | |
| >Add the Authenticator Metadata File</a>. Now you have to set up this account type in the | |
| Android system. To set up the account type, add a dummy account that uses the account type | |
| by calling {@link android.accounts.AccountManager#addAccountExplicitly addAccountExplicitly()}. | |
| </p> | |
| <p> | |
| The best place to call the method is in the | |
| {@link android.support.v4.app.FragmentActivity#onCreate onCreate()} method of your app's | |
| opening activity. The following code snippet shows you how to do this: | |
| </p> | |
| <pre> | |
| public class MainActivity extends FragmentActivity { | |
| ... | |
| ... | |
| // Constants | |
| // The authority for the sync adapter's content provider | |
| public static final String AUTHORITY = "com.example.android.datasync.provider"; | |
| // An account type, in the form of a domain name | |
| public static final String ACCOUNT_TYPE = "example.com"; | |
| // The account name | |
| public static final String ACCOUNT = "dummyaccount"; | |
| // Instance fields | |
| Account mAccount; | |
| ... | |
| @Override | |
| protected void onCreate(Bundle savedInstanceState) { | |
| super.onCreate(savedInstanceState); | |
| ... | |
| // Create the dummy account | |
| mAccount = CreateSyncAccount(this); | |
| ... | |
| } | |
| ... | |
| /** | |
| * Create a new dummy account for the sync adapter | |
| * | |
| * @param context The application context | |
| */ | |
| public static Account CreateSyncAccount(Context context) { | |
| // Create the account type and default account | |
| Account newAccount = new Account( | |
| ACCOUNT, ACCOUNT_TYPE); | |
| // Get an instance of the Android account manager | |
| AccountManager accountManager = | |
| (AccountManager) context.getSystemService( | |
| ACCOUNT_SERVICE); | |
| /* | |
| * Add the account and account type, no password or user data | |
| * If successful, return the Account object, otherwise report an error. | |
| */ | |
| if (accountManager.addAccountExplicitly(newAccount, null, null)) { | |
| /* | |
| * If you don't set android:syncable="true" in | |
| * in your <provider> element in the manifest, | |
| * then call context.setIsSyncable(account, AUTHORITY, 1) | |
| * here. | |
| */ | |
| } else { | |
| /* | |
| * The account exists or some other error occurred. Log this, report it, | |
| * or handle it internally. | |
| */ | |
| } | |
| } | |
| ... | |
| } | |
| </pre> | |
| <h2 id="CreateSyncAdapterMetadata">Add the Sync Adapter Metadata File</h2> | |
| <p> | |
| To plug your sync adapter component into the framework, you need to provide the framework | |
| with metadata that describes the component and provides additional flags. The metadata specifies | |
| the account type you've created for your sync adapter, declares a content provider authority | |
| associated with your app, controls a part of the system user interface related to sync adapters, | |
| and declares other sync-related flags. Declare this metadata in a special XML file stored in | |
| the {@code /res/xml/} directory in your app project. You can give any name to the file, | |
| although it's usually called {@code syncadapter.xml}. | |
| </p> | |
| <p> | |
| This XML file contains a single XML element <code><sync-adapter></code> that has the | |
| following attributes: | |
| </p> | |
| <dl> | |
| <dt><code>android:contentAuthority</code></dt> | |
| <dd> | |
| The URI authority for your content provider. If you created a stub content provider for | |
| your app in the previous lesson <a href="creating-stub-provider.html" | |
| >Creating a Stub Content Provider</a>, use the value you specified for the | |
| attribute | |
| <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">android:authorities</a></code> | |
| in the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html" | |
| ><provider></a></code> element you added to your app manifest. This attribute is | |
| described in more detail in the section | |
| <a href="creating-stub-provider.html#DeclareProvider" | |
| >Declare the Provider in the Manifest</a>. | |
| <br/> | |
| If you're transferring data from a content provider to a server with your sync adapter, this | |
| value should be the same as the content URI authority you're using for that data. This value | |
| is also one of the authorities you specify in the | |
| <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">android:authorities</a></code> | |
| attribute of the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html" | |
| ><provider></a></code> element that declares your provider in your app manifest. | |
| </dd> | |
| <dt><code>android:accountType</code></dt> | |
| <dd> | |
| The account type required by the sync adapter framework. The value must be the same | |
| as the account type value you provided when you created the authenticator metadata file, as | |
| described in the section <a href="creating-authenticator.html#CreateAuthenticatorFile" | |
| >Add the Authenticator Metadata File</a>. It's also the value you specified for the | |
| constant {@code ACCOUNT_TYPE} in the code snippet in the section | |
| <a href="#CreateAccountTypeAccount">Add the Account Required by the Framework</a>. | |
| </dd> | |
| <dt>Settings attributes</dt> | |
| <dd> | |
| <dl> | |
| <dt> | |
| {@code android:userVisible} | |
| </dt> | |
| <dd> | |
| Sets the visibility of the sync adapter's account type. By default, the | |
| account icon and label associated with the account type are visible in the | |
| <b>Accounts</b> section of the system's Settings app, so you should make your sync | |
| adapter invisible unless you have an account type or domain that's easily associated | |
| with your app. If you make your account type invisible, you can still allow users to | |
| control your sync adapter with a user interface in one of your app's activities. | |
| </dd> | |
| <dt> | |
| {@code android:supportsUploading} | |
| </dt> | |
| <dd> | |
| Allows you to upload data to the cloud. Set this to {@code false} if your app only | |
| downloads data. | |
| </dd> | |
| <dt> | |
| {@code android:allowParallelSyncs} | |
| </dt> | |
| <dd> | |
| Allows multiple instances of your sync adapter component to run at the same time. | |
| Use this if your app supports multiple user accounts and you want to allow multiple | |
| users to transfer data in parallel. This flag has no effect if you never run | |
| multiple data transfers. | |
| </dd> | |
| <dt> | |
| {@code android:isAlwaysSyncable} | |
| </dt> | |
| <dd> | |
| Indicates to the sync adapter framework that it can run your sync adapter at any | |
| time you've specified. If you want to programmatically control when your sync | |
| adapter can run, set this flag to {@code false}, and then call | |
| {@link android.content.ContentResolver#requestSync requestSync()} to run the | |
| sync adapter. To learn more about running a sync adapter, see the lesson | |
| <a href="running-sync-adapter.html">Running a Sync Adapter</a> | |
| </dd> | |
| </dl> | |
| </dd> | |
| </dl> | |
| <p> | |
| The following example shows the XML for a sync adapter that uses a single dummy account and | |
| only does downloads. | |
| </p> | |
| <pre> | |
| <?xml version="1.0" encoding="utf-8"?> | |
| <sync-adapter | |
| xmlns:android="http://schemas.android.com/apk/res/android" | |
| android:contentAuthority="com.example.android.datasync.provider" | |
| android:accountType="com.android.example.datasync" | |
| android:userVisible="false" | |
| android:supportsUploading="false" | |
| android:allowParallelSyncs="false" | |
| android:isAlwaysSyncable="true"/> | |
| </pre> | |
| <h2 id="DeclareSyncAdapterManifest">Declare the Sync Adapter in the Manifest</h2> | |
| <p> | |
| Once you've added the sync adapter component to your app, you have to request permissions | |
| related to using the component, and you have to declare the bound {@link android.app.Service} | |
| you've added. | |
| </p> | |
| <p> | |
| Since the sync adapter component runs code that transfers data between the network and the | |
| device, you need to request permission to access the Internet. In addition, your app needs | |
| to request permission to read and write sync adapter settings, so you can control the sync | |
| adapter programmatically from other components in your app. You also need to request a | |
| special permission that allows your app to use the authenticator component you created | |
| in the lesson <a href="creating-authenticator.html">Creating a Stub Authenticator</a>. | |
| </p> | |
| <p> | |
| To request these permissions, add the following to your app manifest as child elements of | |
| <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>: | |
| </p> | |
| <dl> | |
| <dt> | |
| {@link android.Manifest.permission#INTERNET android.permission.INTERNET} | |
| </dt> | |
| <dd> | |
| Allows the sync adapter code to access the Internet so that it can download or upload data | |
| from the device to a server. You don't need to add this permission again if you were | |
| requesting it previously. | |
| </dd> | |
| <dt> | |
| {@link android.Manifest.permission#READ_SYNC_SETTINGS android.permission.READ_SYNC_SETTINGS} | |
| </dt> | |
| <dd> | |
| Allows your app to read the current sync adapter settings. For example, you need this | |
| permission in order to call {@link android.content.ContentResolver#getIsSyncable | |
| getIsSyncable()}. | |
| </dd> | |
| <dt> | |
| {@link android.Manifest.permission#WRITE_SYNC_SETTINGS android.permission.WRITE_SYNC_SETTINGS} | |
| </dt> | |
| <dd> | |
| Allows your app to control sync adapter settings. You need this permission in order to | |
| set periodic sync adapter runs using {@link android.content.ContentResolver#addPeriodicSync | |
| addPeriodicSync()}. This permission is <b>not</b> required to call | |
| {@link android.content.ContentResolver#requestSync requestSync()}. To learn more about | |
| running the sync adapter, see <a href="running-sync-adapter.html" | |
| >Running A Sync Adapter</a>. | |
| </dd> | |
| </dl> | |
| <p> | |
| The following snippet shows how to add the permissions: | |
| </p> | |
| <pre> | |
| <manifest> | |
| ... | |
| <uses-permission | |
| android:name="android.permission.INTERNET"/> | |
| <uses-permission | |
| android:name="android.permission.READ_SYNC_SETTINGS"/> | |
| <uses-permission | |
| android:name="android.permission.WRITE_SYNC_SETTINGS"/> | |
| <uses-permission | |
| android:name="android.permission.AUTHENTICATE_ACCOUNTS"/> | |
| ... | |
| </manifest> | |
| </pre> | |
| <p> | |
| Finally, to declare the bound {@link android.app.Service} that the framework uses to | |
| interact with your sync adapter, add the following XML to your app manifest as a child element | |
| of <code><a href="{@docRoot}guide/topics/manifest/application-element.html" | |
| ><application></a></code>: | |
| </p> | |
| <pre> | |
| <service | |
| android:name="com.example.android.datasync.SyncService" | |
| android:exported="true" | |
| android:process=":sync"> | |
| <intent-filter> | |
| <action android:name="android.content.SyncAdapter"/> | |
| </intent-filter> | |
| <meta-data android:name="android.content.SyncAdapter" | |
| android:resource="@xml/syncadapter" /> | |
| </service> | |
| </pre> | |
| <p> | |
| The | |
| <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code> | |
| element sets up a filter that's triggered by the intent action | |
| {@code android.content.SyncAdapter}, sent by the system to run the sync adapter. When the filter | |
| is triggered, the system starts the bound service you've created, which in this example is | |
| {@code SyncService}. The attribute | |
| <code><a href="{@docRoot}guide/topics/manifest/service-element.html#exported">android:exported="true"</a></code> | |
| allows processes other than your app (including the system) to access the | |
| {@link android.app.Service}. The attribute | |
| <code><a href="{@docRoot}guide/topics/manifest/service-element.html#proc">android:process=":sync"</a></code> | |
| tells the system to run the {@link android.app.Service} in a global shared process named | |
| {@code sync}. If you have multiple sync adapters in your app they can share this process, | |
| which reduces overhead. | |
| </p> | |
| <p> | |
| The | |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data></a></code> | |
| element provides provides the name of the sync adapter metadata XML file you created previously. | |
| The | |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code> | |
| attribute indicates that this metadata is for the sync adapter framework. The | |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#rsrc">android:resource</a></code> | |
| element specifies the name of the metadata file. | |
| </p> | |
| <p> | |
| You now have all of the components for your sync adapter. The next lesson shows you how to | |
| tell the sync adapter framework to run your sync adapter, either in response to an event or on | |
| a regular schedule. | |
| </p> |