#android #android-contentprovider #android-syncadapter
#Android #android-contentprovider #android-syncadapter
Вопрос:
Я пытаюсь заставить пользовательский ContentProvider отображаться в разделе Данные и синхронизация, и я сталкиваюсь с некоторыми проблемами. А именно, он не отображается.
Особенности:
Мой AndroidManifest.xml есть поставщик и сервис:
<provider android:name="BooksProvider"
android:label="ClientName Books"
android:authorities="com.clientname.reader.books"
android:enabled="true"
android:exported="true"
android:syncable="true">
<grant-uri-permission android:pathPattern=".*" />
</provider>
<service android:name=".sync.SyncService"
android:exported="true" android:process=":sync">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data android:name="android.content.SyncAdapater"
android:resource="@xml/syncadapter" />
</service>
И res/xml/syncadapter.xml имеет следующее:
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.clientname.reader.books"
android:accountType="com.google"
android:supportsUploading="true"
android:userVisible="true"
/>
На всякий случай я даже вызвал следующее в onCreate:
AccountManager accountManager = AccountManager.get(getApplicationContext());
Account[] accounts = accountManager.getAccountsByType("com.google");
for(Account account : accounts){
Log.d(TAG, "Account: " account.name);
ContentResolver.setIsSyncable(account, Reader.AUTHORITY, 1);
}
Когда я загружаю действие, я получаю журнал adb из ContentResolver.setIsSyncable, в котором говорится, что учетная запись уже настроена на синхронизацию, поэтому метод ничего не делает.
И все же провайдер отказывается отображаться в Настройках> Учетные записи и синхронизация> Данные и синхронизация. Есть идеи о том, почему? Кто-нибудь знает, как определяется, что отображается в этом разделе?
[редактировать] Дополнительная информация:
Потратив несколько часов на отладку, я сталкиваюсь с этой ошибкой:
04-11 10:46:02.370: DEBUG/SyncManager(105): can't find a sync adapter for SyncAdapterType Key {name=com.clientname.reader.books, type=com.google}, removing settings for it
Также похоже, что мой класс SyncService на самом деле никогда не вызывается. Должен ли я вызывать его сам? Ни один из примеров, которые я видел, или приложений в дикой природе, не вызывает его самостоятельно, но все они также имеют компоненты аутентификации. Мысли?
Ответ №1:
<meta-data android:name="android.content.SyncAdapater"
android:resource="@xml/syncadapter" />
Кто-нибудь еще заметил ответ?
Боже, я ненавижу быть идиотом.
Комментарии:
1. Опечатки — самые досадные ошибки программирования за всю историю!!
2. Даже с вашим ответом я не вижу, что было не так. Можете ли вы сделать это явным?
3. android.content. SyncAdapater должен быть android.content. SyncAdapter
Ответ №2:
Таким образом, с точки зрения семантики поставщики не отображаются непосредственно в Accounts amp; Sync. Вместо этого отображаются учетные записи с поставщиками на их страницах сведений. Итак, поскольку вы привязываете свой SyncAdapter к учетной записи в стиле com.google, средство синхронизации будет отображаться в вашей учетной записи Google — наряду с «контактами», «Календарем» и «Gmail» вы должны увидеть «Книги имен клиентов»
Однако ваша настоящая проблема заключается в вашем XML. Согласно AndroidManifest.xml документы,
android:name
Имя подкласса Service, который реализует сервис. Это должно быть полное имя класса (например, «com.example.project.RoomService»). Однако, в качестве сокращения, если первым символом имени является точка (например, «.RoomService»), оно добавляется к имени пакета, указанному в
Похоже, что он не находит ваш BooksProvider
класс, потому что ему нужен FQCN или относительный путь через ваши пакеты.
Комментарии:
1. Спасибо за информацию. Реальной проблемой была опечатка. Боже, я чувствую себя глупо. Нажмите Ctrl F «adapater» в этом окне, и вы увидите это.
Ответ №3:
Как я наконец выяснил, еще одна причина, по которой ContentProvider может не отображаться на экране настроек синхронизации, заключается в отсутствии android.permission.Разрешение WRITE_SYNC_SETTINGS в манифесте. К сожалению, во всех руководствах, статьях и документации, которые я прочитал, этот пункт отсутствует или явно не описан. Кроме того, платформа (протестированная на уровне API 13), похоже, не выдает никаких исключений в виде разрешений — я надеюсь, они это исправят. Надеюсь, это кому-то поможет.