我想在ActionBar中显示ProgressBar,而我的SyncAdapter正在主动地将内容与Web同步。
我试过用过 SyncStatusObserver 和...一起 ContentProvider.addStatusChangeListener。但是,我无法检查SyncAdapter是否正在运行。我只能检查:
- SyncAdapter正在等待使用 ContentResolver.isSyncPending
- SyncAdapter正在等待或正在使用 ContentResolver.isSyncActive
这些标志可以合并: !isSyncPending && isSyncActive
这样就可以检查SyncAdapter是否正在正常工作,并且没有任何待处理的工作。但是,在某些情况下,SyncAdapter正在正常工作,并有第二个等待它的待处理请求。
看起来很简单,但我无法找到解决这个问题的方法。在SyncAdapter未运行时显示ProgressBar会给用户留下同步非常慢的印象。让它不显示ProgressBar会让用户认为没有发生任何事情。
代码中的上述解决方案如下所示。我们在activity.onResume中注册观察者:
int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING | ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
syncHandle = ContentResolver.addStatusChangeListener(mask, syncObserver);
syncObserver在这里定义为:
syncObserver = new SyncStatusObserver()
{
@Override
public void onStatusChanged(int which)
{
Account account = getSomeAccount();
boolean syncActive = ContentResolver.isSyncActive(account, CONTENT_AUTHORITY);
boolean syncPending = ContentResolver.isSyncPending(account, CONTENT_AUTHORITY);
boolean isSynchronizing = syncActive && !syncPending;
updateRefreshButtonState();
}
}
我终于找到了问题的解决方案。我们的想法是使用ContentResolver getCurrentSyncs() 要么 getCurrentSync() 方法,以可用的为准。以下方法将检查同步操作当前是否适用于帐户和权限。它需要API级别8(Froyo = Android 2.2)。
private static boolean isSyncActive(Account account, String authority)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
return isSyncActiveHoneycomb(account, authority);
} else
{
SyncInfo currentSync = ContentResolver.getCurrentSync();
return currentSync != null && currentSync.account.equals(account) &&
currentSync.authority.equals(authority);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private static boolean isSyncActiveHoneycomb(Account account, String authority)
{
for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs())
{
if(syncInfo.account.equals(account) &&
syncInfo.authority.equals(authority))
{
return true;
}
}
return false;
}
然后,Activity会注册更新 onResume()
并取消注册 onDestroy()
。此外,还必须手动更新状态 onResume()
赶上现状。
这是一个实现这样做的实现。子类应该自己定义
- 什么帐户使用(实施
getAccount()
)
- 什么授权使用(该领域
CONTENT_AUTHORITY
)
- 如何显示同步状态(实现
updateState(boolean isSynchronizing)
)
我希望将来可以帮助某人。
import android.accounts.Account;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.SyncInfo;
import android.content.SyncStatusObserver;
import android.os.Build;
import android.os.Bundle;
public abstract class SyncActivity extends Activity
{
private static final String CONTENT_AUTHORITY = "com.example.authority";
private Object syncHandle;
private SyncStatusObserver observer;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
observer = new SyncStatusObserver()
{
@Override
public void onStatusChanged(int which)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
Account account = getAccount();
boolean isSynchronizing =
isSyncActive(account, CONTENT_AUTHORITY);
updateState(isSynchronizing);
}
});
}
};
}
@Override
protected void onResume()
{
super.onResume();
// Refresh synchronization status
observer.onStatusChanged(0);
// Watch for synchronization status changes
final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING |
ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
syncHandle = ContentResolver.addStatusChangeListener(mask, observer);
}
@Override
protected void onPause()
{
super.onPause();
// Remove our synchronization listener if registered
if (syncHandle != null)
{
ContentResolver.removeStatusChangeListener(syncHandle);
syncHandle = null;
}
}
private static boolean isSyncActive(Account account, String authority)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
return isSyncActiveHoneycomb(account, authority);
} else
{
SyncInfo currentSync = ContentResolver.getCurrentSync();
return currentSync != null && currentSync.account.equals(account)
&& currentSync.authority.equals(authority);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private static boolean isSyncActiveHoneycomb(Account account,
String authority)
{
for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs())
{
if(syncInfo.account.equals(account) &&
syncInfo.authority.equals(authority))
{
return true;
}
}
return false;
}
protected abstract Account getAccount();
protected abstract void updateState(boolean isSynchronizing);
}
我终于找到了问题的解决方案。我们的想法是使用ContentResolver getCurrentSyncs() 要么 getCurrentSync() 方法,以可用的为准。以下方法将检查同步操作当前是否适用于帐户和权限。它需要API级别8(Froyo = Android 2.2)。
private static boolean isSyncActive(Account account, String authority)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
return isSyncActiveHoneycomb(account, authority);
} else
{
SyncInfo currentSync = ContentResolver.getCurrentSync();
return currentSync != null && currentSync.account.equals(account) &&
currentSync.authority.equals(authority);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private static boolean isSyncActiveHoneycomb(Account account, String authority)
{
for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs())
{
if(syncInfo.account.equals(account) &&
syncInfo.authority.equals(authority))
{
return true;
}
}
return false;
}
然后,Activity会注册更新 onResume()
并取消注册 onDestroy()
。此外,还必须手动更新状态 onResume()
赶上现状。
这是一个实现这样做的实现。子类应该自己定义
- 什么帐户使用(实施
getAccount()
)
- 什么授权使用(该领域
CONTENT_AUTHORITY
)
- 如何显示同步状态(实现
updateState(boolean isSynchronizing)
)
我希望将来可以帮助某人。
import android.accounts.Account;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.SyncInfo;
import android.content.SyncStatusObserver;
import android.os.Build;
import android.os.Bundle;
public abstract class SyncActivity extends Activity
{
private static final String CONTENT_AUTHORITY = "com.example.authority";
private Object syncHandle;
private SyncStatusObserver observer;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
observer = new SyncStatusObserver()
{
@Override
public void onStatusChanged(int which)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
Account account = getAccount();
boolean isSynchronizing =
isSyncActive(account, CONTENT_AUTHORITY);
updateState(isSynchronizing);
}
});
}
};
}
@Override
protected void onResume()
{
super.onResume();
// Refresh synchronization status
observer.onStatusChanged(0);
// Watch for synchronization status changes
final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING |
ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
syncHandle = ContentResolver.addStatusChangeListener(mask, observer);
}
@Override
protected void onPause()
{
super.onPause();
// Remove our synchronization listener if registered
if (syncHandle != null)
{
ContentResolver.removeStatusChangeListener(syncHandle);
syncHandle = null;
}
}
private static boolean isSyncActive(Account account, String authority)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
return isSyncActiveHoneycomb(account, authority);
} else
{
SyncInfo currentSync = ContentResolver.getCurrentSync();
return currentSync != null && currentSync.account.equals(account)
&& currentSync.authority.equals(authority);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private static boolean isSyncActiveHoneycomb(Account account,
String authority)
{
for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs())
{
if(syncInfo.account.equals(account) &&
syncInfo.authority.equals(authority))
{
return true;
}
}
return false;
}
protected abstract Account getAccount();
protected abstract void updateState(boolean isSynchronizing);
}