0

I am creating an app and i want to have the ability to change the images later on without uninstalling the app. Since we cannot write to drawable folder, i figured that i use a database to save the images and i can manipulate the data there in later on.

I tested a little code, but it doesnt seem to work. I can pull image from the url and display. But i still havent been able to figure out how to put the images on the database from the url.

Look at my codes.

public class MainActivity extends AppCompatActivity {
Intent intent;
Button btn;
DataBaseHandler db;
 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }

    btn = (Button)findViewById(R.id.btn);
    final ImageView img = (ImageView)findViewById(R.id.img);
    //initialize db
    db = new DataBaseHandler(this);


    URL url = null;
    try {
        url = new URL("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSh3goeAXlletPgkm3pm1F4DgxwArOKS9STyK02ocNn0AZ6Q9u");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    try {
        url = new URL("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSh3goeAXlletPgkm3pm1F4DgxwArOKS9STyK02ocNn0AZ6Q9u");
        final Bitmap image = BitmapFactory.decodeStream(url.openStream());
        byte[]inpudata = Utils.getImageBytes(image);
        db.insertImage(inpudata);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                byte[]inpudata = db.retreiveImageFromDB();


                img.setImageBitmap(Utils.getImage(inpudata));
            }
        });
    } catch(IOException e) {
        System.out.println(e);
    }




}



 }

Also the Database Helper class

public class DataBaseHandler{

public static final String IMAGE_ID = "id";
public static final String IMAGE = "image";
private final Context mContext;

private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;

private static final String DATABASE_NAME = "Images.db";
private static final int DATABASE_VERSION = 1;

private static final String IMAGES_TABLE = "ImagesTable";

private static final String CREATE_IMAGES_TABLE =
        "CREATE TABLE " + IMAGES_TABLE + " (" +
                IMAGE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + IMAGE + " BLOB NOT NULL );";


private static class DatabaseHelper extends SQLiteOpenHelper {
    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_IMAGES_TABLE);
    }

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + CREATE_IMAGES_TABLE);
        onCreate(db);
    }
}

public void Reset() {
    mDbHelper.onUpgrade(this.mDb, 1, 1);
}

public DataBaseHandler(Context ctx) {
    mContext = ctx;
    mDbHelper = new DatabaseHelper(mContext);
}

public DataBaseHandler open() throws SQLException {
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}

// Insert the image to the Sqlite DB
public void insertImage(byte[] imageBytes) {
    ContentValues cv = new ContentValues();
    cv.put(IMAGE, imageBytes);
    mDb.insert(IMAGES_TABLE, null, cv);
}

// Get the image from SQLite DB
// We will just get the last image we just saved for convenience...
public byte[] retreiveImageFromDB() {
    Cursor cur = mDb.query(true, IMAGES_TABLE, new String[]{IMAGE,},
            null, null, null, null,
            IMAGE_ID + " DESC", "1");
    if (cur.moveToFirst()) {
        byte[] blob = cur.getBlob(cur.getColumnIndex(IMAGE));
        cur.close();
        return blob;
    }
    cur.close();
    return null;
}
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
drachomi
  • 17
  • 1
  • 4
  • Did you check https://stackoverflow.com/questions/9357668/how-to-store-image-in-sqlite-database ? – Isuru Oct 12 '17 at 10:41
  • 1
    Please change your mind: save the images locally and **don't bloat your database** with BLOBS. Store only the image paths. – Phantômaxx Oct 12 '17 at 10:54
  • 1
    Or, better, don't even bother to save the images. Just store the URLs. – Phantômaxx Oct 12 '17 at 11:09
  • I need to be able to access the image offline.. hence the need to save it in the database... and yes, i did check the other threads, but didnt get just what i was looking for – drachomi Oct 12 '17 at 18:44

2 Answers2

1

it's not good idea to store image in local database because there is limitation of cursor size See details you can do something like this first download image from server and store in internal storage then store the local path in database

private String saveToInternalStorage(Bitmap bitmapImage){
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
         // path to /data/data/yourapp/app_data/imageDir
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        // Create imageDir
        File mypath=new File(directory,"profile.jpg");

        FileOutputStream fos = null;
        try {           
            fos = new FileOutputStream(mypath);
       // Use the compress method on the BitMap object to write image to the OutputStream
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (Exception e) {
              e.printStackTrace();
        } finally {
            try {
              fos.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
        } 
        return directory.getAbsolutePath();
    }

read image using

private void loadImageFromStorage(String path)
{

    try {
        File f=new File(path, "profile.jpg");
        Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
            ImageView img=(ImageView)findViewById(R.id.imgPicker);
        img.setImageBitmap(b);
    } 
    catch (FileNotFoundException e) 
    {
        e.printStackTrace();
    }

}

reference from https://stackoverflow.com/a/17674787/2941375

0

when you store image in database every time you have to convert to byte and vice versa. It may also lead to memory exception so what I will suggest you ,rather storing image in database try to store URL of that image in database and then fetch the url of image from DB and show the image using Picasso or Glide image library.

param
  • 393
  • 6
  • 17
  • I appreciate, but am not looking at streaming the images live via internet. Considering the app automatically downloading the images at some point, saving it and using it offline. – drachomi Oct 12 '17 at 18:41