SyncService для синхронизации данных между Android и сервером не запускается

В настоящее время я пытаюсь синхронизировать некоторые данные с сервером с помощью фоновой службы. Используя следующие сайты в качестве руководства:

Я также просмотрел StackOverflow и попробовал следующие решения:

  • Sync Adapter not running
    • Not possible since I am currently using the account the user logged in with and is added to the account manager
  • Sync Adapter not calling onCreate
    • By starting the service using the intent, I get the onCreate() to run for the service but it does not run onBind and the adapter is still not called when onChange runs ContentResolver.requestSync(...)
    • Кроме того, я уже сейчас использую requestSync (ACCOUNT, AUTHORITY, new Bundle ()) и трижды проверил, что учетная запись и полномочия совпадают с типом и полномочиями учетной записи в файле syncadapter.xml.
  • ContentResolver.requestSync in Sync Adapter is not working in Android
    • I am currently logging and viewing the LogCat with "No Filters" and can see all my other logs. However, the service logs don't show up which means that my service is not created

Я пробовал и другие решения на StackOverflow, но решения, по сути, инкапсулированы перечисленными выше. Мне интересно, не хватает ли чего-то там, где мне нужно запустить эту службу в моем коде.

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

Действия, в которых я использую преобразователь:

        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);



Ответы (1)


Я решил проблему, которую получал. Есть несколько флагов, которые контролируют работу адаптера синхронизации. Эти:

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=20CATELLINS=false

person Justin Li    schedule 26.02.2018