SyncAdapter正在运行的动画 - 如何知道是否SyncAdapter正在积极进行同步正在积极、正在运行、动画、SyncAdapter

2023-09-04 09:40:33 作者:你只是我的梦

我要显示在动作条一个进度条,而我SyncAdapter积极同步的内容和网页。

我使用SyncStatusObserver连同ContentProvider.addStatusChangeListener.但是,我不能检查,如果一个SyncAdapter正在积极运行。我只能检查:

SyncAdapter正在等待使用ContentResolver.isSyncPending SyncAdapter被挂起或者积极使用ContentResolver.isSyncActive

这些标志可以组合: isSyncPending和放大器;&安培; isSyncActive 以便它可以检查一个SyncAdapter正在积极努力并没有任何挂起的工作。然而,在一些情况下,SyncAdapter正在积极与具有第二挂起请求等待它

这似乎很简单,但我不能找到解决这个问题的方法。有当SyncAdapter没有运行进度明显是为用户提供了即时pression的同步是非常慢的。有了它不显示进度,使用户觉得什么也没发生。

在code将上述溶液如下所示。我们注册在activity.onResume观察员:

  INT面膜= ContentResolver.SYNC_OBSERVER_TYPE_PENDING | ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
 syncHandle = ContentResolver.addStatusChangeListener(面具,的SyncObserver);
 
有谁知道win8系统开始 运行 命令在哪里

的的SyncObserver在此定义为:

 的SyncObserver =新SyncStatusObserver()
{
    @覆盖
    公共无效onStatusChanged(INT它)
    {
        帐户帐户= getSomeAccount();
        布尔syncActive = ContentResolver.isSyncActive(帐户,CONTENT_AUTHORITY);
        布尔syncPending = ContentResolver.isSyncPending(帐户,CONTENT_AUTHORITY);
        布尔isSynchronizing = syncActive和放大器;&安培; !syncPending;
        updateRefreshButtonState();
    }
}
 

解决方案

我终于找到了解决问题的办法。我们的想法是使用ContentResolver的的getCurrentSyncs()或getCurrentSync()方法,取其可用。下面的方法将检查是否同步操作目前正在一个帐户和权限。它需要API级别8(升级Froyo =的Andr​​oid 2.2)。

 私有静态布尔isSyncActive(客户账户,串权威)
{
    如果(Build.VERSION.SDK_INT> = Build.VERSION_ codeS.HONEYCOMB)
    {
        返回isSyncActiveHoneycomb(帐户,授权);
    } 其他
    {
        SyncInfo currentSync = ContentResolver.getCurrentSync();
        返回currentSync = NULL和放大器;!&安培; currentSync.account.equals(账户)及和放大器;
               currentSync.authority.equals(授权);
    }
}

@TargetApi(Build.VERSION_ codeS.HONEYCOMB)
私有静态布尔isSyncActiveHoneycomb(客户账户,串权威)
{
    对于(SyncInfo syncInfo:ContentResolver.getCurrentSyncs())
    {
        如果(syncInfo.account.equals(账户)及和放大器;
           syncInfo.authority.equals(授权))
        {
            返回true;
        }
    }
    返回false;
}
 

这是活动然后注册为 onResume()和注销更新的的onDestroy()。同样的,一个要在 onResume()手动更新状态赶上当前状态。

下面是做到了这一点的实现。子类应自行确定

什么帐户才能使用(实施是getAccount()) 要使用什么authoritity(领域 CONTENT_AUTHORITY ) 如何显示同步控制器的状态(实施 updateState(布尔isSynchronizing)

我希望这将帮助别人的未来。

 进口android.accounts.Account;
进口android.annotation.TargetApi;
进口android.app.Activity;
进口android.content.ContentResolver;
进口android.content.SyncInfo;
进口android.content.SyncStatusObserver;
进口android.os.Build;
进口android.os.Bundle;

公共抽象类SyncActivity扩展活动
{
    私有静态最后弦乐CONTENT_AUTHORITY =com.example.authority;
    私有对象syncHandle;
    私人SyncStatusObserver观测;

    @覆盖
    保护无效的onCreate(包savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        观察者=新SyncStatusObserver()
        {
            @覆盖
            公共无效onStatusChanged(INT它)
            {
                runOnUiThread(新的Runnable()
                {
                    @覆盖
                    公共无效的run()
                    {
                        帐户帐户=是getAccount();
                        布尔isSynchronizing =
                                isSyncActive(帐户,CONTENT_AUTHORITY);
                        updateState(isSynchronizing);
                    }
                });
            }
        };
    }

    @覆盖
    保护无效onResume()
    {
        super.onResume();

        //刷新同步状态
        observer.onStatusChanged(0);

        //留意同步状态的变化
        最终诠释面膜= ContentResolver.SYNC_OBSERVER_TYPE_PENDING |
                ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
        syncHandle = ContentResolver.addStatusChangeListener(面具,观察者);
    }

    @覆盖
    保护无效的onPause()
    {
        super.onPause();

        //删除我们的同步监听器,如果注册
        如果(syncHandle!= NULL)
        {
            ContentResolver.removeStatusChangeListener(syncHandle);
            syncHandle = NULL;
        }
    }

    私有静态布尔isSyncActive(客户账户,串权威)
    {
        如果(Build.VERSION.SDK_INT> = Build.VERSION_ codeS.HONEYCOMB)
        {
            返回isSyncActiveHoneycomb(帐户,授权);
        } 其他
        {
            SyncInfo currentSync = ContentResolver.getCurrentSync();
            返回currentSync = NULL和放大器;!&安培; currentSync.account.equals(帐户)
                    &功放;&安培; currentSync.authority.equals(授权);
        }
    }

    @TargetApi(Build.VERSION_ codeS.HONEYCOMB)
    私有静态布尔isSyncActiveHoneycomb(客户账户,
                                                         字符串的权威)
    {
        对于(SyncInfo syncInfo:ContentResolver.getCurrentSyncs())
        {
            如果(syncInfo.account.equals(账户)及和放大器;
                    syncInfo.authority.equals(授权))
            {
                返回true;
            }
        }
        返回false;
    }

    受保护的抽象的账户是getAccount();
    保护抽象无效updateState(布尔isSynchronizing);
}
 

I want to show a ProgressBar in the ActionBar while my SyncAdapter is actively synchronizing content to and from the web.

I have tried using the SyncStatusObserver together with ContentProvider.addStatusChangeListener. However, I cannot check if a SyncAdapter is actively running. I can only check:

SyncAdapter is pending using ContentResolver.isSyncPending SyncAdapter is pending OR actively working using ContentResolver.isSyncActive

These flags can be combined: !isSyncPending && isSyncActive so that it is possible to check that a SyncAdapter is actively working and does not have any pending work. However, in some cases the SyncAdapter is actively working AND have a second pending request waiting for it.

It seems so simple but I can't find a way around this problem. Having the ProgressBar visible when the SyncAdapter is not running is giving users the impression that the synchronization is very slow. Having it not show the ProgressBar makes the user think nothing is happening.

The above solution in code is shown below. We register the observer in the activity.onResume:

 int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING | ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
 syncHandle = ContentResolver.addStatusChangeListener(mask, syncObserver);

The syncObserver is here defined as:

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

解决方案

I finally found a solution to the problem. The idea is to use the ContentResolver's getCurrentSyncs() or getCurrentSync() methods, whichever is available. The methods below will check if a sync operation is currently working for an account and authority. It requires API level 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;
}

An Activity then registers for updates in onResume() and unregisters in onDestroy(). Also, one have to update state manually in onResume() to catch up with current status.

Here is an implementation that does just that. Subclasses should themselves define

what account to use (implementing getAccount()) what authoritity to use (the field CONTENT_AUTHORITY) how to display sychronization status (implementing updateState(boolean isSynchronizing))

I hope it will help someone in the future.

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