Dears
How I can Android Save Image And Get Image From Sqlite Database I'm Using Android Studio ?
Might be too late. but useful for future readers..
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.util.HashMap;
/**
* Created by Noorul on 23-05-2016.
*/
#SuppressWarnings("ALL")
public class DBSplash extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "SplashDB.db";
public static final String SPLASH_TABLE_NAME = "splash_db";
private HashMap hp;
public DBSplash(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
"create table " + SPLASH_TABLE_NAME + "( name TEXT, image BLOB)"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
public boolean insertImage(String name, Bitmap img) {
Bitmap storedBitmap = null;
String sql = "INSERT INTO " + SPLASH_TABLE_NAME + " (name,image) VALUES(?,?)";
SQLiteDatabase db = this.getWritableDatabase();
SQLiteStatement insertStmt = db.compileStatement(sql);
byte[] imgByte = getBitmapAsByteArray(img);
try {
storedBitmap = getImage(name);
} catch (Exception e) {
AppLog.exception(e);
}
if (storedBitmap == null) {
insertStmt.bindString(1, name);
insertStmt.bindBlob(2, imgByte);
insertStmt.executeInsert();
db.close();
}
return true;
}
public int numberOfRows() {
SQLiteDatabase db = this.getReadableDatabase();
int numRows = (int) DatabaseUtils.queryNumEntries(db, SPLASH_TABLE_NAME);
return numRows;
}
public Bitmap getImage(String name) {
String qu = "SELECT * FROM " + SPLASH_TABLE_NAME;
Cursor cur = null;
SQLiteDatabase db = this.getReadableDatabase();
try {
cur = db.rawQuery(qu, new String[]{});
} catch (Exception e) {
AppLog.exception(e);
}
if (cur != null) {
if (cur.moveToFirst()) {
int index = cur.getColumnIndexOrThrow("image");
byte[] imgByte = cur.getBlob(index);
cur.close();
return BitmapFactory.decodeByteArray(imgByte, 0, imgByte.length);
}
if (cur != null && !cur.isClosed()) {
cur.close();
}
}
return null;
}
public byte[] getBitmapAsByteArray(Bitmap bitmap) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 0, outputStream);
return outputStream.toByteArray();
}
}
Use this code. But storing images in databases is not not best practices.change the image size if you need unblurred image. IMages are blob type with high memory . mobile is smaller device . so storing many images in sqlite db means, it will be ugly. so use #thuongle method
You can check this tutorial for implementing Sqlite in Android.
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
Instead working with Contact for example, you can implement this way
public class Image{
String imagePath; //it is your absolute image file path
}
And your DatabaseHandler can be implemented like below
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "imagedb";
// Contacts table name
private static final String TABLE_IMAGE = "images";
// Contacts Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_IMAGE_PATH = "name";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String sqlQuery = "CREATE TABLE " + TABLE_IMAGE + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_IMAGE_PATH + " TEXT)";
db.execSQL(sqlQuery);
}
// Upgrading database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_IMAGE);
// Create tables again
onCreate(db);
}
// Adding new image
public void addImage(Image image) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_IMAGE_PATH, image.imagePath); // Image path
// Inserting Row
db.insert(TABLE_IMAGE, null, values);
db.close(); // Closing database connection
}
// Getting single image
public Image getImage(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_IMAGE, new String[] { KEY_ID,
KEY_IMAGE_PATH}, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Image image = new Image(Integer.parseInt(cursor.getString(0)),
cursor.getString(1));
// return image
return image;
}
}
Related
I'm developping and android quizz app and i have two problems.
First i cannot update the questions and second i want to store images in the database with the questions.This my database code
Is there someone who can help me?
Thanks
package com.example.toureamidou.piste;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* Created by TOURE Amidou on 24/02/2016.
*/
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "Question";
private static final String TABLE_QUEST = "quest";
private static final String KEY_ID = "id";
private static final String KEY_QUES = "question";
private static final String KEY_ANSWER = "answer";
private static final String KEY_OPTA= "opta";
private static final String KEY_OPTB= "optb";
private static final String KEY_OPTC= "optc";
private SQLiteDatabase dbase;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME,null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
dbase=db;
String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_QUEST + " ( "
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_QUES
+ " TEXT, " + KEY_ANSWER+ " TEXT, "+KEY_OPTA +" TEXT, "
+KEY_OPTB +" TEXT, "+KEY_OPTC+" TEXT)";
db.execSQL(sql);
addQuestions();
}
private void addQuestions() {
Questions q1=new Questions("FFFFF","Tata", "Titi", "Toto", "Tata");
this.addQuestion(q1);
Questions q2=new Questions("Quel est le plus grand pays au monde", "Suisse", "Italie", "Chine", "Chine");
this.addQuestion(q2);
Questions q3=new Questions("Comment s'appele le président francais","Obama", "Hollande","Gorbatchev", "Hollande" );
this.addQuestion(q3);
Questions q4=new Questions("zzzzzzzzzzzzzzzzzzzz", "ali", "dede", "home","dede");
this.addQuestion(q4);
Questions q5=new Questions("Quel est l'homme le plus riche au monde","Gates","Trump","Carlos Slim","Trump");
this.addQuestion(q5);
}
private void addQuestion(Questions quest) {
Log.d("addQuestions", quest.toString());
ContentValues values = new ContentValues();
values.put(KEY_QUES, quest.getQUESTION());
values.put(KEY_ANSWER, quest.getANSWER());
values.put(KEY_OPTA, quest.getOPTA());
values.put(KEY_OPTB, quest.getOPTB());
values.put(KEY_OPTC, quest.getOPTC());
dbase.insert(TABLE_QUEST, null, values);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_QUEST);
onCreate(db);
}
public List<Questions> getAllQuestions() {
List<Questions> quesList = new ArrayList<Questions>();
String selectQuery = "SELECT * FROM " + TABLE_QUEST;
dbase=this.getReadableDatabase();
Cursor cursor = dbase.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
Questions quest = new Questions();
quest.setID(cursor.getInt(0));
quest.setQUESTION(cursor.getString(1));
quest.setANSWER(cursor.getString(2));
quest.setOPTA(cursor.getString(3));
quest.setOPTB(cursor.getString(4));
quest.setOPTC(cursor.getString(5));
quesList.add(quest);
} while (cursor.moveToNext());
}
return quesList;
}
public int updateQuestions (Questions questions){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("questions",questions.getQUESTION());
contentValues.put("answer",questions.getANSWER());
contentValues.put("opta",questions.getOPTA());
contentValues.put("optb",questions.getOPTB());
contentValues.put("optc",questions.getOPTC());
int i = db.update(TABLE_QUEST, contentValues, KEY_ID + " = ?", new String[]{String.valueOf(questions.getID())});
db.close();
return i;
}
}
Another way You can also image load with asset folder
//load image
try {
// get input stream
InputStream ims = getAssets().open("avatar.jpg");
// load image as Drawable
Drawable d = Drawable.createFromStream(ims, null);
// set image to ImageView
mImage.setImageDrawable(d);
}
catch(IOException ex)
{
ex.printStackTrace();
}
in order for database records to "stick" you need to be in a Transaction.
db.getWritableDatabase();
db.beginTransaction();
...INSERT, UPDATE, DELETE
if (ok) {
db.setTransactionSuccessful();
}
db.endTransaction();
db.close();
images could be stored in a BLOB column.
Use this to get you image as String and save it
public String getStringImage() {
if (bitmap != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
} else {
return null;
}
}
change image into byte{}
Bitmap b=BitmapFactory.decodeResource(getResources(),R.drawable.androidpics);
ByteArrayOutputStream bos=new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 100, bos);
img=bos.toByteArray();
insert image into database
................................................
db=h.getWritableDatabase();
btninsert.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ContentValues cv=new ContentValues();
cv.put("image", img);
db.insert("tableimage", null, cv);
System.out.println("image insert successfully...............................");
}
}
);
Heyhey :)
I looked at several Questions to the same topic, but I found no solution to my problem.
A NullPointerException at this.getReadableDatabase(); appears...
Here's my Code:
public class DatabaseHandler extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "TODO_APP";
/*--------------------------- TABLE ITEMS START ---------------------------*/
private static final String TABLE_ITEMS = "items";
private static String KEY_ID_ITEMS = "id_items";
private static final String KEY_CATEGORY_ITEMS = "category";
private static final String KEY_DATETIME_ITEMS = "datetime";
private static String KEY_NAME_ITEMS = "name";
private static final String KEY_DESCRIPTION_ITEMS = "description";
private static final String KEY_ALARM_ITEMS = "alarm";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// create table ITEMS
String CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS + "("
+ KEY_ID_ITEMS + " INTEGER PRIMARY KEY," + KEY_CATEGORY_ITEMS
+ " INTEGER," + KEY_DATETIME_ITEMS
+ " TIMESTAMP DEFAULT CURRENT_TIMESTAMP," + KEY_NAME_ITEMS
+ " TEXT," + KEY_DESCRIPTION_ITEMS + " TEXT," + KEY_ALARM_ITEMS
+ " INTEGER" + ");";
db.execSQL(CREATE_ITEMS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEMS);
// Create tables again
this.onCreate(db);
}
public void addItem(DB_Item item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_CATEGORY_ITEMS, item.getCategory());
values.put(KEY_NAME_ITEMS, item.getName());
values.put(KEY_DESCRIPTION_ITEMS, item.getDescription());
values.put(KEY_ALARM_ITEMS, item.getAlarm());
// Inserting Row
db.insert(TABLE_ITEMS, null, values);
db.close(); // Closing database connection
}
public DB_Item getItem(String name) {
//!!!!! Here is one problem !!!!!
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_ITEMS, new String[] { KEY_ID_ITEMS,
KEY_CATEGORY_ITEMS, KEY_DATETIME_ITEMS, KEY_NAME_ITEMS,
KEY_DESCRIPTION_ITEMS, KEY_ALARM_ITEMS },
KEY_NAME_ITEMS = " = ?", new String[] { String.valueOf(name) },
null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
// DB_Item (int category, String name, String description, int
// alarm)
DB_Item item = new DB_Item(cursor.getInt(1), cursor.getString(3),
cursor.getString(4), cursor.getInt(5));
return item;
}
public List<DB_Item> getAllItems() {
List<DB_Item> itemList = new ArrayList<DB_Item>();
// SELECT ALL
String selectQuery = "SELECT * FROM " + TABLE_ITEMS;
//!!!!!!!!!! here is the other Problem
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor = database.rawQuery(selectQuery, null);
// go through all rows and then adding to list
if (cursor.moveToFirst()) {
do {
DB_Item item = new DB_Item();
item.setCategory(Integer.parseInt(cursor.getString(0)));
// TODO
// adding to list
itemList.add(item);
} while (cursor.moveToNext());
}
return itemList;
}
[and so on, didn't copy the whole code]
Hope you can help me...
The error appears definitely at SQLiteDatabase db = this.getReadableDatabase();
Output:
09-03 08:34:17.863: E/AndroidRuntime(7074): java.lang.RuntimeException: Unable to start activity ComponentInfo{todo.todo_list/todo.view.StartApp}: java.lang.NullPointerException
09-03 08:34:17.863: E/AndroidRuntime(7074): at todo.database.DatabaseHandler.getAllItems(DatabaseHandler.java:144)
09-03 08:34:17.863: E/AndroidRuntime(7074): at todo.helper.SortItems.sortItemsCategory(SortItems.java:16)
09-03 08:34:17.863: E/AndroidRuntime(7074): at todo.view.StartApp.onCreate(StartApp.java:36)
chnage you class to something like this:
package com.mhp.example;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
/*--------------------------- TABLE ITEMS START ---------------------------*/
private static final String TABLE_ITEMS = "items";
private static String KEY_ID_ITEMS = "id_items";
private static final String KEY_CATEGORY_ITEMS = "category";
private static final String KEY_DATETIME_ITEMS = "datetime";
private static String KEY_NAME_ITEMS = "name";
private static final String KEY_DESCRIPTION_ITEMS = "description";
private static final String KEY_ALARM_ITEMS = "alarm";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "dbname";
private static final int DATABASE_VERSION = 1;
tring CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS + "("
+ KEY_ID_ITEMS + " INTEGER PRIMARY KEY," + KEY_CATEGORY_ITEMS
+ " INTEGER," + KEY_DATETIME_ITEMS
+ " TIMESTAMP DEFAULT CURRENT_TIMESTAMP," + KEY_NAME_ITEMS
+ " TEXT," + KEY_DESCRIPTION_ITEMS + " TEXT," + KEY_ALARM_ITEMS
+ " INTEGER" + ");";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(CREATE_ITEMS_TABLE);
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
public void addItem(DB_Item item) {
ContentValues values = new ContentValues();
values.put(KEY_CATEGORY_ITEMS, item.getCategory());
values.put(KEY_NAME_ITEMS, item.getName());
values.put(KEY_DESCRIPTION_ITEMS, item.getDescription());
values.put(KEY_ALARM_ITEMS, item.getAlarm());
// Inserting Row
db.insert(TABLE_ITEMS, null, values);
}
public DB_Item getItem(String name) {
Cursor cursor = db.query(TABLE_ITEMS, new String[] { KEY_ID_ITEMS,
KEY_CATEGORY_ITEMS, KEY_DATETIME_ITEMS, KEY_NAME_ITEMS,
KEY_DESCRIPTION_ITEMS, KEY_ALARM_ITEMS },
KEY_NAME_ITEMS = " = ?", new String[] { String.valueOf(name) },
null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
// DB_Item (int category, String name, String description, int
// alarm)
DB_Item item = new DB_Item(cursor.getInt(1), cursor.getString(3),
cursor.getString(4), cursor.getInt(5));
return item;
}
public List<DB_Item> getAllItems() {
List<DB_Item> itemList = new ArrayList<DB_Item>();
// SELECT ALL
String selectQuery = "SELECT * FROM " + TABLE_ITEMS;
Cursor cursor = db.rawQuery(selectQuery, null);
// go through all rows and then adding to list
if (cursor.moveToFirst()) {
do {
DB_Item item = new DB_Item();
item.setCategory(Integer.parseInt(cursor.getString(0)));
// TODO
// adding to list
itemList.add(item);
} while (cursor.moveToNext());
}
return itemList;
}
}
NOTE: when you create object from DBAdapter,you should open() db and after your work close() it.
DBAdapter db = new DBAdapter(contex);
db.open();
//do you work
db.close();
Just use getReadableDatabase() without this.
I have the following code,but i'm having some trouble with duplicates.How can i modify the code so that it won't allow duplicates in the database ? I'm using it to power an AutoCompleteTextView so the duplicates aren't helping.
Thanks a lot !
package com.giantflyingsaucer;
import android.database.*;
import android.database.sqlite.*;
import android.content.ContentValues;
import android.content.Context;
import android.util.Log;
public class SQLiteCountryAssistant extends SQLiteOpenHelper
{
private static final String DB_NAME = "usingsqlite.db";
private static final int DB_VERSION_NUMBER = 1;
private static final String DB_TABLE_NAME = "countries";
private static final String DB_COLUMN_1_NAME = "country_name";
private static final String DB_CREATE_SCRIPT = "create table " + DB_TABLE_NAME +
" (_id integer primary key autoincrement, country_name text not null);)";
private SQLiteDatabase sqliteDBInstance = null;
public SQLiteCountryAssistant(Context context)
{
super(context, DB_NAME, null, DB_VERSION_NUMBER);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO: Implement onUpgrade
}
#Override
public void onCreate(SQLiteDatabase sqliteDBInstance)
{
Log.i("onCreate", "Creating the database...");
sqliteDBInstance.execSQL(DB_CREATE_SCRIPT);
}
public void openDB() throws SQLException
{
Log.i("openDB", "Checking sqliteDBInstance...");
if(this.sqliteDBInstance == null)
{
Log.i("openDB", "Creating sqliteDBInstance...");
this.sqliteDBInstance = this.getWritableDatabase();
}
}
public void closeDB()
{
if(this.sqliteDBInstance != null)
{
if(this.sqliteDBInstance.isOpen())
this.sqliteDBInstance.close();
}
}
public long insertCountry(String countryName)
{
ContentValues contentValues = new ContentValues();
contentValues.put(DB_COLUMN_1_NAME, countryName);
Log.i(this.toString() + " - insertCountry", "Inserting: " + countryName);
return this.sqliteDBInstance.insert(DB_TABLE_NAME, null, contentValues);
}
public boolean removeCountry(String countryName)
{
int result = this.sqliteDBInstance.delete(DB_TABLE_NAME, "country_name='" + countryName + "'", null);
if(result > 0)
return true;
else
return false;
}
public long updateCountry(String oldCountryName, String newCountryName)
{
ContentValues contentValues = new ContentValues();
contentValues.put(DB_COLUMN_1_NAME, newCountryName);
return this.sqliteDBInstance.update(DB_TABLE_NAME, contentValues, "country_name='" + oldCountryName + "'", null);
}
public String[] getAllCountries()
{
Cursor cursor = this.sqliteDBInstance.query(DB_TABLE_NAME, new String[] {DB_COLUMN_1_NAME}, null, null, null, null, null);
if(cursor.getCount() >0)
{
String[] str = new String[cursor.getCount()];
int i = 0;
while (cursor.moveToNext())
{
str[i] = cursor.getString(cursor.getColumnIndex(DB_COLUMN_1_NAME));
i++;
}
return str;
}
else
{
return new String[] {};
}
}
}
One option would be to call removeCountry from your insertCountry method before actually doing the insert. Alternatively you could modify your database structure to be country_name text not null unique. SQLite will then throw an exception if you fail the constraint which you'll need to catch and handle appropriately.
Finally, another option would be to attempt a query of the database for the string in question, if it exists, don't insert, if it doesn't then insert it.
You could use a function to see if the data already exists in the database.
public boolean checkIfDataExists(String country) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.query(TABLE_NAME, columns, null, null, null, null, null);
int iCountry = c.getColumnIndex(KEY_COUNTRY);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
if (country.equals(c.getString(iCountry))) {
db.close();
return true;
}
}
db.close();
return false;
}
Call this function in an if statement and execute the insert instruction if the condition is not true.
I tried this and it works great,at least so far.
private static final String DB_CREATE_SCRIPT = "create table " + DB_TABLE_NAME +
" (_id integer primary key autoincrement, country_name text UNIQUE);)";
Added UNIQUE instead of not null
I'm entirely new to Android Java, especially database linkage. So far I've got this, which all seems to work, I just now need to get the database values from the database to an array.
package com.example.sleepertrain5;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseHelper extends SQLiteOpenHelper{
private static String DB_PATH = "/sleepertrain5/assets";
private static String DB_NAME="info2.sqlite";
private SQLiteDatabase myDatabase;
private final Context myContext;
public DataBaseHelper(Context context){
super(context, DB_NAME, null, 1);
this.myContext=context;
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//nothing needs done
}else{
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e){
throw new Error("Error copying database");
}
}
}
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//no databases they don't exist
}
if (checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
private void copyDataBase() throws IOException{
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH +DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length=myInput.read(buffer))>0){
myOutput.write(buffer,0,length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException{
//Open database
String myPath = DB_PATH + DB_NAME;
myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
public synchronized void close(){
if(myDatabase != null)
myDatabase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
How would I go about reading from this into an array? I'm struggling to make sense of this at the moment, so any help would be fantastic.
EDIT: The plan is to read the data, which is coordinates and names, into the array, which I can then use later to draw markers onto a GoogleMap. GoogleMap is all set up and I think I know what I'm doing from there, but this is the part I fall down on. The array would have to be multidimensional.
Ok, so the easiest way to work with SQLite in my opinion is using this three-class approach. I've read through a few tutorials and neither really did the trick for me....
So, here we go.
Table definition
package com.test.sqlite;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class ContactTable
{
//key identifiers / column names
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "name";
public static final String KEY_URI = "uri";
public static final String TABLE_NAME = "contacts";
//useful stuff
public static final String[] TABLE_COLUMNS = { KEY_ROWID, KEY_NAME, KEY_URI }; //public makes it more useful
private static final String[] TABLE_COLTYPES = { "integer primary key autoincrement", "text not null", "text not null" };
// Database creation SQL statement in lazy-pretty version
private static final String TABLE_CREATE = "create table " + TABLE_NAME + "("
+ TABLE_COLUMNS[0] + " " + TABLE_COLTYPES[0] + ","
+ TABLE_COLUMNS[1] + " " + TABLE_COLTYPES[1] + ","
+ TABLE_COLUMNS[2] + " " + TABLE_COLTYPES[2] + ");";
private static final String LOGTAG = "ContactTable";
public static void onCreate(SQLiteDatabase database)
{
database.execSQL(TABLE_CREATE);
}
public static void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion)
{
Log.w(LOGTAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(database);
}
public static void scratch(SQLiteDatabase database)
{
database.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
database.execSQL(TABLE_CREATE);
}
}
Now that we have set that up, we need Database Helper class, to ease the use of it.
The helper class
package com.test.sqlite;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
public class ContactDBHelper extends SQLiteOpenHelper
{
// 'main' package name
private static final String PACKAGE_NAME = "com.test.demo";
private static final String DATABASE_PATH = "/data/data/" + PACKAGE_NAME + "/databases/";
private static final String DATABASE_NAME = "contactdata";
private static final int DATABASE_VERSION = 1;
private Context myContext;
public ContactDBHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
myContext = context;
}
// Method is called during creation of the database
#Override
public void onCreate(SQLiteDatabase database)
{
ContactTable.onCreate(database);
}
// Method is called during an upgrade of the database,
// e.g. if you increase the database version
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion)
{
ContactTable.onUpgrade(database, oldVersion, newVersion);
}
public void scratch(SQLiteDatabase database)
{
ContactTable.scratch(database);
}
/**
* Creates a empty database on the system and rewrites it with your own
* database.
* */
public void createDataBase() throws IOException
{
boolean dbExist = checkDataBase();
if (dbExist)
{
// do nothing - database already exist
} else
{
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
File dirFile = new File(DATABASE_PATH);
if (!dirFile.exists())
{
dirFile.mkdir();
}
this.getReadableDatabase();
try
{
copyDataBase();
} catch (IOException e)
{
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each
* time you open the application.
*
* #return true if it exists, false if it doesn't
*/
private boolean checkDataBase()
{
SQLiteDatabase checkDB = null;
try
{
String myPath = DATABASE_PATH + DATABASE_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e)
{
// database does't exist yet.
}
if (checkDB != null) checkDB.close();
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created
* empty database in the system folder, from where it can be accessed and
* handled. This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException
{
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DATABASE_NAME);
// Path to the just created empty db
String outFileName = DATABASE_PATH + DATABASE_NAME;
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
/*
public void openDataBase() throws SQLException
{
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
*/
}
And finally, the adapter, which totally does what you want.
DatabaseAdapter
package com.test.sqlite;
import java.util.ArrayList;
import com.test.demo.Contact;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import static com.test.sqlite.ContactTable.*; //contains database fields
public class ContactDBAdapter
{
private Context context;
private SQLiteDatabase db;
private ContactDBHelper dbHelper;
public ContactDBAdapter(Context context)
{
this.context = context;
}
public synchronized ContactDBAdapter open() throws SQLException
{
dbHelper = new ContactDBHelper(context);
db = dbHelper.getWritableDatabase();
return this;
}
public synchronized void close()
{
dbHelper.close();
}
/**
* Create a new Contact entry. If the entry is successfully created return the new
* rowId for that note, otherwise return a -1 to indicate failure.
*/
public long createRow(Contact contact)
{
ContentValues values = createContentValue(contact);
return db.insert(TABLE_NAME, null, values);
}
/**
* Update a row / entry
*/
public boolean updateRow(long rowIndex, Contact contact)
{
ContentValues values = createContentValue(contact);
return db.update(TABLE_NAME, values, KEY_ROWID + "=" + rowIndex, null) > 0;
}
/**
* Deletes a row
*/
public boolean deleteRow(long rowIndex)
{
return db.delete(TABLE_NAME, KEY_ROWID + "=" + rowIndex, null) > 0;
}
public void deleteAllRows()
{
for(int i = 0; i < fetchAllEntries().getCount(); i++)
deleteRow(i);
}
/**
* Return a Cursor over the list of all Contacts in the database
*
* #return Cursor over all contacts
*/
public Cursor fetchAllEntries()
{
return db.query(TABLE_NAME, TABLE_COLUMNS, null, null, null, null, null);
}
/**
* Return a Cursor positioned at the defined Contact
*/
public Cursor fetchEntry(long rowIndex) throws SQLException
{
Cursor mCursor = db.query(true, TABLE_NAME, TABLE_COLUMNS, KEY_ROWID + "=" + rowIndex, null, null, null, null, null);
if (mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Fetch all entries and rebuild them as Contact objects in an ArrayList.
* If no results are found, an empty list is returned.
*
* #return ArrayList of Contacts
*/
public ArrayList<Contact> fetchAllContacts()
{
ArrayList<Contact> res = new ArrayList<Contact>();
Cursor resultSet = fetchAllEntries();
if (resultSet.moveToFirst() != false)
for(int i = 0; i < resultSet.getCount(); i++)
{
String name = resultSet.getString(resultSet.getColumnIndex(KEY_NAME));
String URI = resultSet.getString(resultSet.getColumnIndex(KEY_URI));
Contact c = new Contact(name, URI);
res.add(c);
if(resultSet.moveToNext() == false)
break;
}
resultSet.close();
return res;
}
public synchronized void reflectWith(ArrayList<Contact> contacts)
{
// deleteAllRows();
dbHelper.scratch(db);
contacts.trimToSize();
//empty contact
Contact empty = new Contact();
empty.empty();
for(Contact c : contacts)
{
if(!c.getName().equals(empty.getName()))
createRow(c); //if not empty, add it
}
}
private ContentValues createContentValue(Contact contact)
{
ContentValues values = new ContentValues();
values.put(KEY_NAME, contact.getName());
values.put(KEY_URI, contact.getURI());
return values;
}
}
this is how it's used:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
dbAdapter = new ContactDBAdapter(getApplicationContext());
dbAdapter.open();
setContentView(R.layout.main);
// list stuff
contacts = new ArrayList<Contact>();
contacts = dbAdapter.fetchAllContacts();
//empty placeholders
if (contacts.size() < 5) for (int i = 0; i < 5 - contacts.size(); i++)
{
Contact c = new Contact();
c.empty();
contacts.add(c);
}
// contacts.addAll(dbAdapter.fetchAllContacts());
...
}
If you have questions, do ask.
Android uses SQLite database and SQLite query syntax for database accessing.
For querying the database directly through the SQLiteDatabase db variable you can do:
String table = CONTACT_TABLE;
String columns = {CONTACT_COLUMN_NAME};
String selection = CONTACT_COLUMN_NAME + "=" + MY_NAME;
String[] selectionArgs = {"wangyif2"};
Cursor c = db.query(table, columns, selection, selectionArgs, null, null, null, null);
This will return you a Cursor object, which you can understand as an iterator that contains all the result matching your query. You can then step through the cursor like you would with any array that is converted to an iterator.
c.moveToFirst();
while (!c.isAfterLast())
{
arr[i] = cur.getString(0);
i++;
c.moveToNext();
}
I am attempting to list all the tables I have in my database in a list view by creating a string array of the table names then passing them to a listView, I have a button which calls the activity which creates the listview. the activity calls getDbNames from my database class. I get this error in LogCat in eclipse:
Tag - CursorWindow
Text - Bad request for field slot 1,-1. numRows = 3, numColumns = 1
I'll include my whole database class to see if you can help.
package the.paddox.pool;
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class Database {
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "newplayersname";
public static final String KEY_PERCENTAGE = "percentage";
private static final String DATABASE_NAME = "paddoxa";
private static final String DATABASE_TABLE = "players";
private static final int DATABASE_VERSION = 1;
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
public static class DbHelper extends SQLiteOpenHelper{
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_NAME + " TEXT NOT NULL);"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public Database(Context c){
ourContext = c;
}
public Database open() throws SQLException{
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close(){
ourHelper.close();
}
public long createEntry(String name) {
// TODO Auto-generated method stub
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}
public String[] getData() {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_NAME};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result ="";
String[] mString = {""};
ArrayList<String> playersData = new ArrayList<String>();
int iName = c.getColumnIndex(KEY_NAME);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = c.getString(iName);
playersData.add(result);
}
mString = (String[]) playersData.toArray(new String[playersData.size()]);
return mString;
}
public String[] getDBNames() {
String[] result = null;
Cursor c = ourDatabase.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
c.moveToFirst();
result = new String[c.getCount()];
int i = 0;
while (c.moveToNext()) {
result[i] = c.getString(c.getColumnIndex(DATABASE_TABLE));
i++;
}
return result;
}
}
Any help would be greatly appreciated.
I think,you are getting this error because where you try to get iName,you haven't call c.moveToFirst(); before that statement!
Instead you can use it like:
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = c.getString(c.getColumnIndex(KEY_NAME));
playersData.add(result);
}
please check your Query "SELECT name FROM sqlite_master WHERE type='table'" in getDBNames() as it list rows for column for name
your c.getColumnIndex(DATABASE_TABLE) // DATABASE_TABLE = "players" in your code. will actually not work and return as -1.
For details check here.
Hope this will help you to work further.