| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 |
- package com.ivalentin.margolariak;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLEncoder;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.regex.Pattern;
- import android.app.Activity;
- import android.app.Dialog;
- import android.content.Context;
- import android.content.SharedPreferences;
- import android.database.Cursor;
- import android.database.DatabaseUtils;
- import android.database.sqlite.SQLiteDatabase;
- import android.os.AsyncTask;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import org.json.*;
- /**
- * AsyncTask that synchronizes the online database to the device.
- * Is run every time the app is started, and periodically in the background.
- *
- * @author Inigo Valentin
- *
- */
- class Sync extends AsyncTask<Void, Void, Void> {
-
- private final Context myContextRef;
- private ProgressBar pbSync;
- private ImageView ivSync;
- private Dialog dialog;
- private MainActivity activity;
- private int fg;
- private String strings[];
- private boolean doProgress = false;
- private long millis = 0;
- private TextView tv;
-
-
- /**
- * Things to do before sync. Namely, displaying a spinning progress bar.
- *
- * @see android.os.AsyncTask#onPreExecute()
- */
- @Override
- protected void onPreExecute(){
- //If pbSync and dialog are not null, it means that the sync is being done on the foreground
- if (pbSync != null) {
- //Show the spinning bar
- pbSync.setVisibility(View.VISIBLE);
- ivSync.setVisibility(View.GONE);
- }
- if (dialog != null) {
- //Show the dialog and assign the elements on it
- dialog.show();
- strings = new String[10];
- strings[0] = myContextRef.getString(R.string.dialog_sync_text_0);
- strings[1] = myContextRef.getString(R.string.dialog_sync_text_1);
- strings[2] = myContextRef.getString(R.string.dialog_sync_text_2);
- strings[3] = myContextRef.getString(R.string.dialog_sync_text_3);
- strings[4] = myContextRef.getString(R.string.dialog_sync_text_4);
- strings[5] = myContextRef.getString(R.string.dialog_sync_text_5);
- strings[6] = myContextRef.getString(R.string.dialog_sync_text_6);
- strings[7] = myContextRef.getString(R.string.dialog_sync_text_7);
- strings[8] = myContextRef.getString(R.string.dialog_sync_text_8);
- strings[9] = myContextRef.getString(R.string.dialog_sync_text_8); //In case I get a 9;
- tv = (TextView) dialog.findViewById(R.id.tv_dialog_sync_text);
- int idx = (int) (Math.random() * 9);
- tv.setText(strings[idx]);
- doProgress = true;
- }
- Log.d("Sync", "Starting full sync");
- }
-
- /**
- * Things to do after sync. Namely, hiding the spinning progress bar.
- *
- * @see android.os.AsyncTask#onPreExecute()
- */
- @Override
- protected void onPostExecute(Void v){
- //If pbSync and dialog are not null, it means that the sync is being done on the foreground
- if (pbSync != null) {
- //Hide the spinner
- pbSync.setVisibility(View.GONE);
- ivSync.setVisibility(View.VISIBLE);
- }
- if (dialog != null){
- //Close the dialog
- dialog.dismiss();
- //Check db version again
- SQLiteDatabase db = myContextRef.openOrCreateDatabase(GM.DB.NAME, Activity.MODE_PRIVATE, null);
- if (db.isReadOnly()){
- Log.e("Db ro", "Database is locked and in read only mode. Skipping sync.");
- return;
- }
- //Get database version
- Cursor cursor;
- int dbVersion;
- cursor = db.rawQuery("SELECT sum(version) AS v FROM version;", null);
- cursor.moveToFirst();
- dbVersion = cursor.getInt(0);
- cursor.close();
- db.close();
- //If the database is on it's initial version (i.e: There is no data, new or old)
- if (true){ //TODO dbVersion == GM.DATA.DEFAULT.DEFAULT_PREF_DB_VERSION){
- Log.e("SYNC", "Full sync failed");
- //Create a message dialog
- final Dialog dial = new Dialog(activity);
- dial.setCancelable(false);
-
- //Set up the window
- dial.requestWindowFeature(Window.FEATURE_NO_TITLE);
- dial.setContentView(R.layout.dialog_sync_failed);
-
- //Set button
- Button btClose = (Button) dial.findViewById(R.id.bt_dialog_sync_failed_close);
- btClose.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- dial.dismiss();
- activity.finish();
- }
- });
-
- //Show the dialog
- dial.show();
- }
- else{
- Log.d("SYNC", "Full sync finished");
- activity.loadSection(GM.SECTION.HOME);
- }
- }
- }
- /**
- * Called when the AsyncTask is created.
- * This constructor is intended for syncs on the background.
- *
- * @param myContextRef The Context of the calling activity.
- */
- public Sync(Activity myContextRef){
- this.myContextRef = myContextRef;
- }
- /**
- * Called when the AsyncTask is created.
- * This constructor is intended for syncs done from the foreground,
- * because it shows and hides a spinner (except for the initial one).
- *
- * @param myContextRef The Context of the calling activity.
- * @param pb The progress bar that will be shown while the sync goes on.
- */
- public Sync(Activity myContextRef, ProgressBar pb, ImageView iv) {
- this.myContextRef = myContextRef;
- dialog = null;
- pbSync = pb;
- ivSync = iv;
- fg = 1;
- }
-
- /**
- * Called when the AsyncTask is created.
- * This constructor is intended to use only in the first sync,
- * from the foreground, because a dialog will block the UI.
- *
- * @param myContextRef The Context of the calling activity.
- * @param d Dialog of the initial sync
- * @param pb The progress bar that will be shown while the sync goes on.
- * @param activity The calling MainActvity
- */
- public Sync(Activity myContextRef, ProgressBar pb, ImageView iv, Dialog d, MainActivity activity) {
- this.dialog = d;
- this.activity = activity;
- this.myContextRef = myContextRef;
- pbSync = pb;
- ivSync = iv;
- fg = 1;
- }
-
- /**
- * Called when the AsyncTask is created.
- *
- * @param context The Context of the calling activity.
- */
- public Sync(Context context) {
- this.myContextRef = context;
- pbSync = null;
- fg = 0;
- }
- @Override
- /**
- * Called when the AsyncTask is updated.
- * Used to change text in the sync window.
- */
- protected void onProgressUpdate(Void...progress) {
- if (doProgress){
- if (millis + 600 < System.currentTimeMillis()) {
- millis = System.currentTimeMillis();
- int idx = (int) (Math.random() * ((4) + 1));
- tv.setText(strings[idx]);
- }
- }
- }
- /**
- * Creates the URL required to performa a sync. Uses static data and data passed as arguments.
- *
- * @param user A unique user identifier.
- * @param version The db version of the client.
- * @param foreground 1 if the sync is done while the app is running, 0 otherwise.
- * @param lang Two letter language identifier.
- *
- * @return The URL that will be used for syncing.
- */
- private String buildUrl(String user, int version, int foreground, String lang){
- String url = "";
- try {
- url = GM.API.SERVER + GM.API.SYNC.PATH + "?" +
- GM.API.SYNC.KEY.CLIENT + "=" + URLEncoder.encode(GM.API.CLIENT, "UTF-8") + "&" +
- GM.API.SYNC.KEY.USER + "=" + URLEncoder.encode(user, "UTF-8") + "&" +
- GM.API.SYNC.KEY.ACTION + "=" + URLEncoder.encode(GM.API.SYNC.VALUE.ACTION, "UTF-8") + "&" +
- GM.API.SYNC.KEY.SECTION + "=" + URLEncoder.encode(GM.API.SYNC.VALUE.SECTION, "UTF-8") + "&" +
- GM.API.SYNC.KEY.VERSION + "=" + version + "&" +
- GM.API.SYNC.KEY.FOREGROUND + "=" + foreground + "&" +
- GM.API.SYNC.KEY.FORMAT + "=" + URLEncoder.encode(GM.API.SYNC.VALUE.FORMAT, "UTF-8") + "&" +
- GM.API.SYNC.KEY.LANG + "=" + URLEncoder.encode(lang, "UTF-8");
- }
- catch (java.io.UnsupportedEncodingException ex){
- Log.e("UTF-8", "Error encoding url for sync \"" + url + "\" - " + ex.toString());
- }
- return url;
- }
- /**
- * Recreates the database, dropping and then creating all the tables containing
- * data. "location" and "notification" tables are untouched.
- *
- * @param db A database connection.
- *
- * @return False if there were errors, true otherwise.
- */
- private boolean recreateDb(SQLiteDatabase db) {
- boolean result = true;
- try {
- db.execSQL(GM.DB.QUERY.DROP.ACTIVITY);
- db.execSQL(GM.DB.QUERY.DROP.ACTIVITY_COMMENT);
- db.execSQL(GM.DB.QUERY.DROP.ACTIVITY_IMAGE);
- db.execSQL(GM.DB.QUERY.DROP.ACTIVITY_ITINERARY);
- db.execSQL(GM.DB.QUERY.DROP.ACTIVITY_TAG);
- db.execSQL(GM.DB.QUERY.DROP.ALBUM);
- db.execSQL(GM.DB.QUERY.DROP.FESTIVAL);
- db.execSQL(GM.DB.QUERY.DROP.FESTIVAL_DAY);
- db.execSQL(GM.DB.QUERY.DROP.FESTIVAL_EVENT);
- db.execSQL(GM.DB.QUERY.DROP.FESTIVAL_EVENT_IMAGE);
- db.execSQL(GM.DB.QUERY.DROP.FESTIVAL_OFFER);
- db.execSQL(GM.DB.QUERY.DROP.PEOPLE);
- db.execSQL(GM.DB.QUERY.DROP.PHOTO);
- db.execSQL(GM.DB.QUERY.DROP.PHOTO_ALBUM);
- db.execSQL(GM.DB.QUERY.DROP.PHOTO_COMMENT);
- db.execSQL(GM.DB.QUERY.DROP.PLACE);
- db.execSQL(GM.DB.QUERY.DROP.POST);
- db.execSQL(GM.DB.QUERY.DROP.POST_COMMENT);
- db.execSQL(GM.DB.QUERY.DROP.POST_IMAGE);
- db.execSQL(GM.DB.QUERY.DROP.POST_TAG);
- db.execSQL(GM.DB.QUERY.DROP.SETTINGS);
- db.execSQL(GM.DB.QUERY.DROP.SPONSOR);
- db.execSQL(GM.DB.QUERY.DROP.VERSION);
- //TODO: Is this really necessary?
- Thread.sleep(1000);
- db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY);
- db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_COMMENT);
- db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_IMAGE);
- db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_ITINERARY);
- db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_TAG);
- db.execSQL(GM.DB.QUERY.CREATE.ALBUM);
- db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL);
- db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_DAY);
- db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_EVENT);
- db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_EVENT_IMAGE);
- db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_OFFER);
- db.execSQL(GM.DB.QUERY.CREATE.PEOPLE);
- db.execSQL(GM.DB.QUERY.CREATE.PHOTO);
- db.execSQL(GM.DB.QUERY.CREATE.PHOTO_ALBUM);
- db.execSQL(GM.DB.QUERY.CREATE.PHOTO_COMMENT);
- db.execSQL(GM.DB.QUERY.CREATE.PLACE);
- db.execSQL(GM.DB.QUERY.CREATE.POST);
- db.execSQL(GM.DB.QUERY.CREATE.POST_COMMENT);
- db.execSQL(GM.DB.QUERY.CREATE.POST_IMAGE);
- db.execSQL(GM.DB.QUERY.CREATE.POST_TAG);
- db.execSQL(GM.DB.QUERY.CREATE.SETTINGS);
- db.execSQL(GM.DB.QUERY.CREATE.SPONSOR);
- db.execSQL(GM.DB.QUERY.CREATE.VERSION);
- //TODO: Is this really necessary?
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- Log.e("SYNC", "Couldn't wait for the database to be recreated: " + e.toString());
- }
- catch (Exception ex) {
- result = false;
- Log.e("SYNC", "Error recreating the database: " + ex.toString());
- }
- return result;
- }
- /**
- * Finds out the type of a column of a table in the database.
- *
- * @param db A database connection.
- * @param table The name of the table.
- * @param idx Index of the column in the database (starting on 0).
- *
- * @return GM.DB.COLUMN.INT, GM.DB.COLUMN.DATETIME, GM.DB.COLUMN.VARCHAR (default).
- */
- private int getColumnType(SQLiteDatabase db, String table, int idx) {
- String type = "";
- Cursor typeCursor;
- try {
- String Query = "PRAGMA table_info(" + table + ")";
- typeCursor = db.rawQuery(Query, null);
- typeCursor.moveToPosition(idx);
- type = typeCursor.getString(2);
- typeCursor.close();
- }
- catch(Exception ex){
- Log.e("SYNC", "Unable to reliably determine the type of the column '" + idx + "' of the table " + table + ": " + ex.toString());
- }
- if (type.equals("INT")) {
- return GM.DB.COLUMN.INT;
- }
- if (type.equals("DATETIME")) {
- return GM.DB.COLUMN.DATETIME;
- }
- return GM.DB.COLUMN.VARCHAR;
- }
- /**
- * Stores version data for each section in the database.
- * Uses a custom JSON parser.
- *
- * @param db Database store the data.
- * @param versions List of strings with data about the versions.
- *
- * @return False if there were errors, true otherwise.
- */
- private boolean saveVersions(SQLiteDatabase db, String versions){
- String str = versions;
- String key;
- boolean result = true;
- int value;
- int totalVersions = 0;
- //If I ever have a database with more than 99 public sections (not tables), I'll have to change this. Also, ask for a raise.
- int[] values = new int[99];
- String[] keys = new String[99];
- try {
- while (str.indexOf("{") > 0){
- key = str.substring(str.indexOf("{\"") + 2, str.indexOf("\":"));
- str = str.substring(str.indexOf("\":\"") + 3);
- value = Integer.parseInt(str.substring(0, str.indexOf("\"")));
- str = str.substring(str.indexOf("}") + 1);
- keys[totalVersions] = key;
- values[totalVersions] = value;
- totalVersions ++;
- }
- if (totalVersions > 0 && totalVersions < 99){
- db.execSQL(GM.DB.QUERY.CREATE.VERSION);
- db.execSQL(GM.DB.QUERY.EMPTY.VERSION);
- for (int i = 0; i < totalVersions; i ++){
- db.execSQL("INSERT INTO version VALUES ('" + keys[i] + "', " + values[i] + ");");
- }
- }
- else{
- result = false;
- }
- }
- catch (Exception ex){
- result = false;
- Log.e("SYNC", "Error saving the remote db versions: " + ex.toString());
- }
- return result;
- }
- /**
- * Stores version data for each section in the database.
- * Uses a custom JSON parser.
- *
- * @param db Database store the data.
- * @param data List of strings in json format with the tables.
- *
- * @return False if there were errors, true otherwise.
- */
- private boolean saveData(SQLiteDatabase db, String data){
- String str;
- String key;
- String value;
- boolean result = true;
- try{
- str = data.substring(data.indexOf("[") + 1, data.lastIndexOf("]"));
- while (str.indexOf("}") > 0){
- try {
- key = str.substring(str.indexOf("\"") + 1, str.indexOf("\"", str.indexOf(":") - 1));
- value = str.substring(str.indexOf("[") + 1, str.indexOf("]"));
- str = str.substring(str.indexOf("]") + 1);
- if (!saveTable(db, key, value)){
- //Finish the loop if there is an error
- return false;
- }
- str = str.substring(str.indexOf("}") + 1);
- }
- catch (Exception ex){
- //End of string
- Log.d("SYNC", "End of data string:" + ex.toString());
- str = "";
- }
- }
- }
- catch (Exception ex){
- Log.e("SYNC", "Error saving the remote db data: " + ex.toString());
- result = false;
- }
- return result;
- }
- /**
- * Stores a table data into the database.
- * Uses a custom JSON parser.
- *
- * @param db Database to store the data.
- * @param table Name of the table.
- * @param data String in JSON format with the data of the table.
- * @return False if there were errors, true otherwise.
- */
- private boolean saveTable(SQLiteDatabase db, String table, String data) {
- int type, i;
- JSONObject jsonObj;
- String[] values = new String[99];
- String[] columns = new String[99];
- String val, row;
- String str = data;
- List<String> queries = new ArrayList<>();
- //The first query has to delete all entries
- queries.add("DELETE FROM " + table + ";");
- //Process each row
- while (str.contains("{\"") && str.contains("\"}")) {
- row = str.substring(str.indexOf("{\""), str.indexOf("\"}") + 2);
- i = 0;
- try {
- //Create a json object with the collumn names and values of the row...
- jsonObj = new JSONObject(row);
- Iterator<?> keys = jsonObj.keys();
- //... and loop through it.
- while (keys.hasNext()) {
- String key = (String) keys.next();
- String value = jsonObj.get(key).toString();
- columns[i] = key;
- values[i] = value;
- i++;
- }
- //Start building the query
- String q = "INSERT INTO " + table + "(";
- //Add column names
- for (int j = 0; j < i; j++) {
- q = q + columns[j] + ", ";
- }
- q = q.substring(0, q.length() - 2) + ") VALUES (";
- //Loop trough values
- for (int j = 0; j < i; j++) {
- //If the value is empty, I dont care what tipe is it, it will be 'null'.
- if (values[j].length() == 0) {
- val = "null";
- q = q + val + ", ";
- }
- //If the value is not empty, I need the type
- else {
- type = getColumnType(db, table, j);
- switch (type) {
- case GM.DB.COLUMN.INT:
- //Check that is really a number to prevent injection.
- if (Pattern.matches("\\-?\\d+", values[j]))
- q = q + values[j] + ", ";
- else{
- //If its not and actually number, just insert null to avoid problems.
- q = q + "null, ";
- }
- break;
- case GM.DB.COLUMN.DATETIME:
- //The API formats ('YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS') are good for inserting. Just escape and add quotes.
- q = q + DatabaseUtils.sqlEscapeString(values[j]) + ", ";
- break;
- default: //VARCHAR
- //Just escape and add quotes.
- q = q + DatabaseUtils.sqlEscapeString(values[j]) + ", ";
- }
- }
- }
- //End the query string and add it to the array.
- q = q.substring(0, q.length() - 2) + ")";
- queries.add(q);
- }
- catch (JSONException e) {
- Log.e("SYNC", "Error parsing table '" + table + "': " + e.toString());
- return false;
- }
- catch (Exception ex) {
- Log.e("SYNC", "Error inserting data from remote table " + table + " into the local db: " + ex.toString());
- return false;
- }
- //Process str for the next loop pass.
- str = str.substring(str.indexOf("\"}") + 2);
- }
- //If I get to this point, there were no errors, and I can safely execute the queries
- try {
- int totalQueries = queries.size();
- for (i = 0; i < totalQueries; i++) {
- db.execSQL(queries.get(i));
- }
- } catch (Exception ex) {
- Log.e("SYNC", "Error inserting data from remote table " + table + " into the local db: " + ex.toString().substring(18 * ex.toString().length() / 20));
- //I don't put a 'return false;' here because I dont want to loose the whole table for just one row.
- }
- return true;
- }
- /**
- * The sweet stuff. Actually performs the sync.
- */
- @Override
- protected Void doInBackground(Void... params) {
- //Get preferences
- SharedPreferences preferences = myContextRef.getSharedPreferences(GM.DATA.DATA, Context.MODE_PRIVATE);
- //Get useful data for the uri
- String userCode = preferences.getString(GM.DATA.KEY.USER, GM.DATA.DEFAULT.USER);
- //Get database. Stop if it's locked
- SQLiteDatabase db = myContextRef.openOrCreateDatabase(GM.DB.NAME, Activity.MODE_PRIVATE, null);
- if (db.isReadOnly()){
- Log.e("SYNC", "Database is locked and in read only mode. Skipping sync.");
- return null;
- }
- //Get database version
- Cursor cursor;
- int dbVersion;
- cursor = db.rawQuery("SELECT sum(version) AS v FROM version;", null);
- cursor.moveToFirst();
- dbVersion = cursor.getInt(0);
- cursor.close();
- URL url;
- String uri = buildUrl(userCode, dbVersion, fg, GM.getLang());
- try {
- url = new URL(uri);
- HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- int httpCode = urlConnection.getResponseCode();
- switch (httpCode){
- case 400: //Client error: Bad request
- Log.e("SYNC", "The server returned a 400 code (Client Error: Bad request) for the url \"" + uri + "\"");
- break;
- case 403: //Client error: Forbidden
- Log.e("SYNC", "The server returned a 403 code (Client Error: Forbidden) for the url \"" + uri + "\"");
- break;
- case 204: //Success: No content
- Log.d("SYNC", "The server returned a 204 code (Success: No content) for the url \"" + uri + "\". Stopping sync process...");
- break;
- case 200: //Success: OK
- Log.d("SYNC", "The server returned a 200 code (Success: OK) for the url \"" + uri + "\". Now syncing...");
- BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
- StringBuilder sb = new StringBuilder();
- String o;
- while ((o = br.readLine()) != null)
- sb.append(o);
- //Get the string with the sync json. (The whole page)
- String strSync = sb.toString();
- strSync = strSync.replace(":null", ":\"\"");
- //Get the JSON object from the string.
- JSONObject jsonSync = new JSONObject(strSync);
- jsonSync = new JSONObject(jsonSync.get("sync").toString().substring(1, jsonSync.get("sync").toString().length() - 1));
- //Get the string wit the versions in JSON format.
- String strVersion = jsonSync.get("version").toString();
- //Handmade parser, because with:
- //String strData = jsonSync.get("data").toString();
- //I get an error: "No value for data"
- String strData = strSync.substring(1, strSync.length() - 1);
- strData = strData.substring(strData.indexOf("{\"data\":"));
- //If the data is correctly parsed and stored, commit changes to the database.
- db.beginTransaction();
- //TODO: for save version apps, this is not needed, but I have to check it after an app update.
- //recreateDb(db);
- if (saveVersions(db, strVersion) && saveData(db, strData)){
- db.setTransactionSuccessful();
- Log.d("SYNC", "The sync process finished correctly. Changes to the database will be commited");
- }
- else{
- Log.e("SYNC", "The sync process did not finish correctly. Any changes made to the database will be reverted");
- }
- db.endTransaction();
- break;
- default:
- Log.e("SYNC", "The server returned an unexpected code (" + httpCode + ") for the url \"" + uri + "\"");
- }
- urlConnection.disconnect();
- return null;
- }
- catch (MalformedURLException e) {
- Log.e("SYNC", "Malformed URL (" + uri + "): " + e.toString());
- e.printStackTrace();
- }
- catch (IOException e) {
- Log.e("SYNC", "IOException for URL (" + uri + "): " + e.toString());
- e.printStackTrace();
- }
- catch (org.json.JSONException e) {
- Log.e("SYNC", "JSONException for URL (" + uri + "): " + e.toString());
- e.printStackTrace();
- }
- db.close();
- return null;
-
- }
- }
|