get notified when requestSync function completed

2019-06-14 03:15发布

问题:

im trying to start the calendar sync programatically using this code

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

ContentResolver.requestSync(accounts[0], "com.android.calendar", bundle);

i want a way so i can know when sync complete so i can read data from the calendar i tried doing this

while (ContentResolver.isSyncActive(accounts[0], "com.android.calendar")) {
System.out.println("looping: " + i);
}

readLocalCalendar();
readLocalEvents();

but the system exit the loop before the sync ends and i can still see the sync sign at the status bar, so any help so i can read calendar events after sync completle done ??

thanks

回答1:

Another option would be to register a broadcast receiver to tell you when the sync is finished like this:

public class UpdateableActivity extends Activity {
    public static final String ACTION_FINISHED_SYNC = "your.package.ACTION_FINISHED_SYNC";

    private static IntentFilter syncIntentFilter = new IntentFilter(ACTION_FINISHED_SYNC);

    private BroadcastReceiver syncBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // update your views
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        // register for sync
        registerReceiver(syncBroadcastReceiver, syncIntentFilter);
        // do your resuming magic
    }

    @Override
    protected void onPause() {
        unregisterReceiver(syncBroadcastReceiver);
        super.onPause();
    }
}

Inside your SyncAdapter use this when done:

getContext().sendBroadcast(new Intent(UpdateableActivity.ACTION_FINISHED_SYNC));  

You can also use this for when starting or updating the status of the sync ;)

Update: Updated the code to avoid leaks and making sure the activity is still active (onResume/onPause)



回答2:

using the addStatusChangeListener actually worked for me .

here's a reference .

don't forget to add the needed permissions .



回答3:

Use ContentResolver.addStatusChangeListener (int mask, SyncStatusObserver callback) to get notified of changes in sync status. docs

Please do not loop forever, its really bad design. Using the above method everything is asynchronous so you don't waste any cpu cycles.

You could also use ContentResolver.registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer) docs to get notified in changes on a specific URI (like the calendar's URI)



回答4:

try an AsyncTask :

private class CustomTask extends AsyncTask<Void, Void, Void>{

      @Override
      protected Void doInBackground(Void... params) {
       // TODO sync your calendar
      }

      protected void onProgressUpdate(Void... progress) {
        //TODO display a spinner or something else to show progress
      }

      protected void onPostExecute(Void t){
       //TODO what you want when doInBackground has finished

      }

}

Good luck !