本文从使用角度上介绍了如何创建和使用android 同步框架,大部分是官方文档资料,但是有些小坑需要注意。
总体上,使用同步框架需要实现三部份代码:
1.创建账户类型(Account)
2.创建Stub ContentProvider
3.创建同步适配器(SyncAdapter)
参考资料:
Creating a Stub Authenticator
Creating a Stub Content Provider
Creating a Sync Adapter
Running a Sync Adapter
googlesamples/android-BasicSyncAdapter
创建账户类型
1.创建一个授权类
public class Authenticator extends AbstractAccountAuthenticator {
//默认代码
}
2.创建一个授权service
package com.crazyman.accountsyncdemo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class AuthenticatorService extends Service {
private Authenticator mAuthenticator;
public AuthenticatorService() {
}
@Override
public void onCreate() {
super.onCreate();
mAuthenticator = new Authenticator(this);
}
@Override
public IBinder onBind(Intent intent) {
return mAuthenticator.getIBinder();
}
}
3.创建xml/authenticator.xml文件
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.crazyman.accountsyncdemo.type"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:smallIcon="@mipmap/ic_launcher" />
PS:这里一定要注意,android:label=”@string/app_name” 不能用字符串代替,一定要用字符串资源才行!
4.在AndroidManifest.xml文件中加入权限和service
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<service
android:name=".AuthenticatorService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
实现以上代码后,安装APP就可以发现,在设置中已经可以创建上面指定类型的账号了。
创建Stub Content Provider
1. 创建一个StubProvider类
public class StubProvider extends ContentProvider {
//默认代码
}
2.在Android Manifest文件中加入provider
<provider
android:name="com.crazyman.accountsyncdemo.StubProvider"
android:authorities="com.crazyman.accountsyncdemo.provider"
android:exported="false"
android:syncable="true" />
创建同步adapter
1.创建adapter类
public class SyncAdapter extends AbstractThreadedSyncAdapter {
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.d("account sync", "-----------onPerformSync--------");
}
}
2.创建同步service
public class SyncService extends Service {
// Storage for an instance of the sync adapter
private static SyncAdapter sSyncAdapter = null;
// Object to use as a thread-safe lock
private static final Object sSyncAdapterLock = new Object();
public SyncService() {
}
@Override
public void onCreate() {
super.onCreate();
synchronized (sSyncAdapterLock) {
sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
}
}
@Override
public IBinder onBind(Intent intent) {
return sSyncAdapter.getSyncAdapterBinder();
}
}
3.创建xml/syncadapter.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.crazyman.accountsyncdemo.provider"
android:accountType="com.crazyman.accountsyncdemo.type"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true"/>
4.在AndroidManifest.xml中加入权限和同步Service:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
......
<service
android:name=".SyncService"
android:enabled="true"
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>
使用同步功能
//添加账号
Account account = new Account("account_test", "com.crazyman.accountsyncdemo.type");
AccountManager accountManager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
accountManager.addAccountExplicitly(account, null, null);
ContentResolver.setIsSyncable(newAccount,MyContract.CONTENT_AUTHORITY,1);
ContentResolver.setSyncAutomatically(newAccount,MyContract.CONTENT_AUTHORITY,true);
ContentResolver.addPeriodicSync(newAccount,MyContract.CONTENT_AUTHORITY, Bundle.EMPTY,10);//注意单位是秒
android 源码中设置的最短同步周期是1分钟,所以用模拟器测试比较准确,而国产机会进行各种修改,我在魅蓝NOTE2中测试最短是30分钟
手动调用同步功能:
ContentResolver.requestSync(newAccount,MyContract.CONTENT_AUTHORITY,Bundle.EMPTY);