Intereting Posts
Получить количество непрочитанных смс Как решить для viewpager: указанный ребенок уже имеет родителя. Вы должны сначала вызвать removeView () родителя ребенка Эмуляция карт NFC Android Как отключить / подавить предупреждения IDEA «Оказание проблем» Android MediaPlayer занимает много времени для подготовки и буферизации Значение поиска для ключа в строковом массиве android Есть ли рекомендуемая стратегия для выпуска бета-версии приложения для ограниченного числа пользователей через Android Market? Как указать версию JDK в студии Android? Приложение Android Webview не позволит проигрывателю проигрывать весь экран Слушать кнопки громкости в фоновом режиме? Android ListView: получить индекс данных видимого элемента Почему сенсорные события уничтожают мою частоту кадров в Android? Настроить устройство для разработки (без разрешений) Как изменить цвет строки состояния в android Как использовать ресурс Idluso Idling для сетевых вызовов

Почему ContentResolver.requestSync не вызывает синхронизацию?

Я пытаюсь реализовать шаблон адаптера Content-Provider-Sync, как описано в Google IO – слайд 26. Мой контент-провайдер работает, и моя синхронизация работает, когда я запускаю его из приложения Dev Tools Sync Tester, однако, когда я вызываю ContentResolver. RequestSync (учетная запись, полномочия, пакет) из моего ContentProvider, моя синхронизация никогда не запускается.

ContentResolver.requestSync( account, AUTHORITY, new Bundle()); 

Изменить – добавлен фрагмент манифеста. Мой манифест xml содержит:

 <service android:name=".sync.SyncService" android:exported="true"> <intent-filter> <action android:name="android.content.SyncAdapter" /> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" /> </service> 

–Редактировать

Мой syncadapter.xml, связанный с моей службой синхронизации, содержит:

 <?xml version="1.0" encoding="utf-8"?> <sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:contentAuthority="AUTHORITY" android:accountType="myaccounttype" android:supportsUploading="true" /> 

Не уверен, какой другой код будет полезен. Учетная запись, переданная requestSync, имеет значение «myaccounttype», а AUTHORITY, переданный вызову, соответствует моему xic-адаптеру syc.

Правильно ли запрашивается синхронизация ContentResolver.requestSync? Похоже, что инструмент тестера синхронизации связывается непосредственно с сервисом и вызывает синхронизацию запуска, но похоже, что он побеждает цель интеграции с архитектурой синхронизации.

Если это правильный способ запросить синхронизацию, то зачем нужен тестер синхронизации, но не мой вызов ContentResolver.requestSync? Есть что-то, что мне нужно передать в комплекте?

Я тестирую эмулятор на устройствах с 2.1 и 2.2.

Solutions Collecting From Web of "Почему ContentResolver.requestSync не вызывает синхронизацию?"

Вызов 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> – это имя вашего класса для подключения синхронизации … Я поговорю с этим через секунду.

Параметр exported 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 когда это SyncAdapterBinder … Вам нужна переменная типа AbstractThreadedSyncAdapter . Итак, как вы можете видеть, это почти все в этом классе. Единственная причина, по которой он заключается в предоставлении Сервиса, который предлагает стандартный интерфейс для Android, чтобы SyncAdapter ваш класс о том, что такое ваш 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. Включите синхронизацию по данной учетной записи / ContentAuthority.

Наконец, синхронизация должна быть включена. Вы можете сделать это на странице «Учетные записи и синхронизация» на панели управления, перейдя в приложение и установив флажок рядом с вашим приложением в соответствующей учетной записи. В качестве альтернативы вы можете сделать это с помощью некоторого кода установки в своем приложении:

 ContentResolver.setSyncAutomatically(account, AUTHORITY, true); 

Чтобы синхронизация происходила, ваша учетная запись / полномочная пара должна быть включена для синхронизации (например, выше), и должен быть установлен общий глобальный флаг синхронизации в системе, а устройство должно иметь сетевое подключение.

Если синхронизация вашей учетной записи / органа или глобальная синхронизация отключены, вызов функции RequestSync () имеет эффект. Он устанавливает флаг, который был запрошен для синхронизации, и будет выполнен, как только включена синхронизация.

Кроме того, на mgv , устанавливая ContentResolver.SYNC_EXTRAS_MANUAL на true в пакете дополнительных компонентов вашего запросаSync, попросите андроид принудительно синхронизировать, даже если глобальная синхронизация отключена (будьте с уважением к своему пользователю здесь!)

Наконец, вы можете настроить периодическую синхронизацию, опять же с функциями ContentResolver.

6. Рассмотрите последствия нескольких счетов

Возможно иметь несколько учетных записей одного и того же типа (две учетные записи @ gmail.com, настроенные на одном устройстве или две учетные записи facebook или две учетные записи twitter и т. Д.). Вы должны учитывать последствия этого приложения для приложения. .. Если у вас есть две учетные записи, вы, вероятно, не хотите пытаться синхронизировать их оба с одними и теми же таблицами базы данных. Возможно, вам нужно указать, что за один раз может быть активен только один, и очистить таблицы и повторно синхронизировать, если вы переключаете учетные записи. (Через страницу свойств, которая запрашивает, какие учетные записи присутствуют). Возможно, вы создаете другую базу данных для каждой учетной записи, возможно, разные таблицы, возможно, ключевой столбец в каждой таблице. Все приложения специфичны и достойны некоторой мысли. ContentResolver.setIsSyncable(Account account, String authority, int syncable) может представлять интерес здесь. setSyncAutomatically() определяет, проверяется ли флажок / учетная пара или нет, а setIsSyncable() предоставляет возможность снять и вычеркнуть строку, чтобы пользователь не мог включить ее. Вы можете установить одну учетную запись Syncable, а другую – не синхронизировать (dsabled).

7. Имейте в виду ContentResolver.notifyChange ()

Одна сложная вещь. ContentResolver.notifyChange() – это функция, используемая ContentProvider s для уведомления Android о том, что локальная база данных была изменена. Это служит двум функциям: во-первых, это приведет к тому, что курсоры следуют за этим содержанием uri для обновления и, в свою очередь, потребуют и недействительны и перерисовывают ListView и т. Д. Это очень волшебный, изменения в базе данных и ваш ListView просто обновляется автоматически. Потрясающие. Кроме того, когда база данных изменится, Android запросит синхронизацию для вас, даже вне вашего обычного расписания, чтобы эти изменения были сняты с устройства и синхронизировались с сервером как можно быстрее. Также потрясающе.

Однако есть один краевой вопрос. Если вы выйдете с сервера и нажмете обновление в ContentProvider , он послушно вызовет notifyChange() и андроид пойдет: «О, изменения в базе данных, лучше поместите их на сервер!» (Doh!) Хорошо написанные ContentProviders проведут несколько тестов, чтобы узнать, произошли ли изменения в сети или у пользователя, и установите флаг логической syncToNetwork если это так, чтобы предотвратить эту расточительную двойную синхронизацию. Если вы загружаете данные в ContentProvider , вам нужно выяснить, как это сделать. В противном случае вы будете всегда выполнять две синхронизации, когда требуется только один.

8. Почувствуй себя счастливым!

После того, как вы включите все эти метаданные xml и включите синхронизацию, Android будет знать, как подключить все для вас, и синхронизация должна начать работать. На данный момент многие вещи, которые хороши, просто защелкнутся на месте, и это будет очень похоже на магию. Наслаждайтесь!