0

I have created a table orders, in order to display the cart items. When I click the add to cart button in the product details activity, the app crashes and goes to the previous page. But, I can see the cart items in listview.

OrderProvider class:

public class OrderProvider extends ContentProvider {

    // this constant is needed in order to define the path of our modification in the table
    public static final int ORDER=100;

    public DBHelper mhelper;
    public static UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        sUriMatcher.addURI(OrderContract.CONTENT_AUTHORITY,OrderContract.PATH,ORDER);
    }


    @Override
    public boolean onCreate() {

        mhelper = new DBHelper(getContext());

        return true;
    }


    @Override
    public Cursor query( Uri uri,  String[] projection,  String selection,  String[] selectionArgs, String sortOrder) {


        SQLiteDatabase database = mhelper.getReadableDatabase();
        Cursor cursor;
        int match = sUriMatcher.match(uri);
        switch (match){
            case ORDER:
                cursor = database.query(OrderContract.OrderEntry.TABLE_NAME, projection, selection, selectionArgs, null,null, sortOrder);
                break;

            default:
                throw new IllegalArgumentException("CANT QUERY");
        }

        cursor.setNotificationUri(getContext().getContentResolver(),uri);
        return cursor;

    }


    @Override
    public String getType(Uri uri) {
        return null;
    }


    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int match = sUriMatcher.match(uri);
        switch (match) {
            case ORDER:
                return insertCart(uri, values);

            default:
                throw new IllegalArgumentException("Cant insert data");
        }

    }

    private Uri insertCart(Uri uri, ContentValues values) {

        String name = values.getAsString(OrderContract.OrderEntry.COLUMN_NAME);
        if(name == null){
            throw new IllegalArgumentException("Name is Required");
        }

        String quantity = values.getAsString(OrderContract.OrderEntry.COLUMN_QUANTITY);
        if(quantity == null){
            throw new IllegalArgumentException("Quantity is Required");
        }

        String price = values.getAsString(OrderContract.OrderEntry.COLUMN_PRICE);
        if(price == null){
            throw new IllegalArgumentException("Price is Required");
        }

        byte[] image = values.getAsByteArray(OrderContract.OrderEntry.COLUMN_IMAGE);
        if(image == null){
            throw new IllegalArgumentException("Image is Required"); //shows this error in logcat  
        }

        //insert values into order

        SQLiteDatabase database = mhelper.getWritableDatabase();
        long id = database.insert(OrderContract.OrderEntry.TABLE_NAME, null, values);

        if(id == 0){
            return null;
        }
        getContext().getContentResolver().notifyChange(uri,null);
        return ContentUris.withAppendedId(uri,id);


    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        //delete data once order is made

        int rowsDeleted;
        SQLiteDatabase database = mhelper.getWritableDatabase();
        int match = sUriMatcher.match(uri);
        switch (match) {
            case ORDER:
                rowsDeleted = database.delete(OrderContract.OrderEntry.TABLE_NAME, selection, selectionArgs);
                break;

            default:
                throw new IllegalArgumentException("Cannot delete");
        }

        if (rowsDeleted!=0) {
            getContext().getContentResolver().notifyChange(uri, null);
        }

        return rowsDeleted;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }
}

OrderContract.class:

public class OrderContract {

    public OrderContract() {
    }

    //content authority requires package name
    public static final String CONTENT_AUTHORITY = "com.example.myapp";
    public static final Uri BASE_URI = Uri.parse(("content://" +CONTENT_AUTHORITY));
    //same as table name
    public static final String PATH = "orders" ;


    public static abstract class OrderEntry implements BaseColumns{

        public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_URI,PATH);

        public static final String TABLE_NAME = "orders" ;
        public static final String _ID = BaseColumns._ID ;
        public static final String COLUMN_NAME = "name" ;
        public static final String COLUMN_QUANTITY = "quantity" ;
        public static final String COLUMN_PRICE = "price" ;
        public static final String COLUMN_IMAGE = "image" ;

    }

}

ProductDetails.class:

public class Sofa1 extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {


    ImageButton plusquantity,minusquantity;
    ImageView productimage;
    TextView quantitynumber,sofaname,sofaprice,sofadesc,totalamount;
    Button addtocart;
    int quantity;
    int totalprice=0;
    public Uri mcurrentcarturi;
    boolean hasallrequiredvalues = false;
    DBHelper DB;


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

        if (getSupportActionBar() != null) {
            getSupportActionBar().hide();
        }




        sofaname=(TextView)findViewById(R.id.sofaname);
        sofaprice=(TextView)findViewById(R.id.sofaprice);
        sofadesc=(TextView)findViewById(R.id.sofadesc);
        plusquantity = findViewById(R.id.addquantity);
        minusquantity  = findViewById(R.id.subquantity);
        quantitynumber = findViewById(R.id.quantity);
        addtocart = (Button) findViewById(R.id.addtocart);
        productimage = (ImageView)findViewById(R.id.productimage);



        DB = new DBHelper(Sofa1.this);
        //product - 1
        byte[] bytesImage = DB.getProductImage("SELECT F_Image FROM Furniture WHERE F_Type = 'Sofa';");
        if (bytesImage != null) {

            Bitmap bitmap = convertByteArraytoImage(bytesImage);
            productimage.setImageBitmap(bitmap);

        }
        String Name = DB.getProductNamePrice("SELECT F_Name FROM Furniture WHERE F_Type = 'Sofa';");
        String Price = DB.getProductNamePrice("SELECT F_Price FROM Furniture WHERE F_Type = 'Sofa';");
        String Desc = DB.getProductNamePrice("SELECT F_Description FROM Furniture WHERE F_Type = 'Sofa';");
        sofaname.setText(Name);
        sofaprice.setText(Price);
        sofadesc.setText(Desc);

        plusquantity.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(quantity<5){
                    //sofaprice
                    int baseprice= Integer.parseInt(sofaprice.getText().toString());
                    quantity++;
                    displayquantity();
                    totalprice = baseprice * quantity;
                    String setnewprice = (String.valueOf(totalprice));
                    sofaprice.setText(setnewprice);
                }
            }
        });

        minusquantity.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int baseprice=0;
                String Price = DB.getProductNamePrice("SELECT F_Price FROM Furniture WHERE F_Type = 'Sofa';");
                baseprice = Integer.parseInt(Price);
                    if(quantity>1) {
                        quantity--;
                        displayquantity();
                        totalprice = baseprice * quantity;
                        String setnewprice = (String.valueOf(totalprice));
                        sofaprice.setText(setnewprice);
                    }


            }
        });

        addtocart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(Sofa1.this, "Product Added to cart", Toast.LENGTH_SHORT).show();

                SaveCart();
                totalamount = (TextView) findViewById(R.id.total);



            }
        });





    }

    private void SaveCart() {

        String name = sofaname.getText().toString();
        String price = sofaprice.getText().toString();
        String quantity = quantitynumber.getText().toString();
        byte[] bytesImage = convertImageViewToByteArray(productimage);

        ContentValues values = new ContentValues();
        values.put(OrderContract.OrderEntry.COLUMN_NAME,name);
        values.put(OrderContract.OrderEntry.COLUMN_PRICE,price);
        values.put(OrderContract.OrderEntry.COLUMN_QUANTITY,quantity);
        values.put(OrderContract.OrderEntry.COLUMN_IMAGE,bytesImage);

        if(mcurrentcarturi == null){
            Uri newUri = getContentResolver().insert(OrderContract.OrderEntry.CONTENT_URI, values);

            if(newUri == null){
                Toast.makeText(this, "Failed to add to cart", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this, "Product added to cart", Toast.LENGTH_SHORT).show();
            }

        }

        hasallrequiredvalues = true;

    }

    private void displayquantity() {
        quantitynumber.setText(String.valueOf(quantity));
    }



    @Override
    public @NotNull Loader<Cursor> onCreateLoader(int id, Bundle args) {

        String[] projection = {OrderContract.OrderEntry._ID,
                OrderContract.OrderEntry.COLUMN_NAME,
                OrderContract.OrderEntry.COLUMN_PRICE,
                OrderContract.OrderEntry.COLUMN_QUANTITY,
                OrderContract.OrderEntry.COLUMN_IMAGE};

        return new CursorLoader(this, mcurrentcarturi, projection, null, null, null);
    }

    @Override
    public void onLoadFinished(@NotNull Loader<Cursor> loader, Cursor cursor) {

        if(cursor==null || cursor.getCount() < 1){
            return;
        }

        if(cursor.moveToFirst()){

            int name = cursor.getColumnIndex(OrderContract.OrderEntry.COLUMN_NAME);
            int price = cursor.getColumnIndex(OrderContract.OrderEntry.COLUMN_PRICE);
            int quantity = cursor.getColumnIndex(OrderContract.OrderEntry.COLUMN_QUANTITY);

            String nameofsofa = cursor.getString(name);
            String priceofsofa = cursor.getString(price);
            String quantityofsofa = cursor.getString(quantity);
            byte[] bytesImage = cursor.getBlob(cursor.getColumnIndex(OrderContract.OrderEntry.COLUMN_IMAGE));

            if (bytesImage != null) {

                Bitmap bitmap = convertByteArraytoImage(bytesImage);
                productimage.setImageBitmap(bitmap);

            }
            sofaname.setText(nameofsofa);
            sofaprice.setText(priceofsofa);
            quantitynumber.setText(quantityofsofa);

        }

    }

    @Override
    public void onLoaderReset(@NotNull Loader<Cursor> loader) {

        sofaname.setText("");
        sofaprice.setText("");
        quantitynumber.setText("");
        byte[] bytesImage = DB.getProductImage("SELECT F_Image FROM Furniture WHERE F_Type = 'Sofa';");
        if (bytesImage != null) {

            Bitmap bitmap = convertByteArraytoImage(bytesImage);
            productimage.setImageBitmap(bitmap);

        }


    }

    private Bitmap convertByteArraytoImage (byte[] bytes){
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    private byte[] convertImageViewToByteArray(ImageView imageView){

        Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG,80,byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();

    }
}

This is my logcat:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapp, PID: 12426
    java.lang.IllegalArgumentException: Image is Required
        at com.example.myapp.OrderProvider.insertCart(OrderProvider.java:96)
        at com.example.myapp.OrderProvider.insert(OrderProvider.java:69)
        at android.content.ContentProvider$Transport.insert(ContentProvider.java:313)
        at android.content.ContentResolver.insert(ContentResolver.java:1845)
        at com.example.myapp.Sofa1.SaveCart(Sofa1.java:165)
        at com.example.myapp.Sofa1.access$100(Sofa1.java:42)
        at com.example.myapp.Sofa1$3.onClick(Sofa1.java:138)
        at android.view.View.performClick(View.java:7257)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
        at android.view.View.performClickInternal(View.java:7213)
        at android.view.View.access$3800(View.java:828)
        at android.view.View$PerformClick.run(View.java:27921)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7830)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1040)
I/Process: Sending signal. PID: 12426 SIG: 9
Disconnected from the target VM, address: 'localhost:50639', transport: 'socket'
Learner
  • 9
  • 2
  • Suggest to you store image path or image url in database as a _String_ instead of _BLOB_ and retrieve it and display in imageview using _Glide_ –  Apr 02 '21 at 12:12

2 Answers2

0

In the ProductDetails class in the convertImageViewToByteArray method the line bitmap.compress(Bitmap.CompressFormat.JPEG,80,byteArrayOutputStream); assumes conversion. However, if you look at bitmap.compress the compress is not certain, thus the value returned should be checked and appropriate action taken if the compress does not work.

  • as per Returns boolean true if successfully compressed to the specified stream.

Perhaps use :-

private byte[] convertImageViewToByteArray(ImageView imageView){

    Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    if (!bitmap.compress(Bitmap.CompressFormat.JPEG,80,byteArrayOutputStream) return new byte[]{};
    return byteArrayOutputStream.toByteArray();
}

However, whether or not storing an empty byte array is acceptable needs to be considered and perhaps handled appropriately. So this fix might get around the issue but may just delay handling the underlying issue of why the image (if one) is not being compressed.

Furthermore, storing large images may be impossible, very hard or inefficient to subsequently retrieve. By large any image approaching something like 250kb. It is often recommended that rather than storing images in the database that the image is stored as a file and the path to the file is stored.

MikeT
  • 51,415
  • 16
  • 49
  • 68
0

hey bro sorry to say that I think you have to wrong way to added data into SQLite

simple use case - https://www.javatpoint.com/android-sqlite-tutorial

for storing an image in an SQLite database you have to use URI you can easily retry and store without any problem or crashed...don't use the blob method bro ... i personally didn't recommend it to use blob

Solution :

In uri store as a string in SQLite and after also if you want to show image and convert string to URI.

Uri to String and Reverse Machinasim - Converting of Uri to String

axar
  • 539
  • 2
  • 17