I have a database app. It shows a list of items containing an image and strings. I want to store image in sqlite database in an activity and fetch it from another activity. But it shows null value is inserted. Here is the code for insertion of images in database---
public class EditorActivity extends AppCompatActivity implements View.OnClickListener{
private static int IMAGE_GALLERY_REQUEST=20;
private EditText mNameEditText;
private EditText mDescEditText;
private EditText mResEditText;
private EditText mStatusEditText;
private Button btn;
private byte[] b;
private Bitmap bitmap;
String mName,mDescription,mResident,mStatus;
int data;
public static String EXTRA_DATA="dataNo";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
mNameEditText = (EditText) findViewById(R.id.name);
mDescEditText = (EditText) findViewById(R.id.desc);
mResEditText = (EditText) findViewById(R.id.res);
mStatusEditText = (EditText) findViewById(R.id.status);
btn=findViewById(R.id.photo);
btn.setOnClickListener(this);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
data = (Integer) (bundle.get(EXTRA_DATA));
}
}
private void saveData()
{
mName=mNameEditText.getText().toString().trim();
mDescription=mDescEditText.getText().toString().trim();
mResident=mResEditText.getText().toString().trim();
mStatus=mStatusEditText.getText().toString().trim();
FriendsDbHelper helper=new FriendsDbHelper(this);
SQLiteDatabase db=helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(FriendContract.FriendEntry.NAME,mName);
values.put(FriendContract.FriendEntry.DESCRIPTION,mDescription);
values.put(FriendContract.FriendEntry.RESIDENCE,mResident);
values.put(FriendContract.FriendEntry.STATUS,mStatus);
values.put(FriendContract.FriendEntry.KEY_IMAGE,b);
db.insert(TABLE_NAME,null,values);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_edit,menu);
return true;
}
public void updateData() {
String name=mNameEditText.getText().toString().trim();
String description=mDescEditText.getText().toString().trim();
String resident=mResEditText.getText().toString().trim();
String status=mStatusEditText.getText().toString().trim();
//try{
FriendsDbHelper helper = new FriendsDbHelper(this);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
if(TextUtils.isEmpty(name))
{
name=mName;
}
if(TextUtils.isEmpty(description))
{
description=mDescription;
}
if(TextUtils.isEmpty(resident))
{
resident=mResident;
}
if(TextUtils.isEmpty(status))
{
status=mStatus;
}
values.put(NAME, name);
values.put(DESCRIPTION, description);
values.put(RESIDENCE, resident);
values.put(STATUS, status);
db.update(TABLE_NAME, values, _ID + "=?", new String[]{Integer.toString(data)});
/* }
catch (SQLiteException e)
{
Toast.makeText(this,"Update failed",Toast.LENGTH_LONG).show();
}*/
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.action_save:
saveData();
finish();
return true;
case R.id.action_update:
updateData();
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
Intent photoIntent=new Intent(Intent.ACTION_PICK);
File photoDirectory= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String photo=photoDirectory.getPath();
Uri uri=Uri.parse(photo);
photoIntent.setDataAndType(uri,"image/*");
startActivityForResult(photoIntent,IMAGE_GALLERY_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==RESULT_OK)
{
if(resultCode==IMAGE_GALLERY_REQUEST)
{
Uri uri=data.getData();
InputStream inputStream;
try
{
inputStream=getContentResolver().openInputStream(uri);
bitmap= BitmapFactory.decodeStream(inputStream);
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,0,stream);
b=stream.toByteArray();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Unable to open image",Toast.LENGTH_LONG).show();
}
}
}
}
}
As a result, strings in each element is visible but image is not visible.
I read same problem from
Insert bitmap to sqlite database. They told to use sqlitemaestro software. How to use that in android?
Please reply soon.
It seems as if the Byte array 'b' is null when you are using the values.put in the savedata method kindly log the variable and check.
Also to save image in SQLite we usually make use of Binary Large Objects i.e BLOBs
Here is a resource which may help you
How to store(bitmap image) and retrieve image from sqlite database in android?
Using a cutdown version of your code. There appears to be nothing wrong with the SQLite side. That is using :-
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static int IMAGE_GALLERY_REQUEST = 20;
private EditText mNameEditText;
private EditText mDescEditText;
private EditText mResEditText;
private EditText mStatusEditText;
private Button btn;
private byte[] b;
private Bitmap bitmap;
String mName, mDescription, mResident, mStatus;
int data;
public static String EXTRA_DATA = "dataNo";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNameEditText = (EditText) findViewById(R.id.name);
mDescEditText = (EditText) findViewById(R.id.desc);
mResEditText = (EditText) findViewById(R.id.res);
mStatusEditText = (EditText) findViewById(R.id.status);
btn = findViewById(R.id.photo);
btn.setOnClickListener(this);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
data = (Integer) (bundle.get(EXTRA_DATA));
}
}
private void saveData() {
mName = mNameEditText.getText().toString().trim();
mDescription = mDescEditText.getText().toString().trim();
mResident = mResEditText.getText().toString().trim();
mStatus = mStatusEditText.getText().toString().trim();
FriendsDbHelper helper = new FriendsDbHelper(this);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(FriendsDbHelper.COL_FRIENDS_NAME, mName);
values.put(FriendsDbHelper.COL_FRIENDS_DESCRIPTION, mDescription);
values.put(FriendsDbHelper.COL_FRIENDS_RESIDENCE, mResident);
values.put(FriendsDbHelper.COL_FRIENDS_STATUS, mStatus);
values.put(FriendsDbHelper.COL_FRIENDS_KEY_IMAGE, b);
db.insert(FriendsDbHelper.TB_FRIENDS, null, values);
}
#Override
public void onClick(View v) {
if (v.getId() == btn.getId()) {
b = new byte[]{0,2,3,4,5,6,7,8,9};
saveData();
}
}
}
Saves a BLOB as expected, as per :-
i.e. the last column is the array of bytes ( the elements being 0,2,3,4,5,6,7,8,9) shown as hex representation as was expected.
This therefore rules out any issue with the SQLite aspect and therefore indicates that the issue is that b is not being set accordingly in the onActivityResult method, which itself relies upon the intent.ACTION_PICK.
You may wish to refer to opening an image using Intent.ACTION_PICK (see notes re returning null) and perhaps Intent.ACTION_PICK behaves differently or the many other SO questions regarding intent.ACTION_PICK.
You may also wish to use something like :-
private void saveData()
{
mName=mNameEditText.getText().toString().trim();
mDescription=mDescEditText.getText().toString().trim();
mResident=mResEditText.getText().toString().trim();
mStatus=mStatusEditText.getText().toString().trim();
FriendsDbHelper helper=new FriendsDbHelper(this);
SQLiteDatabase db=helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(FriendContract.FriendEntry.NAME,mName);
values.put(FriendContract.FriendEntry.DESCRIPTION,mDescription);
values.put(FriendContract.FriendEntry.RESIDENCE,mResident);
values.put(FriendContract.FriendEntry.STATUS,mStatus);
values.put(FriendContract.FriendEntry.KEY_IMAGE,b);
//<<<< ADDED to issue Toast if no valid image...
if (b == null) {
Toast.makeText(this,"No valid Image - No Data Stored!",Toast.LENGTH_LONG).show();
return;
}
db.insert(TABLE_NAME,null,values);
}
Related
I'm making an app to insert data. But when I click on add button by giving all the details. App return me to previous page
This is the way I create insert class
public class InsertStudent extends AppCompatActivity {
Button instudent;
DBHelper dbHelper;
EditText sName,sDOB,sAddress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_insert_student);
instudent = findViewById(R.id.btninsert);
sName = findViewById(R.id.insertname);
sDOB = findViewById(R.id.insertdob)
;
sAddress = findViewById(R.id.insertaddress);
Below is the way I coded to insert data
instudent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String userName = sName.getText().toString();
String dateB = sDOB.getText().toString();
String addr = sAddress.getText().toString();
boolean count = dbHelper.addInfo(userName,dateB,addr );
if(count =true){
Toast.makeText(InsertStudent.this, "Inserted!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(InsertStudent.this, "Something went wrong!", Toast.LENGTH_SHORT).show();
}
}
});
This is addinfo method in DBHelper class
public boolean addInfo(String stdName, String stdDOB, String stdAddress){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(UserProfile.Users.COLUMN_STDNAME, stdName);
contentValues.put(UserProfile.Users.COLUMN_DATEOFBIRTH, stdDOB);
contentValues.put(UserProfile.Users.TABLE_ADDRESS, stdAddress);
long result = sqLiteDatabase.insert(UserProfile.Users.TABLE_NAME, null, contentValues);
if(result==1)
return false;
else
return true;
}
}
The insert method of "SQLiteDatabase" class doesn't return the
count, it's returns the id of the inserted row. so you are checking
if return result is 1, it's a true process, but it's not a way to
check the insert method. It means you need to check if there is any
return result, your insert action performed successfully, but if
there is a problem, the application will crash.
Make sure you created the table that you want to insert data in it.
My goal
Step 1: User registers a new account into SQLite Database
Step 2: User logs in and goes to their Profile
Step 3: Name, Address, and Email user entered in registration get dynamically put into the appropriate TextViews.
The problem is I can only get the email to display since I am just storing that email from the Login EditText into an intent. But I am unable to display the Name and Address of the user that they entered when they registered to be display as well in their profile when they sign in.
I have tried to use:
String NameHolder = intent.getStringExtra(SQLiteHelper.Table_Column_1_Name);
tvName.setText(NameHolder);
But that doesn't display anything in the tvName TextView.
Profile.java
public class Profile extends AppCompatActivity {
String NameHolder, EmailHolder, AddressHolder;
Button bPicButton, bSendToPharmacy, bLogout;
ImageView imageView;
String pathToFile;
TextView tvName, tvAddress, tvEmail;
private NotificationManagerCompat notificationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
bPicButton = findViewById(R.id.bTakePhoto);
bSendToPharmacy = findViewById(R.id.bSendToPharm);
bLogout = findViewById(R.id.bLogout);
imageView = findViewById(R.id.imagePrescription);
tvName = findViewById(R.id.tvName);
tvAddress = findViewById(R.id.tvAddress);
tvEmail = findViewById(R.id.tvEmail);
// Dynamically place Name, Address, and Email into TextViews
Intent intent = getIntent();
EmailHolder = intent.getStringExtra(MainActivity.UserEmail);
displayInfo();
notificationManager = NotificationManagerCompat.from(this);
// Ask for permission for Camera and Storage
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// if camera successfully pops up and takes photo, set photo in ImageView
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
Bitmap bitmap = BitmapFactory.decodeFile(pathToFile);
imageView.setImageBitmap(bitmap);
}
}
// If Image was successfully placed in imageView, display submit to pharmacy button
if (imageView != null){
bSendToPharmacy.setVisibility(View.VISIBLE);
}
}
// Take Picture button onClick listener
public void takePhoto(View view) {
setPhotoTaken();
}
// Take photo
private void setPhotoTaken() {
Intent takePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Make sure the app can handle our intent
if (takePhoto.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
// Created Photo file
photoFile = createPhotoFile();
// Get path of our photo file
if (photoFile != null) {
pathToFile = photoFile.getAbsolutePath();
Uri photoUri = FileProvider.getUriForFile(Profile.this, "com.cognizant.expressprescriptionregistration.fileprovider", photoFile);
takePhoto.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePhoto, 1);
}
}
}
// Create the file where the photo will be stored
private File createPhotoFile() {
// Name of file
String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
// Location of storage
File storedDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File photo = null;
try {
// Creates file in storedDir
photo = File.createTempFile(name, ".jpg", storedDir);
} catch (IOException e) {
e.printStackTrace();
}
return photo;
}
// Send to Pharmacy Button
public void sendToPharmacy(View view) {
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
String name = tvName.getText().toString();
String message = "You have arrived at your pick up location.";
android.app.Notification notification = new NotificationCompat.Builder(this, CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(name)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(bitmap)
.bigLargeIcon(null))
.setContentText(message)
.setContentTitle("GeoFence Demo")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
notificationManager.notify(1, notification);
openSuccessActivity();
}
// Method to open Register Activity
private void openSuccessActivity() {
Intent intent = new Intent(this, Success.class);
startActivity(intent);
}
// Prescription History DialogWindow
public void prescriptionHistory(View view) {
prescriptionHistoryDialogWindow();
}
private void prescriptionHistoryDialogWindow() {
PrescriptionHistoryDW helpDialog = new PrescriptionHistoryDW();
helpDialog.show(getSupportFragmentManager(), "Prescription History");
}
// Patient Health Condition DialogWindow
public void patientHealthCondition(View view) {
patientHealthConditionDialogWindow();
}
private void patientHealthConditionDialogWindow() {
PatientHealthConditionDW helpDialog = new PatientHealthConditionDW();
helpDialog.show(getSupportFragmentManager(), "Patient Health Description");
}
// Insurance Plan Details DialogWindow
public void insurancePlanDetails(View view) {
insurancePlanDetailsDialogWindow();
}
private void insurancePlanDetailsDialogWindow() {
InsurancePlanDetailsDW helpDialog = new InsurancePlanDetailsDW();
helpDialog.show(getSupportFragmentManager(), "Insurance Plan Details");
}
// Logout button
public void bLogout(View view) {
finish();
Toast.makeText(Profile.this,"Logged out. See you soon!", Toast.LENGTH_LONG).show();
}
public void displayInfo() {
sqLiteDatabaseObj = sqLiteHelper.getWritableDatabase();
Cursor cursor = sqLiteDatabaseObj.rawQuery("SELECT * FROM " + SQLiteHelper.TABLE_NAME, new String[]{"WHERE " + Table_Column_2_Email + " = '" + EmailHolder + "'"}, null);
if (cursor != null && cursor.moveToFirst()) {
tvEmail.setText(cursor.getString(cursor.getColumnIndex(Table_Column_2_Email)));
tvName.setText(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Table_Column_1_Name)));
tvAddress.setText(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Table_Column_4_Address)));
}
if(cursor != null) {
cursor.close();
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final String UserEmail = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// EditText Field where user puts email address to login
etEmail = findViewById(R.id.etEmail);
}
emailHolder = etEmail.getText().toString();
// Going to Profile activity after login success message.
Intent intent = new Intent(MainActivity.this, Profile.class);
// Send Email to Profile Activity using intent.
intent.putExtra(UserEmail, emailHolder);
startActivity(intent);
}
SQLiteHelper.java
public class SQLiteHelper extends SQLiteOpenHelper {
static String DATABASE_NAME="UserDataBase";
public static final String TABLE_NAME="UserTable";
public static final String Table_Column_ID="id";
public static final String Table_Column_1_Name="name";
public static final String Table_Column_2_Email="email";
public static final String Table_Column_3_Password="password";
public static final String Table_Column_4_Address="address";
public SQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase database) {
String CREATE_TABLE="CREATE TABLE IF NOT EXISTS "+TABLE_NAME+" ("+Table_Column_ID+" INTEGER PRIMARY KEY, "+Table_Column_1_Name+" VARCHAR, "+Table_Column_2_Email+" VARCHAR, "+Table_Column_3_Password+" VARCHAR, "+Table_Column_4_Address+" VARCHAR)";
database.execSQL(CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
}
Register.java
public class Register extends AppCompatActivity {
Button bRegister;
EditText etName, etAddress, etEmail, etPassword, etPrescriptionHistory, etPatientHealthCondition, etInsurancePlanDetails;
String NameHolder, EmailHolder, PasswordHolder, AddressHolder;
Boolean EditTextEmptyHolder;
SQLiteDatabase sqLiteDatabaseObj;
String SQLiteDataBaseQueryHolder ;
SQLiteHelper sqLiteHelper;
Cursor cursor;
String F_Result = "Not_Found";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
bRegister = findViewById(R.id.bRegister);
// EditText fields
etName = findViewById(R.id.etName);
etAddress = findViewById(R.id.etAddress);
etEmail = findViewById(R.id.etEmail);
etPassword = findViewById(R.id.etPassword);
etPrescriptionHistory = findViewById(R.id.etPrescriptionHistory);
etPatientHealthCondition = findViewById(R.id.etPatientHealthCondition);
etInsurancePlanDetails = findViewById(R.id.etInsurancePlanDetails);
sqLiteHelper = new SQLiteHelper(this);
}
// Register Button
public void registerButton(View view) {
// Intent intent = new Intent(this, Profile.class);
// startActivity(intent);
// Create SQlite Database if it doesn't exist
SQLiteDataBaseBuild();
// Create SQLite Table if it doesn't exist
SQLiteTableBuild();
// Make sure no EditText field is empty
CheckEditTextStatus();
// Make sure email has not already been registered
CheckingEmailAlreadyExistsOrNot();
// Empty all EditText fields after successful database entry
EmptyEditTextAfterDataInsert();
}
// SQLite database build method.
public void SQLiteDataBaseBuild(){
sqLiteDatabaseObj = openOrCreateDatabase(SQLiteHelper.DATABASE_NAME, Context.MODE_PRIVATE, null);
}
// SQLite table build method.
public void SQLiteTableBuild() {
sqLiteDatabaseObj.execSQL("CREATE TABLE IF NOT EXISTS " + SQLiteHelper.TABLE_NAME + "(" + SQLiteHelper.Table_Column_ID + " PRIMARY KEY AUTOINCREMENT NOT NULL, " + SQLiteHelper.Table_Column_1_Name + " VARCHAR, " + SQLiteHelper.Table_Column_2_Email + " VARCHAR, " + SQLiteHelper.Table_Column_3_Password + " VARCHAR, " + SQLiteHelper.Table_Column_4_Address + " VARCHAR);");
}
// Insert data into SQLite database method.
public void InsertDataIntoSQLiteDatabase(){
// If editText is not empty then this block will executed.
if(EditTextEmptyHolder == true)
{
// SQLite query to insert data into table.
SQLiteDataBaseQueryHolder = "INSERT INTO "+SQLiteHelper.TABLE_NAME+" (name,email,password, address) VALUES('"+NameHolder+"', '"+EmailHolder+"', '"+PasswordHolder+"', '"+AddressHolder+"');";
// Executing query.
sqLiteDatabaseObj.execSQL(SQLiteDataBaseQueryHolder);
// Closing SQLite database object.
sqLiteDatabaseObj.close();
// Message if successful
Toast.makeText(Register.this,"User Registered Successfully", Toast.LENGTH_LONG).show();
}
// If any EditText fields are empty, prevent user from creating profile
else {
// Message if any EditText fields are empty
Toast.makeText(Register.this,"Please Make Sure All Fields are filled.", Toast.LENGTH_LONG).show();
}
}
// Empty edittext after done inserting process method.
public void EmptyEditTextAfterDataInsert(){
etName.getText().clear();
etEmail.getText().clear();
etPassword.getText().clear();
etAddress.getText().clear();
}
// Method to check EditText is empty or Not.
public void CheckEditTextStatus(){
// Getting value from All EditText and storing into String Variables.
NameHolder = etName.getText().toString() ;
EmailHolder = etEmail.getText().toString();
PasswordHolder = etPassword.getText().toString();
AddressHolder = etAddress.getText().toString();
if(TextUtils.isEmpty(NameHolder) || TextUtils.isEmpty(EmailHolder) || TextUtils.isEmpty(PasswordHolder) || TextUtils.isEmpty(EmailHolder)){
EditTextEmptyHolder = false ;
}
else {
EditTextEmptyHolder = true ;
}
}
// Checking Email is already exists or not.
public void CheckingEmailAlreadyExistsOrNot(){
// Opening SQLite database write permission.
sqLiteDatabaseObj = sqLiteHelper.getWritableDatabase();
// Adding search email query to cursor.
cursor = sqLiteDatabaseObj.query(SQLiteHelper.TABLE_NAME, null, " " + SQLiteHelper.Table_Column_2_Email + "=?", new String[]{EmailHolder}, null, null, null);
while (cursor.moveToNext()) {
if (cursor.isFirst()) {
cursor.moveToFirst();
// If email is already created, set error
F_Result = "Email already registered";
// Closing cursor.
cursor.close();
}
}
// Calling method to check final result and insert data into SQLite database.
CheckFinalResult();
}
// Checking result
public void CheckFinalResult(){
// Checking whether email is already exists or not.
if(F_Result.equalsIgnoreCase("Email already registered"))
{
// If email is exists then toast msg will display.
Toast.makeText(Register.this,"Email already registered", Toast.LENGTH_LONG).show();
}
else {
// If email is not already in the database, it will be created in the database
InsertDataIntoSQLiteDatabase();
}
F_Result = "Not_Found" ;
}
}
Looking after your code, It seems you are not saving the data in the actual Database.
But passing them from one Activity to another.
I would suggest you go through this training to learn how to save data with Room.
Let me know if you face any trouble in understanding. I can point you out in the right direction.
If you are sure you are storing the data correctly.
Create sqLiteDatabaseObj instance how you have created in Register Activity and then Below method will set the user details. Call this method in OnCreate at the end of it.
public void displayInfo() {
Cursor cursor = sqLiteDatabaseObj.rawQuery("SELECT * FROM " + SQLiteHelper.TABLE_NAME +" WHERE "+Table_Column_2_Email +" = '"+EmailHolder +"'", null);
if (cursor != null && cursor.moveToFirst()) {
tvEmail.setText(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Table_Column_2_Email)));
tvName.setText(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Table_Column_1_Name)));
tvAddress.setText(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Table_Column_4_Address)));
}
if(cursor != null) {
cursor.close();
}
}
}
This post is a continuance of my previous question about saving an image to SQLite. I am getting cannot convert Blob to String error at FoodList activity startup with crash. I am using SQLite Helper and an adapter. My Main Activity code is as follows:
public static SQLiteHelper sqLiteHelper;
final int REQUEST_CODE_GALLERY = 999;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
sqLiteHelper = new SQLiteHelper(this, "FoodDB.sqlite", null, 1);
sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS FOOD (name TEXT, price TEXT, image BLOB)");
btnChoose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ActivityCompat.requestPermissions(
MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_GALLERY
);
}
});
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtName.getText().toString().trim(),
edtPrice.getText().toString().trim(),
imageViewToByte(imageView)
);
Toast.makeText(getApplicationContext(), "Entry Added", Toast.LENGTH_LONG).show();
edtName.setText("");
edtPrice.setText("");
imageView.setImageResource(R.mipmap.ic_launcher);
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
btnList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, FoodList.class);
startActivity(intent);
}
});
}
private byte[] imageViewToByte(ImageView image) {
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CODE_GALLERY) {
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_GALLERY);
}
else {
Toast.makeText(getApplicationContext(), "Permission Denied", Toast.LENGTH_LONG).show();
}
//return;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQUEST_CODE_GALLERY && resultCode == RESULT_OK && data != null) {
Uri uri = data.getData();
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(bitmap);
}
catch (FileNotFoundException e){
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void init() {
edtName = findViewById(R.id.edtName);
edtPrice = findViewById(R.id.edtPrice);
btnChoose = findViewById(R.id.btnChoose);
btnAdd = findViewById(R.id.btnAdd);
btnList = findViewById(R.id.btnList);
imageView = findViewById(R.id.imageView);
}
}
Then my SQLite Helper class is as follows:
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public void queryData(String sql) {
SQLiteDatabase database = getWritableDatabase();
database.execSQL(sql);
}
public void insertData(String name, String price, byte[] image) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO FOOD VALUES (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, price);
statement.bindBlob(3, image);
statement.executeInsert();
}
public Cursor getData(String sql) {
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
My food list adapter code is this:
public class FoodListAdapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<Food> foodsList;
public FoodListAdapter(Context context, int layout, ArrayList<Food> foodsList) {
this.context = context;
this.layout = layout;
this.foodsList = foodsList;
}
#Override
public int getCount() {
return foodsList.size();
}
#Override
public Object getItem(int position) {
return foodsList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
ImageView imageView;
TextView txtName, txtPrice;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
View row = view;
ViewHolder holder = new ViewHolder();
if(row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(layout, null);
holder.txtName = (TextView) row.findViewById(R.id.txtName);
holder.txtPrice = (TextView) row.findViewById(R.id.txtPrice);
holder.imageView = (ImageView) row.findViewById(R.id.imgFood);
row.setTag(holder);
}
else {
holder = (ViewHolder) row.getTag();
}
Food food = foodsList.get(position);
holder.txtName.setText(food.getName());
holder.txtPrice.setText(food.getPrice());
byte[] foodImage = food.getImage();
Bitmap bitmap = BitmapFactory.decodeByteArray(foodImage, 0, foodImage.length);
holder.imageView.setImageBitmap(bitmap);
return row;
}
}
I also have a class called Food that code is also as follows:
public class Food {
private String name;
private String price;
private byte[] image;
public Food(String name, String price, byte[] image) {
this.name = name;
this.price = price;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
}
And last but not least, here is the code for the activity that crashes upon initialization FoodList:
public class FoodList extends AppCompatActivity {
GridView gridView;
ArrayList<Food> list;
FoodListAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.food_list_activity);
gridView = findViewById(R.id.gridView);
list = new ArrayList<>();
adapter = new FoodListAdapter(this, R.layout.food_items, list);
gridView.setAdapter(adapter);
Cursor cursor = MainActivity.sqLiteHelper.getData("SELECT * FROM FOOD");
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String price = cursor.getString(2);
byte[] image = cursor.getBlob(3);
list.add(new Food(name, price, image));
}
adapter.notifyDataSetChanged();
}
}
I have no clue what is causing this error. hopefully someone can shed some light on my issue...
Cursor cursor = MainActivity.sqLiteHelper.getData("SELECT * FROM FOOD");
Will return a Cursor that has 3 columns, name, price and image as such you will have columns with offsets 0 (name), 1 (price) and 2 (image).
Therefore, getString(2) is trying to get the image column which is a BLOB, but as a String, hence the error trying to convert the BLOB to a String.
If it hand't of failed then you would have got another failure with an index error with getBlob(3) as there is no column with an offset of 3.
It is best to not use offsets normally, but rather use the getColumnIndex(column_name) method which returns the column offset(index) according to the given column name.
As such, you could use the following, which would fix the issue :-
String name = cursor.getString(getColumnIndex("name"));
String price = cursor.getString(getColumnIndex("price"));
byte[] image = cursor.getBlob(getColumnIndex("image"));
I am trying to create an app where the user can select their profile picture from gallery. I decided to save their profile picture to my Database as Blob. I am able to save the image and even retrieve it. The thing is, I am not able to replace it, or whenever I click it again, the application stops working and when I check my table where I store the image it says "Too much data returned..."
public class AccountFragment extends Fragment implements OnClickListener {
private LoginDataBaseAdapter loginDataBaseAdapter;
Bitmap image;
Bitmap bitmap;
String picture_location;
TextView textTargetUri;
ImageView targetImage;
public static final String MyPREFERENCES = "MyPrefs" ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// create a instance of SQLite Database
loginDataBaseAdapter = new LoginDataBaseAdapter(getActivity());
loginDataBaseAdapter=loginDataBaseAdapter.open();
//intialize variables
textTargetUri = (TextView) rootView.findViewById(R.id.targeturi);
targetImage=(ImageView) rootView.findViewById(R.id.profpic);
targetImage.setOnClickListener(new ImageView.OnClickListener(){
#Override
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}});
showpic();
return rootView;
}
#Override
public void onActivityResult( int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK){
Uri targetUri = data.getData();
picture_location = targetUri.toString();
textTargetUri.setText(targetUri.toString());
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(targetUri));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
loginDataBaseAdapter.insertPhoto(byteArray);
showpic();
}
catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
public void showpic() {
Cursor cursor = loginDataBaseAdapter.fetchProfileImageFromDatabase();
if(cursor != null)
{
cursor.moveToFirst();
byte[] data = cursor.getBlob(cursor.getColumnIndex("Path"));
ByteArrayInputStream imageStream = new ByteArrayInputStream(data);
Bitmap theImage = BitmapFactory.decodeStream(imageStream);
targetImage.setImageBitmap(theImage);
}
cursor.close();
}
}
and my database handler:
//IMAGE
public static final String Profpic_TABLE = "ProfilePic";
public static final String KEY_ProfpicID = "_id";
public static final String KEY_ProfPic = "Path";
//ProfilePic-Table
static final String DATABASE_ProfPic =
"create table " + Profpic_TABLE + " ("
+ KEY_ProfpicID + " integer primary key DEFAULT 1, "
+ KEY_ProfPic + " BLOB);";
public long insertPhoto(byte[] EImage) {
db.execSQL("delete from "+ Profpic_TABLE);
try {
System.out.println("Function call : ");
ContentValues values = new ContentValues();
values.put(KEY_ProfPic, EImage);
return db.insert(Profpic_TABLE, null, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
public Cursor fetchProfileImageFromDatabase()
{
return db.rawQuery("SELECT Path FROM ProfilePic where _id = 1 " , null);
}
}
I was able to finally solve it. Turns out I have to do it this way instead:
public void showpic() {
LoginDataBaseAdapter db = loginDataBaseAdapter.open();
boolean emptytab = false;
boolean empty = db.checkPic(null, emptytab);
//Cursor cursor = loginDataBaseAdapter.fetchProfileImageFromDatabase();
if(empty==false)
{
Cursor cursor = loginDataBaseAdapter.fetchProfileImageFromDatabase();
cursor.moveToFirst();
byte[] data = cursor.getBlob(cursor.getColumnIndex("Path"));
ByteArrayInputStream imageStream = new ByteArrayInputStream(data);
Bitmap theImage = BitmapFactory.decodeStream(imageStream);
targetImage.setImageBitmap(theImage);
cursor.close();
}
}
and on my db adapter I added this:
public boolean checkPic(String count, Object object) {
boolean empty = false;
Cursor cursor = db.rawQuery("SELECT count(*) FROM ProfilePic", null);
if(cursor != null)
{
cursor.moveToFirst();
if(cursor.getInt(0)== 0)
{
empty = true; //rows not null;
}
else
{
empty = false; // rows null;
}
}
return empty;
}
I created an app for scanning barcodes and QR code using the ZXing library. I also implemented a database that stores the scanned products. I need to implement a listview to display the stored products. any ideas?
here are classes:
BarCodeActivity
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spot_pay);
Button addButton = (Button) findViewById (R.id.addMenuButton);
addButton.setOnClickListener (new OnClickListener(){
public void onClick (View v){
startActivity(new Intent(CodiceBarreActivity.this, AggiungiCodiceActivity.class));
}
});
}
static final class ProductData {
String barcode;
String format;
String title;
BigDecimal price;
}
}
ProductDatabase:
private SQLiteDatabase db;
private static class ProductDatabaseHelper extends SQLiteOpenHelper {
public ProductDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
StringBuilder sql = new StringBuilder();
sql.append("create table ").append(PRODUCT_TABLE)
.append("( ")
.append(" _id integer primary key,")
.append(" barcode text,")
.append(" format text,")
.append(" title text,")
.append(" price currency")
.append(") ");
db.execSQL(sql.toString());
Log.d(TAG, PRODUCT_TABLE + "table created");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + PRODUCT_TABLE);
Log.d(TAG, PRODUCT_TABLE + "table dropped");
onCreate(db);
}
}
public CodiciDatabase(Context context) {
ProductDatabaseHelper helper = new ProductDatabaseHelper(context);
db = helper.getWritableDatabase();
}
public boolean insert(ProductData product) {
ContentValues vals = new ContentValues();
vals.put("barcode", product.barcode);
vals.put("format", product.format);
vals.put("title", product.title);
vals.put("price", product.price.multiply(ONE_HUNDRED).longValue());
return db.insert(PRODUCT_TABLE, null, vals) != -1;
}
}
AddProduct
private static final int REQUEST_BARCODE = 0;
private static final ProductData mProductData = new ProductData();
private EditText mBarcodeEdit;
private EditText mFormatEdit;
private EditText mTitleEdit;
private EditText mPriceEdit;
private Button mScanButton;
private Button mAddButton;
private CodiciDatabase mProductDb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_product);
mBarcodeEdit = (EditText) findViewById(R.id.barcodeEdit);
mFormatEdit = (EditText) findViewById(R.id.codeFormatEdit);
mTitleEdit = (EditText) findViewById(R.id.titleEdit);
mPriceEdit = (EditText) findViewById(R.id.priceEdit);
mScanButton = (Button) findViewById(R.id.scanButton);
mScanButton.setOnClickListener(this);
mAddButton = (Button) findViewById(R.id.addButton);
mAddButton.setOnClickListener(this);
mProductDb = new CodiciDatabase(this); // not yet shown
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.scanButton:
Intent intent = new Intent ("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
startActivityForResult(intent, REQUEST_BARCODE);
break;
case R.id.addButton:
String barcode = mBarcodeEdit.getText().toString();
String format = mFormatEdit.getText().toString();
String title = mTitleEdit.getText().toString();
String price = mPriceEdit.getText().toString();
String errors = validateFields(barcode, format, title, price);
if (errors.length() > 0) {
showInfoDialog(this, "Please fix errors", errors);
} else {
mProductData.barcode = barcode;
mProductData.format = format;
mProductData.title = title;
mProductData.price = new BigDecimal(price);
mProductDb.insert(mProductData);
showInfoDialog(this, "Success", "Product saved successfully");
resetForm();
}
break;
}
}
}
private void resetForm() {
mBarcodeEdit.getText().clear();
mFormatEdit.getText().clear();
mTitleEdit.getText().clear();
mPriceEdit.getText().clear();
}
private void showInfoDialog(Context context, String title, String information) {
new AlertDialog.Builder (context)
.setMessage(information)
.setTitle(title)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
public void onActivityResult(int requestCode, int resultCode, Intent intent){
if (requestCode == REQUEST_BARCODE){
if (resultCode == RESULT_OK) {
String barcode = intent.getStringExtra("SCAN_RESULT");
mBarcodeEdit.setText(barcode);
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
mFormatEdit.setText(format);
} else if (resultCode == RESULT_CANCELED){
finish();
}
}
}
}
private static String validateFields(String barcode, String format,
String title, String price) {
StringBuilder errors = new StringBuilder();
if (barcode.matches("^\\s*$")) {
errors.append("Barcode required\n");
}
if (format.matches("^\\s*$")) {
errors.append("Format required\n");
}
if (title.matches("^\\s*$")) {
errors.append("Title required\n");
}
if (!price.matches("^-?\\d+(.\\d+)?$")) {
errors.append("Need numeric price\n");
}
return errors.toString();
}
}
Overview of what you need to do:
Run a query on your database that will return a Cursor to you. Once you've got that you'll have to make make a CursorAdapter and override its getView() method to inflate and populate the row Views. After that you can use the ListView.setAdapter() method passing in an instance of your adapter. It will handle updating the list on the screen for you whenever there is new data.
I suggest instead of trying to tackle this in your own project you take a break from that and go do this Notepad tutorial from the developer docs. It is very small and simple but once you are complete you will have some sample code to use when you are working on doing this for your barcode application.