Q:

How can I insert an image into my database?

So, I have a database that stores recipes. Right now, the Recipe table just holds the data like name, type, etc. But, since I want to show a picture of each recipe in the app, I need to somehow store the images into the database but I don't know how.
Heres what I have so far
public class DBHandler extends SQLiteOpenHelper{

//    private static class DatabaseHelper extends SQLiteOpenHelper {

        public static final String COLUMN_ROWID = "_id";
        public static final String COLUMN_NAME = "name";
        public static final String COLUMN_TYPE = "type";
        public static final String COLUMN_INGRED = "ingred";

        private static final String TAG = "DBHandler";
        //private DatabaseHelper mDbHelper;
        //private SQLiteDatabase mDb;

        private static final String DATABASE_NAME = "Recipes";
        private static final String SQLITE_TABLE = "TABLE_RECIPES";
        private static final int DATABASE_VERSION = 1;

        //private final Context mCtx;
    public DBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
/*        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }*/

        @Override
        public void onCreate(SQLiteDatabase db) {
            String DATABASE_CREATE =
                    "CREATE TABLE if not exists " + SQLITE_TABLE + " (" +
                            COLUMN_ROWID + " integer PRIMARY KEY autoincrement," +
                            COLUMN_NAME + "," +
                            COLUMN_TYPE + "," +
                            COLUMN_INGRED + ")";

            Log.w(TAG, DATABASE_CREATE);
            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS " + SQLITE_TABLE);
            onCreate(db);
        }

/*    public DBHandler(Context ctx) {
        this.mCtx = ctx;
    }*/
/*
    public DBHandler open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }*/

/*    public void close() {
        if (mDbHelper != null) {
            mDbHelper.close();
        }
    }*/

    public void createRecipe(String name,
                              String type, String ingred) {

        ContentValues initialValues = new ContentValues();
        //initialValues.put(COLUMN_CODE, code);
        initialValues.put(COLUMN_NAME, name);
        initialValues.put(COLUMN_TYPE, type);
        initialValues.put(COLUMN_INGRED, ingred);

        SQLiteDatabase db = this.getWritableDatabase();
        db.insert(SQLITE_TABLE, null, initialValues);
        db.close();
    }

    public boolean deleteAllRecipes() {
        int doneDelete = 0;

        SQLiteDatabase mDb = this.getWritableDatabase();
        doneDelete = mDb.delete(SQLITE_TABLE, null , null);
        Log.w(TAG, Integer.toString(doneDelete));
        return doneDelete > 0;

    }

    public Cursor fetchRecipesByName(String inputText) throws SQLException {
        SQLiteDatabase mDb = this.getWritableDatabase();
        Log.w(TAG, inputText);
        Cursor mCursor = null;
        if (inputText == null  ||  inputText.length () == 0)  {
            mCursor = mDb.query(SQLITE_TABLE, new String[] {COLUMN_ROWID,
                            COLUMN_NAME, COLUMN_TYPE, COLUMN_INGRED},
                    null, null, null, null, null);

        }
        else {

            mCursor = mDb.query(true, SQLITE_TABLE, new String[] {COLUMN_ROWID,
                            COLUMN_NAME, COLUMN_TYPE, COLUMN_INGRED},
                    COLUMN_NAME + " like '%" + inputText + "%'" + " or " +
                            COLUMN_TYPE + " like '%" + inputText + "%'" + " or " +
                            COLUMN_INGRED + " like '%" + inputText + "%'",
                    null, null, null, null, null);
        }
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;

    }

    public Cursor fetchAllRecipes() {
        SQLiteDatabase mDb = this.getWritableDatabase();

        Cursor mCursor = mDb.query(SQLITE_TABLE, new String[] {COLUMN_ROWID,
                        COLUMN_NAME, COLUMN_TYPE, COLUMN_INGRED},
                null, null, null, null, null);

        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }

    public void insertSomeRecipes() {

        createRecipe("Blackened Salmon","Dinner","Salmon");
    }

    public boolean deleteRecipe(String name){
        SQLiteDatabase mDb = this.getWritableDatabase();
        boolean result = false;

        String sql_query = "SELECT * FROM " + SQLITE_TABLE + " WHERE " + COLUMN_NAME + " = \"" + name + "\"";

        Cursor myCursor = mDb.rawQuery(sql_query, null);
        Recipes myRecipe = new Recipes();

        if (myCursor.moveToFirst()){
            myRecipe.setID(myCursor.getInt(0));
            mDb.delete(SQLITE_TABLE, COLUMN_ROWID + " = ?", new String[]{String.valueOf(myRecipe.getID())});
            myCursor.close();
            result = true;
        }

        mDb.close();
        return result;

    }

}

A:

The simplest technique you can follow is to store your Image path in the database table as a String and then you can get it back whenever you need that image and decode it using BitmapFactory.decodeFile. Storing Base64String is fine but the string will have too large so, if you will see the path of image it is comparatively a shorter string
For Example:

define another parameter in your createRecipe() method named String imagePath like:

public void createRecipe(String name,String type, String ingred,String imgPath){}

When you make a call to this function you will pass the image path what ever you have like:

createRecipe(name,type,ingred,path_of_image)
To get ImagePath you can do something like that:
String destination = new File(Environment.getExternalStorageDirectory(), name_of_your_image+ ".jpg");
FileInputStream in = new FileInputStream(destination);
String photoPath = destination.getAbsolutePath();

Finally when you call your fetchRecipesByName() or fetchAllRecipes() method the Cursor will now have your path stored against each entry you can get this path as a String and pass it to the below function you will get Bitmap in return.

private Bitmap getBitmapFromPath(String path)
{     
    BitmapFactory.Options btmapOptions = new BitmapFactory.Options();

    btmapOptions.inSampleSize = 2;

    Bitmap bm = BitmapFactory.decodeFile(path, btmapOptions);

    return bm;
}

Note: You should also take care if you are storing path of image and it could be deleted from gallery so in return you cannot have any bitmap against this path so you should manage if image dosen't exist then use an alternative image.

