I have tried Virgil Dobjanschi patterns A and B and made a conclusion that i want to use pattern C because in that case I can use google based code which take care about how to get may data to a device if i have non-stable network connection and so on... But I didn't find how to implement this in right way. Especially when you consider that the database is large enough to do syncing it all every time.
I did something like this
when CursorLoader did the query to show BizInbox the query returned the cursor and started SyncAdapter which should get data and stop its activity
But my problem is The SyncAdatert's onPerformSync start agin and again. And it looks like the endless cycle when the cursor reload its data and start onPerformSync and so on... And SyncAdapter do it in parallel without any queue as i hoped.
I should notice that the REST back end process data correctly and the second request which do onPerformSync have no data because it used If-Modified-Since http header.
It is obviously i did something wrong, becuase my SyncAdapter did not do sync backoff and did requests without end.
When i did if (!ContentResolver.isSyncActive(mConnectedAccount, Scheme.AUTHORITY)) { ContentResolver.requestSync( mConnectedAccount, // Sync account Scheme.AUTHORITY, // Content authority b); // Extras } else { Log.d(TAG, "> runSyncAdaterForClaimBizInbox skip starting adapter it is already active"); }
i was able to win the problem but the question remained how to perform this syncing if need to sync part of data - not all data ContentResolver.isSyncActive(mConnectedAccount, Scheme.AUTHORITY) - this method can not give info what part of data it is syncing and i don't have a queue for some reasons here. How to manage this problem ?
Please, help me to find the errors or may be somebody has the Pattern C compilable code to find out how to implement this pattern right.
Thanks in advance.
The code below:
public class ContentProvider {
@Override
public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {
final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
final String orderBy = prepareQuery(uri, sortOrder, qb);
final SQLiteDatabase db = databaseHelper.getReadableDatabase();
final Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
runSyncAdapterForQuery(uri);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
void runSyncAdapterForQuery(Uri uri) {
switch (uriMatcher.match(uri)) {
case BIZ_INBOX:
runSyncAdaterForBizInbox(METHOD_GET);
break;
}
}
void runSyncAdaterForBizInbox(String method) {
Bundle b = new Bundle();
b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
b.putString(METHOD_EXTRA, method);
b.putInt(RESOURCE_TYPE_EXTRA, RESOURCE_TYPE_BIZ_INBOX);
Account mConnectedAccount = new Account(BPalAccountGeneral.ACCOUNT_NAME, BPalAccountGeneral.ACCOUNT_TYPE);
//if (!ContentResolver.isSyncActive(mConnectedAccount, Scheme.AUTHORITY)) { Do i need this ? Where is Sync Adapters queue ?
ContentResolver.requestSync(
mConnectedAccount, // Sync account
Scheme.AUTHORITY, // Content authority
b); // Extras
//}
}
}
SyncAdapter
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
String accessToken = "some_token";
switch (resourceType) {
case UNKNOWN_RESOURCE_TYPE:
//do update all ...
break;
case RESOURCE_TYPE_BIZ_INBOX:
if (method.equals(METHOD_GET)) {
String url = "some_inbox_url"
GetBizInboxRequest request = new GetBizInboxRequest();
BizInboxDAO BizInboxDAO = new BizInboxDAO();
String lastModified = BizInboxDAO.getLastModified(getContext().getContentResolver());
RestMethodResult<RestListEntityContainer<BizInboxEntity>> restMethodResult =
request.getBizInboxItems(
url,
null,
lastModified,
accessToken);
int statusCode = restMethodResult.getStatusCode();
if (statusCode == MobileConstant.HTTP_OK) {
List<BizInboxEntity> serverBizInboxEntities = restMethodResult.getResource().getList();
for (BizInboxEntity entity : serverBizInboxEntities) {
BizInboxDAO.insertyData(getContext().getContentResolver(), entity);
syncResult.stats.numInserts++;
}
if(syncResult.stats.numInserts > 0) {
Log.d(TAG, "> onPerformSync BizInboxDAO.sendNotification ");
BizInboxDAO.sendNotification(getContext().getContentResolver());
}
} else {
syncResult.stats.numIoExceptions++;
syncResult.databaseError = true;
}
}
break;
default:
break;
}
}