8

В моем проекте Android я использую пользовательский SyncAdapter, который загружает данные и хранит их в локальной базе данных SQLite.Как уведомить вызывающую деятельность, когда завершен SyncAdapter?

public class CustomSyncAdapter extends AbstractThreadedSyncAdapter { 

    public CustomSyncAdapter(Context context, boolean autoInitialize) { 
     super(context, autoInitialize); 
    } 

    @Override 
    public void onPerformSync(Account account, 
           Bundle extras, 
           String authority, 
           ContentProviderClient provider, 
           SyncResult syncResult) { 

     // 1) Download data via AsyncTask 
     // 2) Store data via ContentProvider 
    } 
} 

запланировать sychronization от главного Activity с использованием ContentResolver, таких как ...

ContentResolver.requestSync(account, Authentication.AUTHORITY, bundle); 

Есть ли общий способ вызывающий Activity уведомляется, когда синхронизация завершена?

ответ

7

Вы можете сделать это с помощью ContentResolver.notifyChange().

Так что в вашем SyncAdapter вы бы на что-то вроде этого:

... 
@Override 
public void onPerformSync(Account account, 
          Bundle extras, 
          String authority, 
          ContentProviderClient provider, 
          SyncResult syncResult) { 

    // 1) Download data via AsyncTask 
    // 2) Store data via ContentProvider 

    getContext().getContentResolver().notifyChange(<your_content_uri>, null, false); 
} 
... 

В процессе, который затем использовать ContentResolver.registerContentObserver():

public class MyActivity extends Activity { 

    private ContentObserver mObserver; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     ... 
     mObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { 
      public void onChange(boolean selfChange) { 
       // Do something. 
      } 
     }; 
     getContentResolver().registerContentObserver(<your_content_uri>, mObserver); 
    } 

    @Override 
    public void onDestroy() { 
     getContentResolver().unregisterContentObserver(mObserver); 
    } 
} 
+0

[ContentObserver] (http://developer.android.com/reference/android/database/ContentObserver.html) требует пройти ах Andler. 'notifyChange' - это то же сообщение, которое уже отправлено' ContentProvider', я думаю ?! Или что вы используете? – JJD

+0

Я добавил «обработчик» к моему ответу. Да, если ваш 'ContentProvider' вызывает' notifyChange', вам не нужно называть его вручную. – Blaz

+0

Я думаю, что я должен уйти из 'Looper.getMainLooper', так как я уже запускаюсь в потоке пользовательского интерфейса. В противном случае я попадаю в 'java.util.concurrent.RejectedExecutionException'. - Я думаю, вы комментируете: «Ничего не делайте». должно быть что-то вроде «Обновить интерфейс». – JJD

3

В вашей деятельности вы можете добавить:

@Override 
public void onResume() { 
    super.onResume(); 
    mSyncMonitor = ContentResolver.addStatusChangeListener(
      ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE 
        | ContentResolver.SYNC_OBSERVER_TYPE_PENDING, 
      this 
    ); 
} 

@Override 
public void onPause() { 
    ContentResolver.removeStatusChangeListener(mSyncMonitor); 
    super.onPause(); 
} 

@Override 
public final void onStatusChanged(int which) { 
    // TODO update activity data 
} 
Смежные вопросы