659 lines
27 KiB
Plaintext
659 lines
27 KiB
Plaintext
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>
|
|
<dt>
|
|
{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS android.permission.AUTHENTICATE_ACCOUNTS}
|
|
</dt>
|
|
<dd>
|
|
Allows you to use the authenticator component you created in the lesson
|
|
<a href="creating-authenticator.html">Creating a Stub Authenticator</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>
|