无法让SyncAdapter在Xamarin中工作

时间:2014-05-15 18:25:14

标签: c# android xamarin android-syncadapter

我一直试图让SyncAdapter工作。男人,多么荒谬的复杂一团糟。我甚至不知道从哪里开始,所以我想我只是转储所有相关的代码。如果我在下面的代码中随处可见断点,那么在启动时会调用以下两个东西(按此顺序):

  • StubContentProvider.OnCreate()
  • AndroidApp.InitSyncService()(我的应用启动时显式调用)。

就是这样。没有任何与SyncAdapter相关的内容被调用(严重的是,我已经将断点放在与其相关的每个类的每个方法的顶部。)

我已经在应用程序的这个方面工作了大约一个半月,并且在不同的时间使它比现在更具功能性,但我不确定我是如何制作它的功能较少。我试过调整它的每个方面。我已将ACCOUNT_TYPEAUTHORITY更改为各种值。当我阅读文档并学到更多知识时,我会在这里和那里进行调整,但它似乎并不想为我聚集在一起。

这是我们应用的最后一项主要功能,所以我再也不能把它放在一边了。

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"/>

相关AndroidManifest.xml(由编译器生成)

<?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>

0 个答案:

没有答案