Q:

How to update your android sql database without crashing the app

My Database is currently at version 1 , I however have an app on the app store and I added a column for my new updates and I know I have to update my database or else when I sent my app for updates it will crash other users apps, how do I upgrade my database safely without crashing the app, I tried running the old version on my phone and the new upgrade using this code after I incremented but it keeps crashing without an error code. How can I upgrade my Database without destroying other users installed app on the app store safely?
My Database Class:
Error:

     Caused by: android.database.sqlite.SQLiteException: table items already exists (code 1): , while compiling: CREATE TABLE items (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, type TEXT NOT NULL, logo INTEGER NOT NULL DEFAULT 0, color INTEGER NOT NULL DEFAULT 0, created_date DATE NOT NULL DEFAULT CURRENT_TIMESTAMP);
        #################################################################
        Error Code : 1 (SQLITE_ERROR)
        Caused By : SQL(query) error or missing database.
            (table items already exists (code 1): , while compiling: CREATE TABLE items (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, type TEXT NOT NULL, logo INTEGER NOT NULL DEFAULT 0, color INTEGER NOT NULL DEFAULT 0, created_date DATE NOT NULL DEFAULT CURRENT_TIMESTAMP);)
        #################################################################

A:

The onUpgrade is ONLY called if your database version has incremented. So you don't need to check if it is newer.
So you have two options when upgrading your Database.
1) onUpgrade calls DROP TABLE and CREATE TABLE for fresh start
2) You run your alteration scripts in the onUpgrade callback. If you need to add a column or move data, handle that appropriately. In other words, if you add a non-nullable field, then you need to update all other fields. Or if you plan to move data around, you would query it, form your objects, then insert into the new structure.
But from the looks of it, you are just doing a simple column add. So you should be fine as long as you increment the static database number.
UPDATING TO HELP FURTHER
Ok so let's talk about managing your database in the non-room way. I now prefer to use Android's Room, but so you don't have to learn something new right now, I'll show you how I used to manage databases for you to utilize.
First I make an Interface like:
 public interface IA35Table {

        /*//////////////////////////////////////////////////////////////////////////////////////////////
        //EXTERNAL METHODS
        *///////////////////////////////////////////////////////////////////////////////////////////////
        /**
         * @return the SQL script to crate the table.
         */
        String getCreateTableScript();
        /**
         * @return the SQL script to upgrade the table.
         */
        String getUpgradeTableScript();

    }

Then I create a class for each table. Here is an example table:
 public class ContactFavoritesTable implements IA35Table {

    /*//////////////////////////////////////////////////////////
    // MEMBERS
    *///////////////////////////////////////////////////////////
    private static final String TAG = Globals.SEARCH_STRING + ContactFavoritesTable.class.getSimpleName();
    public static final String TABLE_NAME = "contactFavorites";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_CONTACT_FAVORITE_ID = "contactId";

    /*//////////////////////////////////////////////////////////
    // DATABASE METHODS
    *///////////////////////////////////////////////////////////
    @Override
    public String getCreateTableScript() {
        try{
            StringBuilder schema = new StringBuilder();

            schema.append("CREATE TABLE " + TABLE_NAME);
            schema.append(" ( ");
            schema.append(COLUMN_ID + " INTEGER PRIMARY KEY");
            schema.append(", ");
            schema.append(COLUMN_CONTACT_FAVORITE_ID + " INTEGER");
            schema.append(")");

            Log.d(TAG, "Creating Contact Favorites Table. Query: " + schema.toString());

            return schema.toString();
        }catch (Exception e){
            Log.e(TAG, "Failed to Create Favorites Table because: " + e.getMessage());
            return "";
        }
    }
    @Override
    public String getUpgradeTableScript() {
        try{
            String query = "DROP TABLE IF EXISTS " + TABLE_NAME;
            A35Log.d(TAG, "Dropping " + TABLE_NAME + " Table. Query: " + query);
            return query;
        }catch (Exception e){
            A35Log.e(TAG, "Failed to Drop Existing Database");
            return "";
        }
    }
}

Next up I make a generic DBHelper class that handles the simple DB interactions of open/close and scripting like:
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import android.util.Log;

import com.a35.interfaces.IA35Table;

import java.util.List;
import java.util.StringTokenizer;

/**
 * Created by App Studio 35 on 5/25/16.
 * <p>
 * Database helper class for Data Definition Language (DDL) and Data Manipulation Language(DML).
 */
public final class A35DBHelper extends SQLiteOpenHelper {

    /*///////////////////////////////////////////////////////////////////////////////////////////////
    //MEMBERS
    *////////////////////////////////////////////////////////////////////////////////////////////////
    private static final String TAG = A35DBHelper.class.getSimpleName();
    private static int sDatabaseVersion;
    private static String sDatabaseName = null;
    private static List<Class<? extends IA35Table>> sTables;

    /*//////////////////////////////////////////////////////////////////////////////////////////////
    // CONSTRUCTOR AND INIT
    *///////////////////////////////////////////////////////////////////////////////////////////////
    private A35DBHelper(Context context) {
        // Use the application context, which will ensure that you don't accidentally leak an Activity's context.
        super(context.getApplicationContext(), sDatabaseName, null, sDatabaseVersion);
    }
    /**
     * Used to set database name and version and supply classes that follow our design implementation
     *
     * @param databaseName the database name.
     * @param databaseVersion the database version.
     */
    public static void initialize(String databaseName, int databaseVersion, List<Class<? extends IA35Table>> tables) {
        sDatabaseName = databaseName;
        sDatabaseVersion = databaseVersion;
        sTables = tables;
    }

    /*///////////////////////////////////////////////////////////////////////////////////////////////
    //OVERRIDE METHODS
    *////////////////////////////////////////////////////////////////////////////////////////////////
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        for(Class<? extends IA35Table> table : sTables){
            try {
                sqLiteDatabase.execSQL(table.newInstance().getCreateTableScript());
            } catch (InstantiationException e) {
                Log.e(TAG, "onCreate: Caught when instantiating the table.", e);
            } catch (IllegalAccessException e) {
                Log.e(TAG, "onCreate: Caught when accessing the table.", e);
            }
        }
    }
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        for (Class<? extends IA35Table> table : sTables) {
            try {
                String updateTableScript = table.newInstance().getUpgradeTableScript();
                executeMultipleQueryIfAvailable(sqLiteDatabase, updateTableScript, false);
            } catch (InstantiationException e) {
                Log.e(TAG, "onUpgrade: Caught when instantiating the table.", e);
            } catch (IllegalAccessException e) {
                Log.e(TAG, "onUpgrade: Caught when accessing the table.", e);
            }
        }
    }

    /*//////////////////////////////////////////////////////////////////////////////////////////////
    //PUBLIC METHODS
    *///////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * Use with Caution, this gives actual database and should be followed up with closeDatabase when complete
     *
     * @param context the Context.
     * @return the writable instance of SQLiteDatabase.
     */
    public static SQLiteDatabase openDatabase(Context context) throws IllegalArgumentException{
        return getA35DBHelper(context).getWritableDatabase();
    }
    /**
     * Close Database if used openDatabase
     *
     * @param db the instance of SQLiteDatabase.
     */
    public static void closeDatabase(SQLiteDatabase db){
        try {
            db.close();
        } catch (Exception e) {
            Log.e(TAG, "Unable to close: " + db, e);
        }
    }

    /*//////////////////////////////////////////////////////////////////////////////////////////////
    //PRIVATE METHODS
    *///////////////////////////////////////////////////////////////////////////////////////////////
    private static A35DBHelper getA35DBHelper(Context context) throws IllegalArgumentException{
        //Internal method to make sure if they did not call initialize we can tell them what went wrong
        try{
            return new A35DBHelper(context);
        }catch (IllegalArgumentException ex){
            throw new IllegalArgumentException("MUST call A35DBHelper.initialize before using the helper methods");
        }
    }
    /**
     * To execute the multiple query sequentially.
     * @param sqLiteDatabase the instance of SQLiteDatabase.
     * @param sqlScript the sql script.
     * @param isRequiredToCloseSQLiteDatabase "true" if user like to close the SQLiteDatabase, Otherwise "false". (Note: We are calling this method for {@link A35DBHelper#onUpgrade(SQLiteDatabase, int, int)}, where we don't need to close the database instance.
     */
    private static void executeMultipleQueryIfAvailable(SQLiteDatabase sqLiteDatabase, String sqlScript, boolean isRequiredToCloseSQLiteDatabase){
        if(!TextUtils.isEmpty(sqlScript)) {
            StringTokenizer queries = new StringTokenizer(sqlScript, SQLSyntaxHelper.MULTIPLE_QUERY_SEPERATOR);
            sqLiteDatabase.beginTransaction();
            try {
                while (queries.hasMoreTokens()) {
                    sqLiteDatabase.execSQL(queries.nextToken());
                }
                sqLiteDatabase.setTransactionSuccessful();
            } finally {
                sqLiteDatabase.endTransaction();
            }

            if(isRequiredToCloseSQLiteDatabase) {
                try {
                    sqLiteDatabase.close();
                 } catch (Exception e) {
                     Log.e(TAG, "Unable to close: " + sqLiteDatabase, e);
                 }
            }
        }
    }
}

Next in your Application class, I add these two methods to initialize it all:
    private void setupDatabase(){
        A35DBHelper.initialize(DATABASE_NAME, DATABASE_VERSION, getDBTables());
    }
    private ArrayList<Class<? extends IA35Table>> getDBTables(){
        ArrayList<Class<? extends IA35Table>> tables = new ArrayList<>();
        tables.add(ContactFavoritesTable.class);
        tables.add(OtherTables.class);
        return tables;
    }

So now as you can see, the Application class initializes the Database which calls the children table classes for their create scripts or upgrade scripts. NOTE* This is very old code, I don't use anymore. You may be able to move away from newInstance of a table class and use static or move to kotlin with companion objects.
Lastly, I make a datasource to interact with it all.
DISCLAIMOR, THIS CLASS WILL NOT ALIGN WITH THE PREVIOUS EXAMPLE ABOVE.
This is because I couldn't find any Java examples for you, other than this one. I only have Kotlin now. However, the only difference is that this uses a contentProvider to get the cursor (because it was an exposed shared database. But it will still get the point across of good architecture.
So anywhere you see a cursor resolve, replace that with getting the A35DatabaseHelper.openDatabase and execute your query script to return a cursor and add finally to always A35DatabaseHelper.close(). The rest will line up.
public class ContactFavoritesDataSource {

/*//////////////////////////////////////////////////////////
// MEMBERS
*///////////////////////////////////////////////////////////
private static final String TAG = Globals.SEARCH_STRING + ContactFavoritesDataSource.class.getSimpleName();
public static final String[] CONTACT_FAVORITES_PROJECTION = {
        ContactFavoritesTable.COLUMN_ID,
        ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID
};

/*//////////////////////////////////////////////////////////
// CRUD OPERATIONS
*///////////////////////////////////////////////////////////
public static ArrayList<A35ContactFavorite> getAllContactFavorites(Context context) {
    ArrayList<A35ContactFavorite> favoritesList = new ArrayList<A35ContactFavorite>();

    try{
        Cursor cursor = context.getContentResolver().query(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI, CONTACT_FAVORITES_PROJECTION, null, null, null);
        if(cursor != null){
            if(cursor.moveToFirst()){
                do {
                    A35ContactFavorite contactFavorite = new A35ContactFavorite();

                    contactFavorite.setId(cursor.getInt(cursor.getColumnIndex(ContactFavoritesTable.COLUMN_ID)));
                    contactFavorite.setContactId(cursor.getString(cursor.getColumnIndex(ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID)));

                    favoritesList.add(contactFavorite);

                } while (cursor.moveToNext());

            }

            cursor.close();
        }

    }catch (Exception e){
        A35Log.e(TAG, e.getMessage());

    }

    return favoritesList;

}
public static A35ContactFavorite getContactFavoriteById(Context context, String contactId){
    A35ContactFavorite foundFav = null;

    try{
        Uri uriForId = Uri.parse(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI + "/" + contactId);
        Cursor cursor = context.getContentResolver().query(uriForId, CONTACT_FAVORITES_PROJECTION, null, null, null);
        if(cursor != null){
            if(cursor.moveToFirst()){
                do {
                    foundFav = new A35ContactFavorite();

                    foundFav.setId(cursor.getInt(cursor.getColumnIndex(ContactFavoritesTable.COLUMN_ID)));
                    foundFav.setContactId(cursor.getString(cursor.getColumnIndex(ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID)));

                } while (cursor.moveToNext());

            }

            cursor.close();
        }

    }catch (Exception e){
        A35Log.e(TAG, e.getMessage());

    }

    return foundFav;
}
public static boolean getContactIsFavorite(Context context, A35Contact contact){
    boolean exists = false;

    try{
        Uri uriForId = Uri.parse(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI + "/" + contact.getId());
        Cursor cursor = context.getContentResolver().query(uriForId, CONTACT_FAVORITES_PROJECTION, null, null, null);
        if(cursor != null){
            if(cursor.moveToFirst()){
                do {
                    String foundId = cursor.getString(cursor.getColumnIndex(ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID));

                    if(contact.getId().equals(foundId)){
                        exists = true;
                    }

                } while (cursor.moveToNext());

            }

            cursor.close();
        }

    }catch (Exception e){
        A35Log.e(TAG, e.getMessage());

    }

    return exists;
}
public static long insertContactFavorite(Context context, A35ContactFavorite contactFavorite){
    long contactFavId = -1;

    try{
        ContentValues values = new ContentValues();
        values.put(ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID, contactFavorite.getContactId());
        Uri insertUri = context.getContentResolver().insert(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI, values);
        contactFavId = Integer.parseInt(insertUri.getLastPathSegment());
        contactFavorite.setId(contactFavId);

    }catch (Exception e){
        A35Log.e(TAG, e.getMessage());

    }

    return contactFavId;

}
public static int insertMultipleContactsToFavorites(Context context, ArrayList<A35Contact> contacts){
    int count = 0;

    try {
        for (A35Contact contact : contacts) {
            ContentValues values = new ContentValues();
            values.put(ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID, contact.getId());
            context.getContentResolver().insert(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI, values);
            count++;

        }

    } catch (Exception e) {
        A35Log.e(TAG, e.getMessage());
        count = -1;

    }

    return count;
}
public static int insertMultipleContactFavorites(Context context, ArrayList<A35ContactFavorite> contactFavorites){
    int count = 0;

    try {
        for (A35ContactFavorite contactFav : contactFavorites) {
            ContentValues values = new ContentValues();
            values.put(ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID, contactFav.getContactId());
            context.getContentResolver().insert(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI, values);
            count++;

        }

    } catch (Exception e) {
        A35Log.e(TAG, e.getMessage());
        count = -1;

    }

    return count;
}
public static int removeContactFavorite(Context context, A35ContactFavorite contactFavorite) {
    int count = 0;

    try{
        Uri uriForId = Uri.parse(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI + "/" + String.valueOf(contactFavorite.getId()));
        count = context.getContentResolver().delete(uriForId, null, null);

    }catch (Exception e){
        A35Log.e(TAG, e.getMessage());

    }

    return count;

}
public static int removeContactFavorite(Context context, long favId) {
    int count = 0;

    try{
        Uri uriForId = Uri.parse(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI + "/" + String.valueOf(favId));
        count = context.getContentResolver().delete(uriForId, null, null);

    }catch (Exception e){
        A35Log.e(TAG, e.getMessage());

    }

    return count;

}
public static int removeMultipleContactsFromFavorites(Context context, ArrayList<A35Contact> contacts){
    int count = 0;

    try {
        for (A35Contact contact : contacts) {
            String selection = ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID + SQLSyntaxHelper.IS_EQUAL_TO + contact.getId();

            Uri uriForId = Uri.parse(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI + "/");
            count += context.getContentResolver().delete(uriForId, selection, null);

        }

    } catch (Exception e) {
        A35Log.e(TAG, e.getMessage());
        count = -1;

    }

    return count;
}
public static int removeMultipleContactFavorites(Context context, ArrayList<A35ContactFavorite> contactFavorites){
    int count = 0;

    try {
        for (A35ContactFavorite contactFav : contactFavorites) {
            String selection = ContactFavoritesTable.COLUMN_CONTACT_FAVORITE_ID + SQLSyntaxHelper.IS_EQUAL_TO + contactFav.getContactId();

            Uri uriForId = Uri.parse(ThisWayContentProvider.CONTACT_FAVORITES_CONTENT_URI + "/");
            count += context.getContentResolver().delete(uriForId, selection, null);

        }

    } catch (Exception e) {
        A35Log.e(TAG, e.getMessage());
        count = -1;

    }

    return count;
}

}

Last thing I leave you with is:
Consider using ROOM it is much less code, simple to use, and very clean database interactions. Then you don't have to build all this bloat on every project.
There is a learning curve with it, but it is worth the journey.
https://developer.android.com/training/data-storage/room/ 
Hope this helps.
Your error insinuates that you are trying to create something that is already there btw. You will need to set breakpoints to check the sql that you are executing to look for flaws if you choose to continue troubleshooting your current architecture.

