我是Android开发的新手。我想开发Android应用程序,它需要在线以及离线工作。如果它离线我将在本地sqLite Db中存储api调用方法名称类型和json字符串。一旦网络建立,我需要打电话给api。所以要实现这一点,我尝试使用同步适配器框架工作。但它没有正常工作。我在这里发布了我的代码。请帮助我。
我在下面提到了这些链接。
https://chariotsolutions.com/blog/post/android-data-sync/
http://www.zoftino.com/sync-data-between-device-and-server-in-android
http://www.oodlestechnologies.com/blogs/How-to-use-Sync-Adapter-In-Android
MainActivity
public class MainActivity extends AppCompatActivity {
Button btnCreate, btnSignup;
public String TAG = "MainActivity";
public static final String AUTHORITY = Constants.AUTHORITY;
public static final String ACCOUNT_TYPE = Constants.ACCOUNT_TYPE;
public static final String ACCOUNT = Constants.ACCOUNT_NAME;
public static final int SYNC_INTERVAL = 60;
private Account mAccount;
private ContentResolver mContentResolver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCreate = (Button) findViewById(R.id.btnAccount);
btnSignup = (Button) findViewById(R.id.btnSignup);
try
{
btnCreate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mAccount = CreateSyncAccount(getApplicationContext());
mContentResolver = getContentResolver();
ContentResolver.setIsSyncable(mAccount, AUTHORITY, 1);
ContentResolver.setSyncAutomatically(mAccount, AUTHORITY, true);
ContentResolver.addPeriodicSync(mAccount, AUTHORITY, Bundle.EMPTY, SYNC_INTERVAL);
Log.i(TAG, "onClick: AFter setSyncAutomatically" );
}
});
}catch (Exception ex)
{
Log.i(TAG, "Error : " + ex.getMessage().toString());
}
}
private Account CreateSyncAccount(Context context) {
Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE);
AccountManager accountManager =
(AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS}, 31);
}
Account accounts[] = accountManager.getAccountsByType(ACCOUNT_TYPE);
if (accounts == null || accounts.length < 1) {
if (accountManager.addAccountExplicitly(newAccount, null, null)) {
return newAccount;
} else {
Log.i("sync activity", "error creating account");
}
} else {
return accounts[0];
}
return null;
}
}
清空Stub Authenticator和ContentProvider
身份验证服务
public class AuthenticatorService extends Service {
private static final String TAG = "AuthenticatorService";
private static Authenticator sAccountAuthenticator = null;
private Authenticator authenticator;
@Override
public void onCreate() {
authenticator = new Authenticator(this);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return authenticator.getIBinder();
}
}
SyncService
public class SyncService extends Service {
private static SyncAdapter syncAdapter = null;
private static final Object syncAdapterLock = new Object();
public void onCreate() {
synchronized (syncAdapterLock) {
Log.i("Sync Started", "SyncService started");
if (syncAdapter == null)
syncAdapter = new SyncAdapter(this, true);
Log.i("Sync Stoped", "SyncService finished");
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return syncAdapter.getSyncAdapterBinder();
}
}
同步适配器:
public class SyncAdapter extends AbstractThreadedSyncAdapter {
private static final String TAG = SyncAdapter.class.getSimpleName();
private ContentResolver contentResolver;
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {
super(context, autoInitialize, allowParallelSyncs);
this.contentResolver = context.getContentResolver();
Log.i(TAG, "ReaderSyncAdapter created");
// manager = new ApolloBackendConfigurationManager(context);
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.i(TAG, "onPerformSync: Sync called" );
Toast.makeText(getContext(), "Sync Called at " + Calendar.getInstance().getTime().toString(), Toast.LENGTH_SHORT).show();
}
}
清单
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="arasan.com.syncadap">
<uses-permission android:name="android.permission.READ_SYNC_STATS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"></uses-permission>
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name=".Provider.SyncContentProvider"
android:authorities="@string/Authority"
android:syncable="true"
android:exported="false"
android:label="SyncProvider" />
<service android:name=".Services.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=".Services.SyncService"
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>
</application>
</manifest>
身份验证器XML
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="@string/AccountType"
android:icon="@drawable/ic_launcher"
android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"
/>
SyncAdapter XML
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="@string/Authority"
android:accountType="@string/AccountType"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true">
</sync-adapter>