No se puede obtener SyncAdapter para trabajar en Xamarin

He estado tratando de conseguir un SyncAdapter para trabajar. Hombre, qué lío ridículamente complicado. Ni siquiera sé por dónde empezar, así que supongo que voy a descargar todo el código relacionado. Si pongo puntos de interrupción prácticamente en todas partes en el código de abajo, las siguientes dos cosas se llaman al inicio (en este orden):

  • StubContentProvider.OnCreate()
  • AndroidApp.InitSyncService() (llamado explícitamente cuando se inicia mi aplicación).

Y eso es. Nada más relacionado con el SyncAdapter nunca se llama (En serio, he puesto puntos de interrupción en la parte superior de cada método de cada clase relacionada con él.)

He trabajado en este aspecto de la aplicación de vez en cuando durante un mes y medio y en varias ocasiones lo había más funcional de lo que es ahora, pero no estoy seguro de cómo lo hice menos funcional. He intentado ajustar todos los aspectos de la misma. He cambiado ACCOUNT_TYPE y AUTHORITY a varios valores. Como he leído la documentación y aprendido más, voy a pellizcar aquí y allá, pero simplemente no parece querer reunirse para mí.

Esta es la última pieza importante de funcionalidad para nuestra aplicación, por lo que ya no puedo seguir poniendo esto a un lado.

AndroidApp.cs

 public static class AndroidApp { public static string ACCOUNT_TYPE = "georgesmobile.android.backgroundservice"; public static string ACCOUNT = "mobile"; public static string AUTHORITY = "georgesmobile.android.provider"; public static Account SyncAccount { get; private set; } public static void InitSyncService(Context context) { if (SyncAccount == null) { CreateSyncAccount(context); ContentResolver.SetIsSyncable(AndroidApp.SyncAccount, AndroidApp.AUTHORITY, 1); ContentResolver.SetSyncAutomatically(AndroidApp.SyncAccount, AndroidApp.AUTHORITY, true); Bundle bund = new Bundle(); ContentResolver.AddPeriodicSync(AndroidApp.SyncAccount, AndroidApp.AUTHORITY, bund, 2); } } private static Account CreateSyncAccount(Context context) { SyncAccount = new Account(ACCOUNT, ACCOUNT_TYPE); AccountManager accountManager = (AccountManager)context.GetSystemService(Context.AccountService); return SyncAccount; } } 

StubContentProvider.cs

 [ContentProvider(new[] { "georgesmobile.android.provider" }, Name = "georgesmobile.android.backgroundservice.StubContentProvider", Exported = false, Syncable = true)] public class StubContentProvider : ContentProvider { public override int Delete(global::Android.Net.Uri uri, string selection, string[] selectionArgs) { return 0; } public override string GetType(global::Android.Net.Uri uri) { return ""; } public override global::Android.Net.Uri Insert(global::Android.Net.Uri uri, ContentValues values) { return null; } public override bool OnCreate() { return true; } public override global::Android.Database.ICursor Query(global::Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder) { return null; } public override int Update(global::Android.Net.Uri uri, ContentValues values, string selection, string[] selectionArgs) { return 0; } } 

GenericAccountService.cs

 [Service(Name = "georgesmobile.android.backgroundservice.GenericAccountService")] [IntentFilter(new string[] { "android.accounts.AccountAuthenticator" })] [MetaData("android.accounts.AccountAuthenticator", Resource = "@xml/authenticator")] public class GenericAccountService : Service { private Authenticator _authenticator; public static Account GetAccount(string accountType) { return new Account(AndroidApp.ACCOUNT, AndroidApp.ACCOUNT_TYPE); } public override void OnCreate() { base.OnCreate(); _authenticator = new Authenticator(this); } public override IBinder OnBind(Intent intent) { return _authenticator.IBinder; } } 

SyncAdapter.cs

 [MetaData("android.content.SyncAdapter", Resource = "@xml/syncadapter")] public class SyncAdapter : AbstractThreadedSyncAdapter { public override void OnPerformSync(global::Android.Accounts.Account account, Bundle extras, string authority, ContentProviderClient provider, SyncResult syncResult) { BackgroundDataSync.Synchronize(); } } 

SyncService.cs

 [Service(Name = "georgesmobile.android.backgroundservice.SyncService", Exported = true)] public class SyncService : Service { private static SyncAdapter _syncAdapter; private static object _syncLock = new object(); public override void OnCreate() { base.OnCreate(); lock (_syncLock) { _syncAdapter = new SyncAdapter(ApplicationContext, true); } } public override IBinder OnBind(Intent intent) { return _syncAdapter.SyncAdapterBinder; } public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) { return base.OnStartCommand(intent, flags, startId); } } 

syncadapter.xml

 <?xml version="1.0" encoding="utf-8" ?> <sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:contentAuthority="georgesmobile.android.provider" android:accountType="georgesmobile.android.backgroundservice" android:userVisible="true" android:supportsUploading="true" android:allowParallelSyncs="true" android:isAlwaysSyncable="true"/> 

authenticator.xml

 <?xml version="1.0" encoding="utf-8" ?> <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" android:icon="@drawable/georgeslogo_icon" android:smallIcon="@drawable/georgeslogo_icon" android:label="@string/AppName" android:accountType="georgesmobile.android.backgroundservice"/> 

relevante AndroidManifest.xml (como generado por el compilador)

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="georgesmobile.android" android:versionCode="1" android:versionName="Crackerjack"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.READ_SYNC_STATS" /> <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" /> <uses-permission android:name="android.permission.ACCOUNT_MANAGER" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <application android:label="GeorgesMobile" android:icon="@drawable/georgeslogo_icon" android:theme="@android:style/Theme.Light" android:name="mono.android.app.Application" android:debuggable="true"> <receiver android:name="georgesmobile.android.backgroundservice.BootupReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <service android:name="georgesmobile.android.backgroundservice.GenericAccountService"> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" /> <intent-filter> <action android:name="android.accounts.AccountAuthenticator" /> </intent-filter> </service> <provider android:authorities="georgesmobile.android.provider" android:exported="false" android:name="georgesmobile.android.backgroundservice.StubContentProvider" android:syncable="true" /> <service android:exported="true" android:name="georgesmobile.android.backgroundservice.SyncService"> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" /> </service> <activity android:icon="@drawable/georgeslogo_icon" android:label="George's Inc" android:name="georgesmobile.android.views.HomeActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:icon="@drawable/georgeslogo_icon" android:label="George's Login" android:name="georgesmobile.android.views.LoginActivity" /> <provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="georgesmobile.android.mono.MonoRuntimeProvider.__mono_init__" /> <receiver android:name="mono.android.Seppuku"> <intent-filter> <action android:name="mono.android.intent.action.SEPPUKU" /> <category android:name="mono.android.intent.category.SEPPUKU.georgesmobile.android" /> </intent-filter> </receiver> </application> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> </manifest> 

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.