我正在编写一个使用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)中运行,并且在尝试检查日志时已经考虑到了这一点。