I am currently developing an app in Android Studio (in Java) that can save some drawings and count the number of drawings per month you did.
I am using Room database and for the moment I only have one entity which is Drawing. It contains a title (string), a date (string) and an image (byte[]).
I have a form to add a drawing and I load an image from the gallery. When I add a drawing with no image (only date and title) it works, but when I add the image it does not save the drawing anymore.
I think it is the way I am getting the image that is making my code crashes.
I don't really know what to do, is there anyone who has an idea to fix the problem ?
package com.example.sketchhub.views;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.sketchhub.R;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class AddDrawing extends AppCompatActivity {
private EditText drawingTitleInput, drawingDateInput;
private ImageView drawingImageInput;
private Button saveBtn, addImgBtn;
public static final String EXTRA_ID = "com.gtappdevelopers.gfgroomdatabase.EXTRA_ID";
public static final String EXTRA_TITLE = "com.gtappdevelopers.gfgroomdatabase.EXTRA_TITLE";
public static final String EXTRA_DATE = "com.gtappdevelopers.gfgroomdatabase.EXTRA_DATE";
public static final String EXTRA_IMAGE = "com.gtappdevelopers.gfgroomdatabase.EXTRA_IMAGE";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_drawing);
// get inputs
drawingTitleInput = findViewById(R.id.addDrawing_titleInput);
drawingDateInput = findViewById(R.id.addDrawing_dateInput);
drawingImageInput = findViewById(R.id.addDrawing_imgView);
// get save button
saveBtn = findViewById(R.id.addDrawing_btnSaveDrawing);
addImgBtn = findViewById(R.id.addDrawing_btnAddImage);
// set date
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
String date = dateFormat.format(Calendar.getInstance().getTime());
drawingDateInput.setText(date);
Intent intent = getIntent();
if (intent.hasExtra(EXTRA_ID)) {
drawingTitleInput.setText(intent.getStringExtra(EXTRA_TITLE));
drawingDateInput.setText(intent.getStringExtra(EXTRA_DATE));
byte[] imageByteArray = intent.getByteArrayExtra(EXTRA_IMAGE);
if (imageByteArray != null) {
Bitmap imageBitmap = BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
drawingImageInput.setImageBitmap(imageBitmap);
}
}
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String drawingTitle = drawingTitleInput.getText().toString();
String drawingDate = drawingDateInput.getText().toString();
byte[] imageByteArray = null;
// Check if there is an image in the ImageView
if (drawingImageInput.getDrawable() instanceof BitmapDrawable) {
// If an image is selected, convert it to byte array
Bitmap imageBitmap = getBitmapFromImageView(drawingImageInput);
imageByteArray = getBytesFromBitmap(imageBitmap);
} else {
// If no image is selected, set imageByteArray to null
imageByteArray = null;
}
if (drawingDate.isEmpty()) {
Toast.makeText(AddDrawing.this, "Please enter valid drawing details.", Toast.LENGTH_SHORT).show();
return;
}
if (drawingTitle.isEmpty()) {
drawingTitle = "No Title";
}
saveDrawing(drawingTitle, drawingDate, imageByteArray);
}
});
addImgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 3);
}
});
}
private void saveDrawing(String drawingTitle, String drawingDate, byte[] imageByteArray) {
Intent data = new Intent();
data.putExtra(EXTRA_TITLE, drawingTitle);
data.putExtra(EXTRA_DATE, drawingDate);
if (imageByteArray != null) {
data.putExtra(EXTRA_IMAGE, imageByteArray);
}
int id = getIntent().getIntExtra(EXTRA_ID, -1);
if (id != -1) {
data.putExtra(EXTRA_ID, id);
}
setResult(RESULT_OK, data);
Toast.makeText(this, "Drawing has been saved to Room Database. ", Toast.LENGTH_SHORT).show();
// Finish the current activity
finish();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 3 && resultCode == RESULT_OK && data != null) {
Uri selectedImage = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImage);
drawingImageInput.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public byte[] getBytesFromBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}
private Bitmap getBitmapFromImageView(ImageView imageView) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
// If the ImageView has a BitmapDrawable, extract the Bitmap
return ((BitmapDrawable) drawable).getBitmap();
} else {
// If the ImageView doesn't have a BitmapDrawable, try to create a Bitmap from the Drawable
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
if (width <= 0 || height <= 0) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
}
I tried to debug the code.
When I get the drawable, it actually returns an empty string. This is why I think this is the problem.