用于在 android 和未启动的服务器之间同步数据的 SyncService

SyncService for synchronizing data between android and server not starting

我目前正在尝试使用后台服务将一些数据与服​​务器同步。使用以下站点作为指南:

我还搜索了 Whosebug 并尝试了以下解决方案:

我也在 Whosebug 上尝试过其他解决方案,但这些解决方案基本上由上面列出的解决方案封装。我想知道在我的代码中需要启动此服务的地方是否缺少某些内容。

SyncService.java:

public class SyncService extends Service {
private static SyncAdapter syncAdapter = null;
private static final Object syncAdapterLock = new Object();

@Override
public void onCreate() {
    super.onCreate();
    Log.d("SyncService", "[DEBUG]       SyncService created...");
    synchronized (syncAdapterLock) {
        if (syncAdapter == null) {
            syncAdapter = new SyncAdapter(getApplicationContext(), true);
        }
    }
}

@Override
public IBinder onBind(Intent intent) {
    Log.d("SyncService", "[DEBUG]      onBind(...) run for SyncAdapter...");
    return syncAdapter.getSyncAdapterBinder();
}
}

SyncAdapter.java:

public class SyncAdapter extends AbstractThreadedSyncAdapter {
private ContentResolver resolver;
private AccountManager am;

public SyncAdapter(Context context, boolean autoInitialize) {
    super(context, autoInitialize);
    resolver = context.getContentResolver();
    am = AccountManager.get(context);
}

// Maintains compatibility with Android >= 3.0 platform versions
public SyncAdapter(Context context , boolean autoInitialize, boolean allowParallelSyncs) {
    super(context, autoInitialize, allowParallelSyncs);
    resolver = context.getContentResolver();
    am = AccountManager.get(context);
}

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
    Log.d("SyncAdapter", "[DEBUG]       onPerformSync for account[" + account.name + "] called. Syncing....");

    // Connect to server
    // Download and upload data
    // Handle data conflicts and determining if data is current
    // Clean up
}
}

观察者:

public class AlarmObserver extends ContentObserver {
Account account;

public AlarmObserver(Handler handler, Account account) {
    super(handler);
    this.account = account;
}

@Override
public void onChange(boolean selfChange) {
    onChange(selfChange, null);
}

@Override
public void onChange(boolean selfChange, Uri changeUri) {
    Log.d("AlarmObserver", "[DEBUG]     Change to content detected. Account: " + account.name + " Uri: " + changeUri.toString() + " Authority: " + AlarmContract.AUTHORITY);
    ContentResolver.requestSync(account, AlarmContract.AUTHORITY, new Bundle());
}
}

syncadapter.xml:

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
    android:contentAuthority="livotto.smarthomeapi.AlarmProvider"
    android:accountType="@string/default_account_type"
    android:userVisible="true"
    android:supportsUploading="true"
    android:allowParallelSyncs="false"
    android:isAlwaysSyncable="true" />

Activity 我使用解析器的地方:

        AccountManager am = AccountManager.get(this);
    Account[] accounts = am.getAccounts();

    if (accounts.length > 1) {
        // Dialog should appear asking which account to use
    }
    account = accounts[0];      // for now we take the first account

    resolver = getContentResolver();
    observer = new AlarmObserver(new Handler(), account);
    resolver.registerContentObserver(AlarmContract.CONTENT_URI, true, observer);

我遇到的问题已经解决了。有一些标志将控制同步适配器的运行方式。它们是:

ContentResolver.SYNC_EXTRAS_MANUAL 
ContentResolver.SYNC_EXTRAS_EXPEDITED

您可以通过以下方式进行设置:

Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);

ContentResolver.requestSync(ACCOUNT, AUTHORITY, bundle);

有关这些标志的作用的更多信息:

https://books.google.ca/books?id=30G1DAAAQBAJ&lpg=PT265&ots=f6T3TOqtr_&dq=syncservice%20oncreate%20not%20called%20android&pg=PT267#v=onepage&q=syncservice%20oncreate%20not%20called%20android&f=false