SyncAdapter始终处于挂起状态-永不同步

时间:2019-07-01 16:16:46

标签: java android synchronization adapter

我正在编写一个使用SyncAdapter的Android设备应用程序。我遇到的问题是ContentResolver从未调用过SyncAdapter。

当我打电话给:

Bundle extras = new Bundle();
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);

ContentResolver.requestSync(
    Utility.Accounts.getAccount(),
    MyContract.CONTENT_AUTHORITY,
    extras);

从不调用SyncAdapter中的方法。我尝试检查:

ContentResolver.isSyncPending(
    Utility.Accounts.getAccount(),
    MyContract.CONTENT_AUTHORITY);

,并且始终解析为true。为了解决这个问题,我在Application.java onCreate方法中有以下代码:

if (ContentResolver.isSyncPending(
        Utility.Accounts.getAccount(),
        MyContract.CONTENT_AUTHORITY)) {
    Log.d(TAG, "cancelling pending sync");
    ContentResolver.cancelSync(
        Utility.Accounts.getAccount(),
        MyContract.CONTENT_AUTHORITY);
}

if (ContentResolver.isSyncPending(
        Utility.Accounts.getAccount(),
        MyContract.CONTENT_AUTHORITY)) {
    Log.d(TAG, "didn't work");
}

但是输出始终保持不变:

2019-07-01 11:33:49.168 18549-18549/? D/Application: cancelling pending sync
2019-07-01 11:33:49.169 18549-18549/? D/Application: didn't work

对于上下文,我的Utility.Accounts类:

public static class Accounts {

    static final String TYPE = "ca.package";
    static final String NAME = "name";

    public static Account getAccount() {
        return new Account(NAME, TYPE);
    }
}

和我的MyContract:

public class MyContract {
    public static final String CONTENT_AUTHORITY = "ca.package.name.provider";
}

AndroidManifest中的相关行如下:

<service android:name="ca.package.name.datasync.AuthenticatorService">
    <intent-filter>
        <action android:name="android.accounts.AccountAuthenticator" />
    </intent-filter>
    <meta-data
        android:name="android.accounts.AccountAuthenticator"
        android:resource="@xml/authenticator" />
</service>

<service
    android:name="ca.package.name.datasync.SyncAdapterService"
    android:exported="true"
    android:process=":sync">
    <intent-filter>
        <action android:name="android.content.SyncAdapter" />
    </intent-filter>
    <meta-data
        android:name="android.content.SyncAdapter"
        android:resource="@xml/syncadapter" />
</service>

<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />

authenticator.xml:

<?xml version="1.0" encoding="utf-8"?>

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="ca.package" />

syncadapter.xml:

<?xml version="1.0" encoding="utf-8"?>

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="ca.package"
    android:allowParallelSyncs="false"
    android:contentAuthority="ca.package.name.provider"
    android:supportsUploading="true"
    android:userVisible="false" />

SyncAdapter.java:

package ca.package.name.datasync;

public class SyncAdapter extends AbstractThreadedSyncAdapter {

    private static final String TAG = "SyncAdapter";

    private ContentResolver mContentResolver;

    public SyncAdapter(Context context, boolean autoInitialize) {
        this(context, autoInitialize, false);
    }

    public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {
        super(context, autoInitialize, allowParallelSyncs);

        Log.d(TAG, "constructor"); // this is never hit

        mContentResolver = context.getContentResolver();
    }

    @Override
    public void onPerformSync(Account account,
                              Bundle extras,
                              String authority,
                              ContentProviderClient provider,
                              SyncResult syncResult) {
        Log.i(TAG, "onPerformSync()"); // this is never hit

        doStuff();
    }
}

SyncAdapterService.java:

package ca.package.name.datasync;

public class SyncAdapterService extends Service {

    private static final String TAG = "SyncAdapterService";

    private static final Object sSyncAdapterLock = new Object();
    private static SyncAdapter sSyncAdapter = null;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate()"); // this is never hit

        synchronized (sSyncAdapterLock) {
            if (sSyncAdapter == null) {
                sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
            }
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind()"); // this is never hit
        return sSyncAdapter.getSyncAdapterBinder();
    }
}

Authenticator.java:

package ca.package.name.datasync;

public class Authenticator extends AbstractAccountAuthenticator {

    private static final String TAG = "Authenticator";

    public Authenticator(Context context) {
        super(context);
        Log.d(TAG, "constructor"); // this is never hit
    }

    @Override
    public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse,
                                 String s) {
        Log.d(TAG, "editProperties()"); // this is never hit
        throw new UnsupportedOperationException();
    }

    @Override
    public Bundle addAccount(AccountAuthenticatorResponse accountAuthenticatorResponse,
                             String s,
                             String s1,
                             String[] strings,
                             Bundle bundle) throws NetworkErrorException {
        Log.d(TAG, "addAccount()"); // this is never hit
        return null;
    }

    @Override
    public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse,
                                     Account account,
                                     Bundle bundle) throws NetworkErrorException {
        Log.d(TAG, "confirmCredentials()"); // this is never hit
        return null;
    }

    @Override
    public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse,
                               Account account,
                               String s,
                               Bundle bundle) throws NetworkErrorException {
        Log.d(TAG, "getAuthToken()"); // this is never hit
        throw new UnsupportedOperationException();
    }

    @Override
    public String getAuthTokenLabel(String s) {
        Log.d(TAG, "getAuthTokenLabel()"); // this is never hit
        throw new UnsupportedOperationException();
    }

    @Override
    public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse,
                                    Account account,
                                    String s,
                                    Bundle bundle) throws NetworkErrorException {
        Log.d(TAG, "updateCredentials()"); // this is never hit
        throw new UnsupportedOperationException();
    }

    @Override
    public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse,
                              Account account,
                              String[] strings) throws NetworkErrorException {
        Log.d(TAG, "hasFeatures()"); // this is never hit
        throw new UnsupportedOperationException();
    }
}

AuthenticatorService.java:

package ca.package.name.datasync;

public class AuthenticatorService extends Service {

    private static final String TAG = "AuthenticatorService";

    private Authenticator mAuthenticator;

    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate()"); // this is never hit
        super.onCreate();
        mAuthenticator = new Authenticator(this);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind()"); // this is never hit
        return mAuthenticator.getIBinder();
    }
}

在我的任何SyncAdapter或Authenticator类中都没有命中任何日志。我知道SyncAdapter在不同的进程(:sync)中运行,并且在尝试检查日志时已经考虑到了这一点。

0 个答案:

没有答案