我创建了一个表订单,以显示购物车项目。当我单击产品详细信息活动中的添加到购物车按钮时,应用程序崩溃并转到上一页。但是,我可以在列表视图中看到购物车项目。
OrderProvider 类:
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();
}
}
这是我的日志:
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'
答案 0 :(得分:0)
在 convertImageViewToByteArray
方法的 ProductDetails 类中,行 bitmap.compress(Bitmap.CompressFormat.JPEG,80,byteArrayOutputStream);
假定转换。但是,如果您查看 bitmap.compress 压缩是不确定的,因此应该检查返回的值并在压缩不起作用时采取适当的措施。
也许使用:-
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();
}
但是,是否可以接受存储空字节数组需要考虑并可能适当处理。因此,此修复程序可能会解决该问题,但可能只会延迟处理图像(如果有)未压缩的潜在问题。
此外,存储大图像可能是不可能的,随后检索起来非常困难或效率低下。总的来说,任何接近 250kb 的图像。通常建议不要将图像存储在数据库中,而是将图像存储为文件并存储文件的路径。
答案 1 :(得分:0)
嘿兄弟对不起,我认为你必须以错误的方式将数据添加到 SQLite
简单用例 - https://www.javatpoint.com/android-sqlite-tutorial
要将图像存储在 SQLite 数据库中,您必须使用 URI 您可以轻松地重试和存储而不会出现任何问题或崩溃...不要使用 blob 方法兄弟...我个人不推荐它使用blob
解决方案:
在 uri 中存储为 SQLite 中的字符串,如果您想显示图像并将字符串转换为 URI。
Uri 到 String 和 Reverse Machinasim - Converting of Uri to String