我已经实现了一个同步适配器,我想在我的活动中完成回调。我尝试过使用ContentResolver.addStatusChangeListener
,但我只是在同步待处理/活动时才收到回调。以下是我的活动中的一些相关代码:
@Override
protected void onResume() {
super.onResume();
final int mask = ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE | ContentResolver.SYNC_OBSERVER_TYPE_PENDING;
syncObserverHandle = ContentResolver.addStatusChangeListener(mask, syncStatusObserver);
}
@Override
protected void onPause() {
super.onPause();
if (syncObserverHandle != null) {
ContentResolver.removeStatusChangeListener(syncObserverHandle);
syncObserverHandle = null;
}
}
private SyncStatusObserver syncStatusObserver = new SyncStatusObserver() {
@Override
public void onStatusChanged(int which) {
AccountManager am = AccountManager.get(TodosActivity.this);
Account a = am.getAccountsByType(Const.ACCOUNT_TYPE)[0];
Log.d(Const.TAG, "Sync status changed: " + which);
if (!ContentResolver.isSyncActive(a, DataProvider.AUTHORITY) &&
!ContentResolver.isSyncPending(a, DataProvider.AUTHORITY)) {
Log.d(Const.TAG, "Sync finished, should refresh nao!!");
}
}
};
但是,if
方法中的onStatusChanged
永远无效。我在JumpNote demo中使用了这个例子,因为它也可以在onResume()
中手动调用,因此当同步完成时,它可能从未被系统调用 。或者是,我做错了什么?这是我在logcat中得到的:
D/MYAPP (10903): Sync status changed: 2
D/MYAPP (10903): Sync status changed: 2
D/MYAPP (10903): Sync status changed: 4
D/MYAPP (10981): --> DataSyncAdapter.onPerformSync()
D/MYAPP (10981): <-- DataSyncAdapter.onPerformSync()
D/MYAPP (10903): Sync status changed: 4
所以,似乎我可以依赖第二个SYNC_OBSERVER_TYPE_ACTIVE
(4)状态更改来刷新我的数据,但这似乎真的丑陋。有什么想法吗?
答案 0 :(得分:41)
我找到的一个解决方案是完全抛弃ContentResolver
并实现我自己的广播。基本上,在onPerformSync
:
Intent i = new Intent(SYNC_FINISHED);
sendBroadcast(i);
这在活动中:
@Override
protected void onResume() {
super.onResume();
registerReceiver(syncFinishedReceiver, new IntentFilter(DataSyncService.SYNC_FINISHED));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(syncFinishedReceiver);
}
private BroadcastReceiver syncFinishedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(Const.TAG, "Sync finished, should refresh nao!!");
}
};
这似乎工作正常,但我希望在SDK中找到一些在同步完成时直接通知我的内容。
答案 1 :(得分:17)
奇怪,它对我有用。
在Activity
我有:
@Override
protected void onPause() {
super.onPause();
ContentResolver.removeStatusChangeListener(mContentProviderHandle);
}
@Override
protected void onResume() {
super.onResume();
mContentProviderHandle = ContentResolver.addStatusChangeListener(
ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, this);
}
@Override
public void onStatusChanged(int which) {
AccountManager accountManager = AccountManager.get(this);
Account[] accounts = accountManager
.getAccountsByType(AuthenticatorActivity.PARAM_ACCOUNT_TYPE);
if (accounts.length <= 0) {
return;
}
updateRefresh(ContentResolver.isSyncActive(accounts[0],
MyContentProvider.AUTHORITY));
}
// Since onStatusChanged() is not called from the main thread
// I need to update the ui in the ui-thread.
private void updateRefresh(final boolean isSyncing) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (isSyncing) {
mRefreshMenu.setActionView(R.layout.menu_item_refresh);
} else {
mRefreshMenu.setActionView(null);
}
}
});
}
答案 2 :(得分:6)
我正在研究类似的东西,而且我在onStatusChanged函数的末尾还有一个Log.d,它没有执行!
因此,经过15分钟的调试和错误试验后,我意识到我需要添加READ_SYNC_STATS权限,但我已经获得了GET_ACCOUNTS权限。所以,请检查你是否获得了正确的许可,而不是“如果”没有成为真实,而是它一直保留。