package com.onemore.karungguniapp; import android.accounts.Account; import android.content.*; import android.database.Cursor; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; import com.turbomanage.httpclient.ParameterMap; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayInputStream; import java.io.IOException; /** * Handle the transfer of data between a server and an * app, using the Android sync adapter framework. */ public class SyncAdapter extends AbstractThreadedSyncAdapter { // Global variables // Define a variable to contain a content resolver instance ContentResolver mContentResolver; /** * Set up the sync adapter */ public SyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); /* * If your app uses a content resolver, get an instance of it * from the incoming Context */ mContentResolver = context.getContentResolver(); } /** * Set up the sync adapter. This form of the * constructor maintains compatibility with Android 3.0 * and later platform versions */ public SyncAdapter( Context context, boolean autoInitialize, boolean allowParallelSyncs) { super(context, autoInitialize, allowParallelSyncs); /* * If your app uses a content resolver, get an instance of it * from the incoming Context */ mContentResolver = context.getContentResolver(); } /* * Specify the code you want to run in the sync adapter. The entire * sync adapter runs in a background thread, so you don't have to set * up your own background processing. */ @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { Log.w("SYNC_ADAPTER", "Syncing..."); // there are a few general tasks your implementation should perform: // conencting to a server // downloading and uploading data // handling data conflicts or determing how current the data is // clean up (close connectiongs and clean up temp files and caches) // Step 1: Get latest advertisement, seller and kg data from the server String ADVERTISEMENTS_SELECTION = null; String[] ADVERTISEMENTS_SELECTION_ARGS = null; Bundle lastSync = getLastSync(this.getContext()); // If seller data hasn't been synced, get it now if (lastSync.getLong(AppData.Sellers.TABLE_NAME) == -1) { JSONArray sellers; Bundle sellerResult = RestClient.query(AppData.Sellers.CONTENT_URI, null, null, null, null, null); if (sellerResult.getInt("status") == 200) { try { sellers = RestClient.parseJsonArray(new ByteArrayInputStream(sellerResult.getString("response").getBytes("UTF-8"))); ContentValues values; JSONObject seller; // Loop through the advertisements for (int i = 0; i < sellers.length(); i++) { seller = sellers.getJSONObject(i); values = new ContentValues(); values.put(AppData.Sellers._ID, seller.getString(AppData.Sellers._ID)); values.put(AppData.Sellers.COLUMN_NAME_EMAIL, seller.getString(AppData.Sellers.COLUMN_NAME_EMAIL)); values.put(AppData.Sellers.COLUMN_NAME_DISPLAY_NAME, seller.getString(AppData.Sellers.COLUMN_NAME_DISPLAY_NAME)); values.put(AppData.Sellers.COLUMN_NAME_ADDRESS, seller.getString(AppData.Sellers.COLUMN_NAME_ADDRESS)); values.put(AppData.Sellers.COLUMN_NAME_ADDRESS_LAT, seller.getString(AppData.Sellers.COLUMN_NAME_ADDRESS_LAT)); values.put(AppData.Sellers.COLUMN_NAME_ADDRESS_LONG, seller.getString(AppData.Sellers.COLUMN_NAME_ADDRESS_LONG)); // Insert to local DB mContentResolver.insert(AppData.Sellers.CONTENT_ID_URI_BASE, values); } Log.w("SYNC_ADAPTER", "Inserted into sellers."); // Save sync status Long now = System.currentTimeMillis() / 1000; setLastSync(getContext(), AppData.Sellers.TABLE_NAME, now); Cursor mCursor = mContentResolver.query(AppData.Sellers.CONTENT_URI, null, null, null, null); Log.w("SYNC_ADAPTER", "Count: " + mCursor.getCount()); } catch (JSONException e) { e.printStackTrace(); return; } catch (IOException e) { e.printStackTrace(); return; } } } // If KG data hasn't been synced, get it now if (lastSync.getLong(AppData.Sellers.TABLE_NAME) == -1) { JSONArray karunggunis; Bundle karungguniResult = RestClient.query(AppData.KarungGunis.CONTENT_URI, null, null, null, null, null); if (karungguniResult.getInt("status") == 200) { try { karunggunis = RestClient.parseJsonArray(new ByteArrayInputStream(karungguniResult.getString("response").getBytes("UTF-8"))); ContentValues values; JSONObject karungguni; // Loop through the advertisements for (int i = 0; i < karunggunis.length(); i++) { karungguni = karunggunis.getJSONObject(i); values = new ContentValues(); values.put(AppData.KarungGunis._ID, karungguni.getString(AppData.KarungGunis._ID)); values.put(AppData.KarungGunis.COLUMN_NAME_EMAIL, karungguni.getString(AppData.KarungGunis.COLUMN_NAME_EMAIL)); values.put(AppData.KarungGunis.COLUMN_NAME_DISPLAY_NAME, karungguni.getString(AppData.KarungGunis.COLUMN_NAME_DISPLAY_NAME)); values.put(AppData.KarungGunis.COLUMN_NAME_RATING, karungguni.getString(AppData.KarungGunis.COLUMN_NAME_RATING)); // Insert to local DB mContentResolver.insert(AppData.KarungGunis.CONTENT_ID_URI_BASE, values); } Log.w("SYNC_ADAPTER", "Inserted into Karung Gunis."); // Save sync status Long now = System.currentTimeMillis() / 1000; setLastSync(getContext(), AppData.KarungGunis.TABLE_NAME, now); Cursor mCursor = mContentResolver.query(AppData.KarungGunis.CONTENT_URI, null, null, null, null); Log.w("SYNC_ADAPTER", "Count: " + mCursor.getCount()); } catch (JSONException e) { e.printStackTrace(); return; } catch (IOException e) { e.printStackTrace(); return; } } } // If lastSync is not empty, set the required selections if (lastSync.getLong(AppData.Advertisements.TABLE_NAME) != -1) { ADVERTISEMENTS_SELECTION = "/latest/" + lastSync.getLong(AppData.Advertisements.TABLE_NAME); } JSONArray advertisements; Bundle result = RestClient.query(AppData.Advertisements.CONTENT_URI, null, ADVERTISEMENTS_SELECTION, ADVERTISEMENTS_SELECTION_ARGS, null, null); if (result.getInt("status") == 200) { try { advertisements = RestClient.parseJsonArray(new ByteArrayInputStream(result.getString("response").getBytes("UTF-8"))); ContentValues values; JSONObject advertisement; // Loop through the advertisements for (int i = 0; i < advertisements.length(); i++) { advertisement = advertisements.getJSONObject(i); values = new ContentValues(); values.put(AppData.Advertisements._ID, advertisement.getString(AppData.Advertisements._ID)); values.put(AppData.Advertisements.COLUMN_NAME_OWNER, advertisement.getString(AppData.Advertisements.COLUMN_NAME_OWNER)); values.put(AppData.Advertisements.COLUMN_NAME_TITLE, advertisement.getString(AppData.Advertisements.COLUMN_NAME_TITLE)); values.put(AppData.Advertisements.COLUMN_NAME_DESCRIPTION, advertisement.getString(AppData.Advertisements.COLUMN_NAME_DESCRIPTION)); values.put(AppData.Advertisements.COLUMN_NAME_PHOTO, advertisement.getString(AppData.Advertisements.COLUMN_NAME_PHOTO)); values.put(AppData.Advertisements.COLUMN_NAME_CATEGORY, advertisement.getString(AppData.Advertisements.COLUMN_NAME_CATEGORY)); values.put(AppData.Advertisements.COLUMN_NAME_STATUS, advertisement.getString(AppData.Advertisements.COLUMN_NAME_STATUS)); values.put(AppData.Advertisements.COLUMN_NAME_TIMING_START, advertisement.getString(AppData.Advertisements.COLUMN_NAME_TIMING_START)); values.put(AppData.Advertisements.COLUMN_NAME_TIMING_END, advertisement.getString(AppData.Advertisements.COLUMN_NAME_TIMING_END)); values.put(AppData.COLUMN_NAME_DATE_CREATED, advertisement.getString(AppData.COLUMN_NAME_DATE_CREATED)); // Insert to local DB mContentResolver.insert(AppData.Advertisements.CONTENT_ID_URI_BASE, values); } Log.w("SYNC_ADAPTER", "Inserted."); // Save sync status Long now = System.currentTimeMillis() / 1000; setLastSync(getContext(), AppData.Advertisements.TABLE_NAME, now); Cursor mCursor = mContentResolver.query(AppData.Advertisements.CONTENT_URI, null, null, null, null); Log.w("SYNC_ADAPTER", "Count: " + mCursor.getCount()); } catch (JSONException e) { e.printStackTrace(); return; } catch (IOException e) { e.printStackTrace(); return; } } // Step 2: Publish local advertisement data to the server JSONObject advertisement; ADVERTISEMENTS_SELECTION = "_ID LIKE 'unsynced_%'"; Cursor mCursor = mContentResolver.query(AppData.Advertisements.CONTENT_URI, null, ADVERTISEMENTS_SELECTION, null, null); if (mCursor != null && mCursor.getCount() > 0 && mCursor.moveToFirst()) { Log.w("SYNC_ADAPTER", "Publishing to server"); // Loop through each row and send the data to the server // Update the _ID field to the new value ParameterMap params = new ParameterMap(); do { params.put(AppData.Advertisements.COLUMN_NAME_OWNER, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_OWNER))); params.put(AppData.Advertisements.COLUMN_NAME_TITLE, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_TITLE))); params.put(AppData.Advertisements.COLUMN_NAME_DESCRIPTION, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_DESCRIPTION))); params.put(AppData.Advertisements.COLUMN_NAME_PHOTO, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_PHOTO))); params.put(AppData.Advertisements.COLUMN_NAME_CATEGORY, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_CATEGORY))); params.put(AppData.Advertisements.COLUMN_NAME_STATUS, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_STATUS))); params.put(AppData.Advertisements.COLUMN_NAME_TIMING_START, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_TIMING_START))); params.put(AppData.Advertisements.COLUMN_NAME_TIMING_END, mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements.COLUMN_NAME_TIMING_END))); // params.put(AppData.COLUMN_NAME_DATE_CREATED, mCursor.getString(mCursor.getColumnIndex(AppData.COLUMN_NAME_DATE_CREATED))); result = RestClient.insert(AppData.Advertisements.CONTENT_ID_URI_BASE, params, null); if (result.getInt("status") == 201) { try { advertisement = RestClient.parseJsonObject(new ByteArrayInputStream(result.getString("response").getBytes("UTF-8"))); String _id = advertisement.getString("_id"); ContentValues updatedId = new ContentValues(); updatedId.put("_id", _id); String[] selectionArgs = new String[] { mCursor.getString(mCursor.getColumnIndex(AppData.Advertisements._ID)) }; int rowsUpdated = mContentResolver.update(AppData.Advertisements.CONTENT_ID_URI_BASE, updatedId, "_ID = ?", selectionArgs); if (rowsUpdated == 0) { Log.w("SYNC_ADAPTER", "Updating error occurred ;_;"); } } catch (JSONException e) { e.printStackTrace(); return; } catch (IOException e) { e.printStackTrace(); return; } } } while (mCursor.moveToNext()); } } public static Bundle getLastSync(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); Bundle lastSync = new Bundle(); lastSync.putLong(AppData.Advertisements.TABLE_NAME, prefs.getLong("lastSync." + AppData.Advertisements.TABLE_NAME, -1)); lastSync.putLong(AppData.Sellers.TABLE_NAME, prefs.getLong("lastSync." + AppData.Sellers.TABLE_NAME, -1)); lastSync.putLong(AppData.KarungGunis.TABLE_NAME, prefs.getLong("lastSync." + AppData.KarungGunis.TABLE_NAME, -1)); return lastSync; } public static void setLastSync(Context context, String tableName, Long time) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); editor.putLong("lastSync." + tableName, time); editor.commit(); } }