3

I created a book app, where you can save books from the internet (googleBooksAPI). The BookData (title, author, image) will be saved in an SQLite DB. You can view the books in a listview. If you click on a row ( a book) all the bookdata will be shown in a new activity (bookInfoActivity) My Problem is, that I dont know how to pass the Image of the row i clicked to the bookinfoactivity.

I tried it like following, but as I and you know it will only pass the image of the first row.

BookInfoActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_book_info);
    bookDBHelper = new BookDBHelper(this);
    Typeface myTypeface = Typeface.createFromAsset(getAssets(), "Lobster.ttf");
    TextView myTextView = (TextView) findViewById(R.id.yourbookinfo);
    myTextView.setTypeface(myTypeface);

    imageView = (ImageView) findViewById(R.id.passed_bookimage);
    btn_update = (Button) findViewById(R.id.button_update);
    btn_delete_book = (Button) findViewById(R.id.btn_delete_book);

    Intent intent = getIntent();
    String secret_editText_titel = intent.getStringExtra(BookDataListActivity.EXTRA_MSG0);

    cursor2.moveToFirst();

    int rows = cursor2.getCount();

    for(int i=0; i < rows; i++ ){
        String booktitle = cursor2.getString(1);
        byte[] blob= cursor2.getBlob(0);
        Bitmap bookimage = BitmapFactory.decodeByteArray(blob, 0, blob.length);
        imageView.setImageBitmap(bookimage);
        Toast.makeText(this, "here is your image", Toast.LENGTH_SHORT).show();

    if(secret_editText_titel == booktitle){

    }else{
        cursor2.moveToNext();
    }
    }

    /*bookDBHelper = new BookDBHelper(getApplicationContext());
    sqLiteDatabaseBooks = bookDBHelper.getReadableDatabase();
    cursor2 = bookDBHelper.getInformations(sqLiteDatabaseBooks);
    if (cursor2.moveToPrevious()) {
        {
            String se
            byte[] blob= cursor2.getBlob(0);
            Bitmap bookimage = BitmapFactory.decodeByteArray(blob, 0, blob.length);
            imageView.setImageBitmap(bookimage);
            Toast.makeText(this, "here is your image", Toast.LENGTH_SHORT).show();

        }
    }*/

    String secret_title = intent.getStringExtra(BookDataListActivity.EXTRA_MSG1);
    Secret_editText_title = (EditText) findViewById(R.id.secret_edittext_title);
    Secret_editText_title.setText(secret_title);

    //defaultImage = (ImageView) findViewById(R.id.defaultImage);
    /*Bitmap book_image = intent.????????(BookDataListActivity.EXTRA_MSG0);
    passedbookimage = (ImageView) findViewById(R.id.passed_bookimage);
    passedbookimage.setImageBitmap(book_image);
*/
    String book_title = intent.getStringExtra(BookDataListActivity.EXTRA_MSG1);
    passedbooktitle = (EditText) findViewById(R.id.passed_booktitle);
    passedbooktitle.setText(book_title);

    String book_author = intent.getStringExtra(BookDataListActivity.EXTRA_MSG2);
    passedbookauthor = (EditText) findViewById(R.id.passed_bookauthor);
    passedbookauthor.setText(book_author);

    String book_date = intent.getStringExtra(BookDataListActivity.EXTRA_MSG3);
    passedbookdate = (EditText) findViewById(R.id.passed_bookdate);
    passedbookdate.setText(book_date);

    String book_rating = intent.getStringExtra(BookDataListActivity.EXTRA_MSG4);
    passedbookrating = (EditText) findViewById(R.id.passed_bookrating);
    passedbookrating.setText(book_rating);

    String book_shelf = intent.getStringExtra(BookDataListActivity.EXTRA_MSG5);
    passedbookshelf = (EditText) findViewById(R.id.passed_bookshelf);
    passedbookshelf.setText(book_shelf);

    DeleteData();
}

*BookDBHelper

public class BookDBHelper extends SQLiteOpenHelper{

public SQLiteDatabase sqLiteDatabase;

private static final String DATABASE_BOOKS_NAME = "BookINFO.DB";
private static final int DATABASE_BOOKS_VERS = 2;
private static final String CREATE_QUERY_BOOKS =
        "CREATE TABLE "
                + BookContent.NewBookInfo.TABLE_NAME_BOOKS
                +"("
                + BookContent.NewBookInfo.BOOK_IMAGE +" BLOB NOT NULL, "
                + BookContent.NewBookInfo.BOOK_TITLE+" TEXT, "
                + BookContent.NewBookInfo.BOOK_AUTHOR+" TEXT, "
                + BookContent.NewBookInfo.BOOK_DATE+" TEXT, "
                + BookContent.NewBookInfo.BOOK_RATING+" TEXT, "
                + BookContent.NewBookInfo.BOOK_SHELF+" TEXT);";


public BookDBHelper(Context context){
    super(context, DATABASE_BOOKS_NAME, null, DATABASE_BOOKS_VERS);
    Log.e("DATABASE OPERATIONS", " DATABASE CREATED");
}

@Override
public void onCreate(SQLiteDatabase bookdb) {

    bookdb.execSQL(CREATE_QUERY_BOOKS);
    Log.e("DATABASE OPERATIONS", " DATABASE CREATED");
}

@Override
public void onUpgrade(SQLiteDatabase bookdb, int oldVersion, int newVersion) {
    bookdb.execSQL(" DROP TABLE IS EXISTS " + BookContent.NewBookInfo.TABLE_NAME_BOOKS);
    onCreate(bookdb);
}

public void addInformations(byte[] image, String booktitle, String bookauthor, String bookdate, String bookrating, String bookshelf, SQLiteDatabase bookdb)
{

    ContentValues contentValues = new ContentValues();
    contentValues.put(BookContent.NewBookInfo.BOOK_IMAGE, image);
    contentValues.put(BookContent.NewBookInfo.BOOK_TITLE, booktitle);
    contentValues.put(BookContent.NewBookInfo.BOOK_AUTHOR, bookauthor);
    contentValues.put(BookContent.NewBookInfo.BOOK_DATE, bookdate);
    contentValues.put(BookContent.NewBookInfo.BOOK_RATING, bookrating);
    contentValues.put(BookContent.NewBookInfo.BOOK_SHELF, bookshelf);

    bookdb.insert(BookContent.NewBookInfo.TABLE_NAME_BOOKS, null, contentValues);
    Log.e("DATABASE OPERATIONS", "ON ROW INSERTED");
}

public void addOwnBookInformations(String booktitle, String bookauthor, String bookdate, String bookrating, String bookshelf, SQLiteDatabase bookdb)
{

    ContentValues contentValues = new ContentValues();
    contentValues.put(BookContent.NewBookInfo.BOOK_TITLE, booktitle);
    contentValues.put(BookContent.NewBookInfo.BOOK_AUTHOR, bookauthor);
    contentValues.put(BookContent.NewBookInfo.BOOK_DATE, bookdate);
    contentValues.put(BookContent.NewBookInfo.BOOK_RATING, bookrating);
    contentValues.put(BookContent.NewBookInfo.BOOK_SHELF, bookshelf);

    bookdb.insert(BookContent.NewBookInfo.TABLE_NAME_BOOKS, null, contentValues);
    Log.e("DATABASE OPERATIONS", "ON ROW INSERTED");
}

public Cursor getInformations(SQLiteDatabase bookdb){
    Cursor cursor2;
        String[] projections = {
                BookContent.NewBookInfo.BOOK_IMAGE,
                BookContent.NewBookInfo.BOOK_TITLE,
                BookContent.NewBookInfo.BOOK_AUTHOR,
                BookContent.NewBookInfo.BOOK_DATE,
                BookContent.NewBookInfo.BOOK_RATING,
                BookContent.NewBookInfo.BOOK_SHELF};
    cursor2 = bookdb.query(BookContent.NewBookInfo.TABLE_NAME_BOOKS, projections,null, null, null, null, null);
    return cursor2;
}

BookDataListActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.book_data_list_layout);

    Typeface myTypeface = Typeface.createFromAsset(getAssets(), "Lobster.ttf");

    TextView myTextView = (TextView) findViewById(R.id.text_yourbooks);
    myTextView.setTypeface(myTypeface);

    btn_home = (Button) findViewById(R.id.btn_home);

    booklistView = (ListView) findViewById(R.id.book_list_view);
    inputSearch = (EditText) findViewById(R.id.search_bar);
    imageView = (ImageView) findViewById(R.id.book_image);

    bookListDataAdapter = new BookListDataAdapter(getApplicationContext(), R.layout.row_book_layout);
    booklistView.setAdapter(bookListDataAdapter);


    //onItemClickListener
    booklistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            Intent intent = new Intent(getApplicationContext(), BookInfoActivity.class);

            /*imageView = (ImageView) findViewById(R.id.book_image);
            byte[] book_image = cursor2.getBlob(cursor2.getColumnIndex(BookContent.NewBookInfo.BOOK_IMAGE));
            imageView.setImageBitmap(BitmapFactory.decodeByteArray(book_image,0,book_image.length));
            //intent.putExtra(EXTRA_MSG0, book_image);
*/

            editTextBooktitle = (TextView) view.findViewById(R.id.text_book_title);
            String book_title = editTextBooktitle.getText().toString();
            intent.putExtra(EXTRA_MSG1, book_title);

            editTextBookauthor = (TextView) view.findViewById(R.id.text_book_author);
            String bookauthor = editTextBookauthor.getText().toString();
            intent.putExtra(EXTRA_MSG2, bookauthor);

            editTextBookdate = (TextView) view.findViewById(R.id.text_book_date);
            String bookdate = editTextBookdate.getText().toString();
            intent.putExtra(EXTRA_MSG3, bookdate);

            editTextBookrating = (TextView) view.findViewById(R.id.text_book_rating);
            String bookrating = editTextBookrating.getText().toString();
            intent.putExtra(EXTRA_MSG4, bookrating);

            editTextBookshelf = (TextView) view.findViewById(R.id.text_book_shelf);
            String bookshelf = editTextBookshelf.getText().toString();
            intent.putExtra(EXTRA_MSG5, bookshelf);

            startActivity(intent);

            onResume();

        }

    });


    inputSearch.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            bookListDataAdapter.getFilter().filter(s);
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

    bookDBHelper = new BookDBHelper(getApplicationContext());
    sqLiteDatabaseBooks = bookDBHelper.getReadableDatabase();
    cursor2 = bookDBHelper.getInformations(sqLiteDatabaseBooks);
    if (cursor2.moveToFirst()) {
        do {
            String booktitle, bookauthor, bookdate, bookrating, bookshelf;
            Bitmap bookimage;

            byte[] blob= cursor2.getBlob(0);
            bookimage = BitmapFactory.decodeByteArray(blob,0,blob.length);
            booktitle = cursor2.getString(1);
            bookauthor = cursor2.getString(2);
            bookdate = cursor2.getString(3);
            bookrating = cursor2.getString(4);
            bookshelf = cursor2.getString(5);

            BookDataProvider bookDataProvider = new BookDataProvider(bookimage, booktitle, bookauthor, bookdate, bookrating, bookshelf);
            bookListDataAdapter.add(bookDataProvider);

        } while (cursor2.moveToNext());
    }
    backtoMainView();
}

public void backtoMainView(){
    btn_home.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            startActivity(intent);
        }
    });
}
@Override
public void onResume(){
    super.onResume();
    bookListDataAdapter.notifyDataSetChanged();

}
}

LOGcat*

    Process: com.kasutwentyseven.gui4selfshelf, PID: 20482
                                                                               java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kasutwentyseven.gui4selfshelf/com.kasutwentyseven.gui4selfshelf.Books.BookInfoActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String)' on a null object reference
                                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2357)
                                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2419)
                                                                                   at android.app.ActivityThread.access$900(ActivityThread.java:154)
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                   at android.os.Looper.loop(Looper.java:135)
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5291)
                                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                                   at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
                                                                                Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String)' on a null object reference
                                                                                   at com.kasutwentyseven.gui4selfshelf.Books.BookDBHelper.getInformations(BookDBHelper.java:85)
                                                                                   at com.kasutwentyseven.gui4selfshelf.Books.BookInfoActivity.onCreate(BookInfoActivity.java:60)
                                                                                   at android.app.Activity.performCreate(Activity.java:5990)
                                                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2310)
                                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2419) 
                                                                                   at android.app.ActivityThread.access$900(ActivityThread.java:154) 
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) 
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                   at android.os.Looper.loop(Looper.java:135) 
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5291) 
                                                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                                                   at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 
K.Horst
  • 75
  • 9
  • I think Your if-state is not what You need. MoveToPrevious() moves the cursor to the entry before that one You need. And it returns false if cursor is already there (true if not). I think You need something like cursor.moveToPosition(position), if You know the position inside Your database.... – Opiatefuchs Jan 28 '16 at 11:53
  • Hi, thanks for your fast comment. I thought about the same. I also thought about implementing a "WHERE Clause" on the cursor and going about the Row_ID. But I am new to programming and dont know how to handle this – K.Horst Jan 28 '16 at 11:57
  • Why you don't save URI of your image ? it's more easier to handle in such situation – Amir Jan 28 '16 at 11:58
  • storing an image as blob will guarantee that it is available. storing it as URI can lead into problems, when user removed it from that place..... – Opiatefuchs Jan 28 '16 at 11:59
  • @Amir Well, its kind of embarrassing...Because I am new to programming and this was a solution of a youtube tutorial. I felt lucky to have at least one solution :( – K.Horst Jan 28 '16 at 12:00
  • Store the file in the app data folder - unless the phone is rooted, the use won't be able to access the images. It will be a more efficient solution. I can see performance problems as the size of the database gets larger. – Mark Jan 28 '16 at 12:02
  • @Opiatefuchs I use same approach and didn't face any issue. especially if use some caching library like Glide or Picasso. – Amir Jan 28 '16 at 12:03
  • Do you keep the blob in the same table row with the other book data like title...? – Bö macht Blau Jan 28 '16 at 12:12
  • @Amir...for sure, but if the images should exist all the time, then BLOB is not the worst idea. And like I said, if user deletes the images, no image is there. So using a BLOB is ok, for sure, the database could grow and grow and grow...... And this OP is just a beginner, I think explaining about Picasso or Glide is to hard for now..... – Opiatefuchs Jan 28 '16 at 12:15

3 Answers3

2

There is a lot more to do and to explain the whole SQLite implementation is beyond the frame here. First You have to implement an unique id for every book into Your database. Then You have to pass this ID via intent into Your next activity, where You show the book info:

pass id from listView activity:

Intent myIntent = new Intent(YourListViewActivity.this, yourBookActivity.class);
myIntent.putExtra("bookid", id_value);
startActivity(myIntent);

get it in Your book activity:

Intent mIntent = getIntent();
int idValue= mIntent.getIntExtra("bookid", 0);

If You got this all, then it´s easy like this:

    //set the cursor to the first row
    cursor2.moveToFirst();

    //get the number of rows
    int rows = cursor2.getCount();

    //loop through the cursor
    for(int i=0;i<rows;i++){

       //get the id
       int id = cursor2.getInt(0);
       byte[] blob= cursor2.getBlob(1);
                Bitmap bookimage = BitmapFactory.decodeByteArray(blob, 0, blob.length);
                imageView.setImageBitmap(bookimage);
                Toast.makeText(this, "here is your image", Toast.LENGTH_SHORT).show();

    if(idValue==id){

      //stop cursor here because You get what You wanted
    }else{

    cursor2.moveToNext();

    }

  }

But that´s only a possible example, there are other ways too. You should read how to build a correct database for Your intention:

http://examples.javacodegeeks.com/android/core/database/android-database-example/

Opiatefuchs
  • 9,800
  • 2
  • 36
  • 49
  • This looks great. Unfortunately I havent implemented a ID Column (was a stupid tutorial I guess) I will go for the book_title ( not as unique as an id but, yeah...) I will try your solution, but looks good. – K.Horst Jan 28 '16 at 12:20
  • no problem, if there is any problem, come back...think about that above is only an example and not tested for now.... – Opiatefuchs Jan 28 '16 at 12:23
  • I got a NullpointerException at `cursor2.movetoFirst()` I will add my Activities to my Question. (The comments are attempts to find a solution) – K.Horst Jan 28 '16 at 12:45
  • an please post the logcat output too. If You really get NullPointer here, than the only cause is, that Your cursor is not initialized... – Opiatefuchs Jan 28 '16 at 12:48
  • Sorry again for some "unlogical" solutions. I build the app by using different tutorials. – K.Horst Jan 28 '16 at 12:52
  • no problem...it´s how I thought...You have not initialized Your cursor with cursor2 = bookDBHelper.getInformations(sqLiteDatabaseBooks); method before You use the cursor... – Opiatefuchs Jan 28 '16 at 12:56
  • I added: `cursor = bookDBHelper.getInformations(sqLiteDatabaseBooks);` above the cursor2.movetoFirst(); now I got two errors @BookDBHelper ( I will add to question too) `cursor2 = bookdb.query(BookContent.NewBookInfo.TABLE_NAME_BOOKS, projections,null, null, null, null, null);` and @BookInfoActivity `cursor2 = bookDBHelper.getInformations(sqLiteDatabaseBooks);` – K.Horst Jan 28 '16 at 13:03
  • 2
    now I guess You have not initialized Your database....You should also update Your code posts to Your changes..... – Opiatefuchs Jan 28 '16 at 13:36
  • Alright I initialized the database. I will ad my solution to my question! – K.Horst Jan 28 '16 at 13:42
  • There is a bug in our solution. I tried it again. I added the first book and open the detailed View - good! I added a second book and open the detailed View - good! I open the first book again -> the image of the last opened detailedView shows up. so here, of the second book – K.Horst Jan 28 '16 at 21:32
  • ok, can You please update all the code you have made changes? So I take a look where the problem is... – Opiatefuchs Jan 29 '16 at 08:21
  • I guess it is because You left the book activity where You can see all informations, but You do not finish it. If You come back to this activity, the old one will be shown. – Opiatefuchs Jan 29 '16 at 08:22
0

You could pass a Bitmap to another Activity via Intent. Pass the ByteArray via intent, receive the ByteArray and decode it in your second Activity.

    ByteArrayOutputStream bStream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.PNG, 100, bStream);
    byte[] byteArray = bStream.toByteArray();

    Intent intent = new Intent(this, Activity2.class);
    intent.putExtra("image",byteArray);

And then in second Activity :

    byte[] byteArray = getIntent().getByteArrayExtra("image");
    Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0,byteArray.length);                             

While this is not the best practice to do this task with the perspective of performance, you should save the image in your disk first and fetch it through file path.

Ref : Answer By Zaid Daghestani

Community
  • 1
  • 1
Tafveez Mehdi
  • 456
  • 3
  • 12
0

Here is the answer to my question.

Thanks for all the comments.

bookDBHelper = new BookDBHelper(getApplicationContext());
    sqLiteDatabaseBooks = bookDBHelper.getReadableDatabase();
    cursor2 = bookDBHelper.getInformations(sqLiteDatabaseBooks);
    cursor2.moveToFirst();

    int rows = cursor2.getCount();

    for(int i=0; i < rows; i++ ){
        String booktitle = cursor2.getString(1);
        byte[] blob= cursor2.getBlob(0);
        Bitmap bookimage = BitmapFactory.decodeByteArray(blob, 0, blob.length);
        imageView.setImageBitmap(bookimage);
        Toast.makeText(this, "here is your image", Toast.LENGTH_SHORT).show();

    if(secret_editText_titel == booktitle){

    }else{
        cursor2.moveToNext();
    }
    }
K.Horst
  • 75
  • 9