I'm new to android and I'm coding an app, and I want to get an image from my database and send it to the gallery I know how to do the opposite but this I have no idea what to do or how to start.
Here's the code I wrote:
public class ImageStorageActivity extends AppCompatActivity {
// DATABASE
public static DatabaseManager databaseManager;
final int REQUEST_CODE_GALLERY = 999;
ImageView imageView;
// grid view
GridView gridView;
ArrayList<Photo> list;
Photoadapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_storage);
imageView = findViewById(R.id.imageView);
CreateDatabase(); // create the database
gridView();
}
public void CreateDatabase() {
databaseManager = new DatabaseManager(this, "Image.db", null, 1);
databaseManager.queryData("CREATE TABLE IF NOT EXISTS Image(Id INTEGER PRIMARY KEY AUTOINCREMENT, image BLOB)");
Log.d("DATABASE", "Database was created");
}
private void update() {
// get all data from sqlite
Cursor cursor = ImageStorageActivity.databaseManager.getData("SELECT * FROM Image");
list.clear();
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
byte[] image = cursor.getBlob(1);
list.add(new Photo(id, image));
}
adapter.notifyDataSetChanged();
}
public void gridView(){
gridView = findViewById(R.id.gridView);
list = new ArrayList<>();
adapter = new Photoadapter(this, R.layout.photo_list, list);
gridView.setAdapter(adapter);
gridView.setBackgroundColor(Color.BLACK);
gridView.setPadding(5,5,5,5);
Log.d("gridView", "gridView is working");
// get all data from sqlite
final Cursor cursor = ImageStorageActivity.databaseManager.getData("SELECT * FROM Image");
list.clear();
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
byte[] image = cursor.getBlob(1);
list.add(new Photo( id,image));
}
adapter.notifyDataSetChanged();
Log.d("data", "get all data from sqlite");
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
CharSequence[] items = {"Delete"};
AlertDialog.Builder dialog = new AlertDialog.Builder(ImageStorageActivity.this);
dialog.setTitle("Choose an action");
dialog.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
// delete
Cursor c = ImageStorageActivity.databaseManager.getData("SELECT id FROM Image");
ArrayList<Integer> arrID = new ArrayList<>();
while (c.moveToNext()) {
arrID.add(c.getInt(0));
}
showDialogDelete(arrID.get(position));
}
}
});
dialog.show();
return true;
}
});
}
private void showDialogDelete(final int idImage) {
final AlertDialog.Builder dialogDelete = new AlertDialog.Builder(ImageStorageActivity.this);
dialogDelete.setTitle("Warning!!");
dialogDelete.setMessage("Are you sure you want to this delete?");
dialogDelete.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
ImageStorageActivity.databaseManager.fetch(idImage);
ImageStorageActivity.databaseManager.deleteData(idImage);
Toast.makeText(getApplicationContext(), "Delete successfully!!!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e("error", e.getMessage());
}
update();
}
});
dialogDelete.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialogDelete.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_image, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
RelativeLayout Main_view = findViewById(R.id.main_view);
switch (item.getItemId()) {
case R.id.add: {
try{
ActivityCompat.requestPermissions(
ImageStorageActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_GALLERY);
}
catch (Exception e){
e.printStackTrace();
}
break;
}
default:
return super.onOptionsItemSelected(item);
}
return false;
}
public static 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;
}
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(), "You don't have permission to access file location!", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#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);
databaseManager.insertData(imageViewToByte(imageView));
Toast.makeText(getApplicationContext(), "Added successfully!", Toast.LENGTH_SHORT).show();
imageView.setImageResource(R.mipmap.ic_launcher);
getContentResolver().delete(uri,null,null);
update();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
Here's my database
public class DatabaseManager extends SQLiteOpenHelper{
public DatabaseManager(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( byte[] image ) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO IMAGE VALUES (NULL,? ,?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindBlob(1,image);
statement.executeInsert();
}
public void updateData(byte[] image , int id ){
SQLiteDatabase database = getWritableDatabase();
String sql ="UPDATE IMAGE SET image = ? WHERE id = ? ";
SQLiteStatement statement = database.compileStatement(sql);
statement.bindBlob(1,image);
statement.bindDouble(2,(double)id);
statement.execute();
database.close();
}
public void deleteData(int id) {
SQLiteDatabase database = getWritableDatabase();
String sql = "DELETE FROM IMAGE WHERE id = ?";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindDouble(1, (double)id);
statement.execute();
database.close();
}
public Cursor getData(String sql){
SQLiteDatabase database = getWritableDatabase();
return database.rawQuery(sql,null);
}
public Cursor fetch(int id){
SQLiteDatabase database = getWritableDatabase();
String sql = "SELECT FROM IMAGE WHERE id = ? ";
Cursor c = database.rawQuery(sql,null);
return c ;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
You can try below code to convert from blob to byte array and then use that byte array to create bitmap which you can show in imageview.
byte[] byteArray = DBcursor.getBlob(columnIndex);
Bitmap bm = BitmapFactory.decodeByteArray(byteArray, 0 ,byteArray.length);
Related
I am using an external SQlite database in my project and a Listview with simple adapter, in fact it works fine but i wanna show images in Listview using glide library. i stored images url in database but i don't know how can I pass it to glide , it's possible or not?
thanks in advance.
public class DatabaseHandler extends SQLiteOpenHelper {
private Context main_context;
private static String DB_PATH;
private static String DB_NAME = "ebook_db.db";
private static int DB_VERSION = 1;
private static String DB_TBL_BOOKS = "books";
private static String DB_TBL_SETTINGS = "settings";
private SQLiteDatabase db;
public DatabaseHandler(Context con) {
super(con, DB_NAME, null, DB_VERSION);
main_context = con;
DB_PATH = con.getCacheDir().getPath() + "/" + DB_NAME;
}
#Override
public void onCreate(SQLiteDatabase db) {
/* do nothing */
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/* do nothing */
}
private boolean dbExists() {
File f = new File(DB_PATH);
if (f.exists())
return true;
else
return false;
}
private boolean copyDB() {
try {
FileOutputStream out = new FileOutputStream(DB_PATH);
InputStream in = main_context.getAssets().open(DB_NAME);
byte[] buffer = new byte[1024];
int ch;
while ((ch = in.read(buffer)) > 0) {
out.write(buffer, 0, ch);
}
out.flush();
out.close();
in.close();
return true;
} catch (Exception e) {
/* do nothing */
return false;
}
}
public void open() {
if (dbExists()) {
try {
File temp = new File(DB_PATH);
db = SQLiteDatabase.openDatabase(
temp.getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE
);
} catch (Exception e) {
/* do nothing */
}
} else {
if (copyDB())
open();
}
}
#Override
public synchronized void close() {
db.close();
}
public List<HashMap<String,Object>> getTableOfContent(String id) {
Cursor result = db.rawQuery("SELECT * FROM " + DB_TBL_BOOKS + " WHERE author = '" + id + "'", null);
List<HashMap<String, Object>> all_data = new ArrayList<>();
while (result.moveToNext()) {
HashMap<String,Object> temp = new HashMap<>();
temp.put("id", result.getString(0));
temp.put("title", result.getString(1));
temp.put("author", result.getString(3));
temp.put("image", result.getString(8));
if (result.getString(9).equals("1")) {
temp.put("fav_flag", R.drawable.is_favorite);
} else {
temp.put("fav_flag", R.drawable.not_favorite);
}
if (result.getString(10).equals("1")) {
temp.put("see_flag", R.drawable.see);
} else {
temp.put("see_flag", R.drawable.not_see);
}
all_data.add(temp);
}
return all_data;
}
tblOfContent.java
public class tblOfContent extends AppCompatActivity {
private ListView contentListView;
private List<HashMap<String, Object>> books_list;
private DatabaseHandler db;
public String my_key_number;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tbl_of_content);
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Bundle extras = getIntent().getExtras();
if (extras != null) {
my_key_number = extras.getString("number_of_keys");
Toast.makeText(this, my_key_number, Toast.LENGTH_LONG).show();
}
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
//actionBar.setTitle(R.string.doctors_title);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
contentListView = findViewById(R.id.tblOfContentListView);
db = new DatabaseHandler(getBaseContext());
db.open();
books_list = db.getTableOfContent(my_key_number);
String[] from = {"title", "image", "fav_flag", "see_flag"};
int[] to = {R.id.txtTitle, R.id.url, R.id.setFav, R.id.setSee};
SimpleAdapter adb = new SimpleAdapter(
getBaseContext(), books_list, R.layout.foods_row_item, from, to
);
contentListView.setAdapter(adb);
db.close();
contentListView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(getBaseContext(), book_content.class);
String my_id = books_list.get(position).get("id").toString();
i.putExtra("id", my_id);
startActivity(i);
}
}
);
}
}
Try this:
String[] from = {"title", "fav_flag", "see_flag"};
int[] to = {R.id.txtTitle, R.id.setFav, R.id.setSee};
SimpleAdapter adb = new SimpleAdapter(getBaseContext(), books_list, R.layout.foods_row_item, from, to){
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = super.getView(position, convertView, parent);
String url = (String)((HashMap<String, Object>)getItem(position)).get("image");
ImageView imageView = (ImageView)itemView.findViewById(R.id.url);
Glide.with(this)
.load(url)
.into(imageView);
return itemView;
}
};
Hope it helps!
How to retrieve random pic of gallery from android SQLite database and display it in another Activity with name and price? When I click on "profile" button my app crashes but data is added successfully.
My code is:
MainActivity class:
public class MainActivity extends AppCompatActivity {
EditText edtName, edtPrice;
Button btnChoose, btnAdd, btnList;
ImageView imageView;
Uri imageuri;
final int REQUEST_CODE_GALLERY = 999;
private static final int pick_image = 100;
public static SQLiteHelper sqLiteHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtName = (EditText) findViewById(R.id.edtName);
edtPrice = (EditText) findViewById(R.id.edtPrice);
btnChoose = (Button) findViewById(R.id.btnChoose);
btnAdd = (Button) findViewById(R.id.btnAdd);
btnList = (Button) findViewById(R.id.btnList);
imageView = (ImageView) findViewById(R.id.imageView);
sqLiteHelper = new SQLiteHelper(this, "FoodDB.sqlite", null, 1);
sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS FOOD(Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, price VARCHAR, image BLOB)");
btnChoose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery,pick_image);
}
});
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(), "Added successfully!", Toast.LENGTH_SHORT).show();
// edtName.setText("");
//edtPrice.setText("");
// imageView.setImageResource(R.mipmap.ic_launcher);
String s = "iqra"; //why we take string whrn we take only next button,is it necessary to take the string?
Intent i = new Intent(MainActivity.this, foodprofile.class);
Bundle bun = new Bundle();
bun.putString("name", s);
i.putExtras(bun);
startActivity(i);
}
catch (Exception e){
e.printStackTrace();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK && requestCode == pick_image){
imageuri = data.getData();
imageView.setImageURI(imageuri);
}
}
public static byte[] imageViewToByte(ImageView image) {
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
//bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
bitmap.compress(Bitmap.CompressFormat.JPEG, 0, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, 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(), "You don't have permission to access file location!", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
SQLitehelper class:
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 (NULL, ?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, price);
statement.bindBlob(3, image);
statement.executeInsert();
}
public void updateData(String name, String price, byte[] image, int id) {
SQLiteDatabase database = getWritableDatabase();
String sql = "UPDATE FOOD SET name = ?, price = ?, image = ? WHERE id = ?";
SQLiteStatement statement = database.compileStatement(sql);
statement.bindString(1, name);
statement.bindString(2, price);
statement.bindBlob(3, image);
statement.bindDouble(4, (double)id);
statement.execute();
database.close();
}
public void deleteData(int id) {
SQLiteDatabase database = getWritableDatabase();
String sql = "DELETE FROM FOOD WHERE id = ?";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindDouble(1, (double)id);
statement.execute();
database.close();
}
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("Select * from food ",null);
return res;
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
foodprofile
public class foodprofile extends AppCompatActivity {
SQLiteHelper sqLiteHelper;
Button profile;
TextView txtresult1,txtresult2,txtresult6;
ImageView imgvresult;
Uri imageuri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foodprofile);
txtresult1 = (TextView) findViewById(R.id.name);
txtresult2 = (TextView) findViewById(R.id.price);
imgvresult = (ImageView) findViewById(R.id.image) ;
profile = (Button) findViewById(R.id.btnprofile);
}
public void profile(View v) {
if(v.getId()==R.id.btnprofile) {
Cursor res = sqLiteHelper.getData();
StringBuffer stringbuffer = new StringBuffer();
Toast pass = Toast.makeText(foodprofile.this,"inserted successfully", Toast.LENGTH_SHORT);
pass.show();
txtresult1.setText(" " + res.getString(0) );
txtresult2.setText(" " + res.getString(1) );
imgvresult.setImageURI(imageuri);
// imgvresult.setImageResource(res.getString(2),R.mipmap.ic_launcher);
//imgvresult.setImageResource(res.getBlob(0x2));
txtresult6.setText("-------------------------" + "\n");
//txtresult.setText(stringbuffer.toString());
Toast pass1= Toast.makeText(foodprofile.this, "retrieve successfully", Toast.LENGTH_SHORT);
pass1.show();
}
}
}
foodprofile.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ffffff" >
<Button
android:id="#+id/btnprofile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="profile"
android:background="#color/colorPrimaryDark"
android:onClick="profile"/>
<ImageView
android:id="#+id/image"
android:layout_marginTop="55dp"
android:layout_width="match_parent"
android:layout_height="200dp" />
<TextView
android:id="#+id/name"
android:textColor="#000"
android:textStyle="bold"
android:textSize="30dp"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginTop="300dp"/>
<TextView
android:id="#+id/price"
android:textColor="#000"
android:textStyle="bold"
android:textSize="30dp"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginTop="350dp"/>
</RelativeLayout>
</ScrollView>
You need to :-
a) get a byte array via the getBlob() and then
b) convert the byte array to a Bitmap and then
c) set the ImageView using the Bitmap
Something along the lines of :-
public void profile(View v) {
if(v.getId()==R.id.btnprofile) {
Cursor res = sqLiteHelper.getData();
StringBuffer stringbuffer = new StringBuffer();
Toast pass = Toast.makeText(foodprofile.this,"inserted successfully", Toast.LENGTH_SHORT);
pass.show();
txtresult1.setText(" " + res.getString(0) );
txtresult2.setText(" " + res.getString(1) );
// get the Blob
byte[] my_bytearray = res.getBlob(2);
// convert byte array into a bitmap
Bitmap bmp = BitmapFactory.decodeByteArray(my_bytearray, 0, my_bytearray.length);
// apply the image to the image view
imgvresult.setImageBitmap(Bitmap.createScaledBitmap(bmp, image.getWidth(),
image.getHeight(), false)));
Toast pass1= Toast.makeText(foodprofile.this, "retrieve successfully", Toast.LENGTH_SHORT);
pass1.show();
}
}
Notes
Storing images can be problematic and inefficient. If the images are greater than about 100k it is advisable to store the images as files and to then store the path to the image in the database.
The above codes is in-principle it has not been tested and may therefore have typing errors.
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 a List for Android with a SQLite DB. While creating a new Item works without a problem, after it returns to the list activity, the Items are showed various times. Still in my DB only one new Item is inserted (as should), and when I restart the App and load the list, each Item is showed once. So here is my main activity, as I said DBHandler should be ok.
public class MainActivity extends Activity {
List<FavImages> FavImages = new ArrayList<FavImages>();
ListView favImageListView;
final Context context = this;
private SharedPreferences mPrefs;
private SharedPreferences.Editor mEditor;
//label logs
private static String logtag = "CameraApp";
//use main camera
private static int TAKE_PICTURE = 1;
private Uri imageUri;
public Uri imagePath = Uri.parse("android.resource://com.adrian/drawable/no_picture.png");
DataBaseHandler dbHandler;
int longClickedItemIndex;
ArrayAdapter<FavImages> favImagesAdapter;
private static final int EDIT = 0, DELETE = 1;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
favImageListView = (ListView) findViewById(R.id.listView);
dbHandler = new DataBaseHandler(getApplicationContext());
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
mEditor = mPrefs.edit();
//enter an Item
registerForContextMenu(favImageListView);
//maybe without long
favImageListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//position of Item
longClickedItemIndex = position;
return false;
}
});
populateList();
//Button Action
Button cameraButton = (Button)findViewById(R.id.button_camera);
cameraButton.setOnClickListener(cameraListener);
}
private OnClickListener cameraListener = new OnClickListener(){
public void onClick(View v){
takePhoto(v);
}
};
//launch native camera app
private void takePhoto(View v){
final Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//save Image and create file
// in Progress
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.text_entry, null);
final EditText input1 = (EditText) textEntryView.findViewById(R.id.pictureName);
final AlertDialog.Builder alert = new AlertDialog.Builder(this);
//create Dialog
alert
.setTitle("Bitte bennenen Sie Ihr Bild!")
.setView(textEntryView)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Log.i("AlertDialog","TextEntry 1 Entered "+input1.getText().toString());
/* User clicked OK so do some stuff */
String inputText = input1.getText().toString();
mEditor.putString("pictureName", inputText);
mEditor.commit();
File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), replaceChars(mPrefs.getString("pictureName", "picture")) + ".jpg");
//access information of file
imageUri = Uri.fromFile(photo);
//save image path information
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
//for favImages
imagePath = imageUri;
mEditor.putString("picturePath", imagePath.toString());
mEditor.commit();
//
startActivityForResult(intent, TAKE_PICTURE);
//
Log.e("Dateipfad", imagePath.toString());
FavImages favImages = new FavImages(dbHandler.getFavCount(), mPrefs.getString("pictureName", "Bild"), imagePath);
dbHandler.createFav(favImages);
FavImages.add(favImages);
//favImagesAdapter.notifyDataSetChanged();
populateList();
List<FavImages> addableFavs = dbHandler.getAllFav();
int favCount = dbHandler.getFavCount();
for(int i = 0; i < favCount; i++){
FavImages.add(addableFavs.get(i));
}
if (!addableFavs.isEmpty())
populateList();
}
});
//show Dialog
alert.show();
}
public String replaceChars (String inputText){
inputText = inputText.replace("ä","ae");
inputText = inputText.replace("ö","oe");
inputText = inputText.replace("ü","ue");
inputText = inputText.replace("ß","ss");
return inputText;
}
//deal with output
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
//user hits ok button (picture accepted)
if(resultCode == Activity.RESULT_OK){
Uri selectedImage = imageUri;
//communication between apps
getContentResolver().notifyChange(selectedImage, null);
/*get Image
ImageView imageView = (ImageView)findViewById(R.id.image_camera);
//hold Image data
ContentResolver cr = getContentResolver();
Bitmap bitmap;
//get bitmap data
try {
bitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage);
//set Image
imageView.setImageBitmap(bitmap);
//notify user of success
Toast.makeText(MainActivity.this, selectedImage.toString(), Toast.LENGTH_LONG).show();
}catch (Exception e){ //catch exceptions along the way
Log.e(logtag, e.toString());
} */
}
}
//
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo){
super.onCreateContextMenu(menu, view, menuInfo);
menu.setHeaderTitle("Favorit bearbeiten");
menu.add(Menu.NONE, DELETE, menu.NONE, "Favorit löschen");
}
public boolean onContextItemSelected (MenuItem item){
switch (item.getItemId()){
case EDIT:
//TODO: edit Favorites
break;
case DELETE:
//
dbHandler.deleteFav(FavImages.get(longClickedItemIndex));
FavImages.remove(longClickedItemIndex);
favImagesAdapter.notifyDataSetChanged();
break;
}
return super.onContextItemSelected(item);
}
private void populateList(){
//ArrayAdapter<FavImages> adapter = new favImagesListAdapter();
//favImageListView.setAdapter(adapter);
favImagesAdapter = new favImagesListAdapter();
favImageListView.setAdapter(favImagesAdapter);
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
#Override
public View getView (int position, View view, ViewGroup parent){
if (view == null)
view = getLayoutInflater().inflate(R.layout.listview_item, parent, false);
FavImages currentFav = FavImages.get(position);
TextView favName = (TextView) view.findViewById(R.id.favName);
favName.setText(currentFav.getImageName());
ImageView ivFavsImage = (ImageView) view.findViewById(R.id.favImage);
ivFavsImage.setImageURI(currentFav.getImagePath());
return view;
}
}
So to sum it up, what am I doing wrong, that my Items are loaded various times.
EDIT:
as requested here is my DBHandler class:
<!-- language: lang-java -->
public class DataBaseHandler extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "favoritesManager",
TABLE_FAVS = "favorites",
KEY_ID = "id",
KEY_IMGName = "name",
KEY_IMGPATH = "imagePath";
//standard DB method
public DataBaseHandler(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//standard DB method
#Override
public void onCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE " + TABLE_FAVS + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_IMGName + " TEXT, " + KEY_IMGPATH + " TEXT)");
}
//standard DB method
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABL IF EXISTS" + TABLE_FAVS);
onCreate(db);
}
public void createFav(FavImages favImages){
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_IMGName, favImages.getImageName());
values.put(KEY_IMGPATH, favImages.getImagePath().toString());
db.insert(TABLE_FAVS, null, values);
db.close();
}
public void deleteFav(FavImages favImages){
SQLiteDatabase db = getWritableDatabase();
db.delete(TABLE_FAVS, KEY_ID + "=?", new String[]{String.valueOf(favImages.getId())});
db.close();
}
public int getFavCount(){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_FAVS, null);
int count = cursor.getCount();
cursor.close();
db.close();
return count;
}
public List<FavImages> getAllFav(){
List<FavImages> favImages = new ArrayList<FavImages>();
SQLiteDatabase db = getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_FAVS, null);
if (cursor.moveToFirst()){
do {
favImages.add(new FavImages(Integer.parseInt(cursor.getString(0)), cursor.getString(1), Uri.parse(cursor.getString(2))));
}while (cursor.moveToNext());
}
cursor.close();
db.close();
return favImages;
}
Hi you need to use the view holder pattern see link provided below:
http://ricston.com/blog/optimising-listview-viewholder-pattern/
Ok after a fresh look on the code I found my mistake myself, I am adding multiple times the same Item to the List. Stupid mistake I know but now it works fine.
Still, thanks for your Help.
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;
}