Вызов requestSync()
будет работать только с парой {Account, ContentAuthority}, известной системе. Ваше приложение должно пройти ряд шагов, чтобы сообщить Android, что вы можете синхронизировать определенный тип контента с использованием определенного типа учетной записи. Это делается в AndroidManifest.
1. Сообщите Android, что ваш пакет приложений обеспечивает синхронизацию
Прежде всего, в AndroidManifest.xml вы должны объявить, что у вас есть служба синхронизации:
<service android:name=".sync.mySyncService" android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_myapp" />
</service>
Атрибут name тега <service>
- это имя вашего класса для подключения синхронизации ... Я поговорю об этом через секунду.
Установка экспортированного значения true делает его видимым для других компонентов (необходимо, чтобы ContentResolver
мог его вызвать).
Фильтр намерений позволяет ему поймать намерение, запрашивающее синхронизацию. (Это Intent
взято из ContentResolver
при вызове ContentResolver.requestSync()
или связанных методов планирования.)
Тег <meta-data>
будет рассмотрен ниже.
2. Предоставьте Android сервис, используемый для поиска вашего SyncAdapter
Итак, сам класс ... Вот пример:
public class mySyncService extends Service {
private static mySyncAdapter mSyncAdapter = null;
public SyncService() {
super();
}
@Override
public void onCreate() {
super.onCreate();
if (mSyncAdapter == null) {
mSyncAdapter = new mySyncAdapter(getApplicationContext(), true);
}
}
@Override
public IBinder onBind(Intent arg0) {
return mSyncAdapter.getSyncAdapterBinder();
}
}
Ваш класс должен расширять Service
или один из его подклассов, должен реализовывать public IBinder onBind(Intent)
и должен возвращать SyncAdapterBinder
при вызове ... Вам нужна переменная типа AbstractThreadedSyncAdapter
. Итак, как вы можете видеть, это почти все в этом классе. Единственная причина, по которой он там, - это предоставление Службы, которая предлагает стандартный интерфейс для Android, чтобы запрашивать у вашего класса, какой у вас SyncAdapter
.
3. Укажите class SyncAdapter
для фактического выполнения синхронизации.
mySyncAdapter - это место, где хранится настоящая логика синхронизации. Его метод onPerformSync()
вызывается, когда приходит время для синхронизации. Я полагаю, у вас уже есть это на месте.
4. Установить привязку между типом учетной записи и органом управления контентом
Оглядываясь назад на AndroidManifest, этот странный тег <meta-data>
в нашем сервисе является ключевым элементом, который устанавливает связь между ContentAuthority и учетной записью. Внешне он ссылается на другой XML-файл (называйте его как угодно, что-то относящееся к вашему приложению). Давайте посмотрим на sync_myapp.xml:
<?xml version="1.0" encoding="utf-8" ?>
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.android.contacts"
android:accountType="com.google"
android:userVisible="true" />
Хорошо, так что это делает? Он сообщает Android, что определенный нами адаптер синхронизации (класс, который был вызван в элементе name тега <service>
, включающего тег <meta-data>
, который ссылается на этот файл ...) будет синхронизировать контакты с помощью com. Аккаунт в стиле Google.
Все ваши строки contentAuthority должны совпадать и совпадать с тем, что вы синхронизируете. Это должна быть заданная вами строка, если вы создаете собственную базу данных, или вы должны использовать некоторые существующие строки устройства, если вы ' повторная синхронизация известных типов данных (таких как контакты или события календаря или что у вас есть.) Выше («com.android.contacts»), как представляется, строка ContentAuthority для данных типа контактов (сюрприз, сюрприз.)
accountType также должен соответствовать одному из тех известных типов учетных записей, которые уже введены, или он должен совпадать с тем, который вы создаете (Это включает создание подкласса AccountAuthenticator для получения аутентификации на вашем сервере ... Стоит статья, сам по себе.) Опять "com.google" - это определенная строка, идентифицирующая ... учетные данные в стиле google.com (опять же, это не должно вызывать удивления.)
5. Включить синхронизацию для данной пары Account / ContentAuthority
Наконец, синхронизация должна быть включена. Это можно сделать на странице «Аккаунты и синхронизация» на панели управления, перейдя в свое приложение и установив флажок рядом с вашим приложением в соответствующей учетной записи. Кроме того, вы можете сделать это с помощью некоторого кода установки в вашем приложении:
ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
Для того, чтобы произошла синхронизация, ваша пара аккаунт / полномочия должна быть включена для синхронизации (как указано выше) и должен быть установлен общий глобальный флаг синхронизации в системе, и устройства должен иметь подключение к сети.
Если ваша учетная запись / синхронизация с полномочиями или глобальная синхронизация отключены, вызов RequestSync () имеет эффект - он устанавливает флаг, что синхронизация была запрошена, и будет выполнена, как только синхронизация будет включена.
Кроме того, за мгВ , установив для ContentResolver.SYNC_EXTRAS_MANUAL
значение true в комплекте extras вашего requestSync, будет запрашивать у Android принудительную синхронизацию, даже если глобальная синхронизация отключена (будьте внимательны к вашему пользователю здесь!)
Наконец, вы можете настроить периодическую запланированную синхронизацию, опять же с функциями ContentResolver.
6. Рассмотрим последствия нескольких учетных записей
Можно иметь более одной учетной записи одного типа (две учетные записи @ gmail.com, настроенные на одном устройстве или две учетные записи Facebook, или две учетные записи Twitter и т. Д.). Следует учитывать последствия применения делая это ... Если у вас есть две учетные записи, вы, вероятно, не хотите пытаться синхронизировать их в одной и той же таблице базы данных. Возможно, вам нужно указать, что одновременно может быть активна только одна, и очистить таблицы и выполнить повторную синхронизацию, если вы переключаете учетные записи. (через страницу свойств, которая запрашивает, какие учетные записи присутствуют). Может быть, вы создаете разные базы данных для каждой учетной записи, может быть, разные таблицы, может быть ключевой столбец в каждой таблице. Все приложения специфичны и достойны некоторой мысли. ContentResolver.setIsSyncable(Account account, String authority, int syncable)
может быть интересно здесь. setSyncAutomatically()
контролирует, будет ли пара учетная запись / полномочия отмечена или снята с проверки , тогда как setIsSyncable()
предоставляет способ снять отметку и выделить строку, чтобы пользователь не мог ее включить , Вы можете установить одну учетную запись как синхронизируемую, а другую не синхронизируемую (dsabled).
7. Помните о ContentResolver.notifyChange ()
Одна хитрая вещь. ContentResolver.notifyChange()
- это функция, используемая ContentProvider
s для уведомления Android об изменении локальной базы данных. Это служит двум функциям, во-первых, это заставит курсоры, следующие за этим URI контента, обновляться, и, в свою очередь, запрашивать и аннулировать и перерисовывать ListView
и т. Д. Это очень волшебно, база данных меняется, и ваш ListView
просто обновляется автоматически , Потрясающие. Кроме того, при изменении базы данных Android будет запрашивать синхронизацию для вас, даже вне вашего обычного расписания, чтобы эти изменения были сняты с устройства и синхронизированы с сервером как можно быстрее. Тоже круто.
Хотя есть один крайний случай. Если вы извлечете сервер и вставите обновление в ContentProvider
, оно покорно вызовет notifyChange()
, и Android скажет: «О, изменения в базе данных, лучше разместите их на сервере!» (Doh!) Хорошо написанный ContentProviders
будет иметь несколько тестов, чтобы видеть, произошли ли изменения из сети или от пользователя, и установит логический флаг syncToNetwork
false, если так, чтобы предотвратить эту расточительную двойную синхронизацию. Если вы подаете данные в ContentProvider
, вам следует выяснить, как это работает - в противном случае вы всегда будете выполнять две синхронизации, когда нужна только одна.
8. Чувствую себя счастливым!
Когда у вас есть все эти XML-метаданные и включена синхронизация, Android будет знать, как все подключить, и синхронизация должна начать работать. В этот момент многие приятные вещи просто встанут на свои места, и это будет похоже на магию. Наслаждайтесь!