Android-Not able to write to database - android

I am having issue with android app connectivity to SQLite database. I have an instance of SQLite database in Assets folder. 'Select' operation returns the data that is manually inserted into database.But, Write operations (Insert,Update,Delete) are failing. I was using 'this.getReadableDatabase()' and replaced with 'this.getWritableDatabase', Similarly,
SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY) was replaced with SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE), but still of no use. I am testing on Samsung Galaxy S i-90003 with 2.3.6 version. Some one please help me
db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// values.put(KEY_ID,contact.getId());//Contact Id
values.put(KEY_NAME, contact.getName()); // Contact Name
values.put(KEY_IMAGE, contact.getImage()); // Contact Phone
// Inserting Row
try {
if(isTableExists(TABLE_IMAGES,true)) {
db.insert(TABLE_IMAGES, null, values);
}
}catch (Exception e) {
System.out.println("Error inserting:"+e.getMessage());
}
db.close(); // Closing database connection
public boolean isTableExists(String tableName, boolean openDb) {
if(openDb) {
if(db == null || !db.isOpen()) {
db = getWritableDatabase();
}
if(!db.isReadOnly()) {
db.close();
db = getWritableDatabase();
}
}
Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'", null);
if(cursor!=null) {
if(cursor.getCount()>0) {
cursor.close();
return true;
}
cursor.close();
}
return false;
}

The problem seems about write permission on the database.
Android give you this 2 method to manage the creation and upgrade of a new database
public class MyDBHandler extends SQLiteOpenHelper {
#Override
public void onCreate(SQLiteDatabase arg0) {
//add here the sql code to create the database
}
#Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// everytime you need to change the database place your sql code here
}
}
You should follow this tutorial to understand how to correct it
http://www.techotopia.com/index.php/An_Android_SQLite_Database_Tutorial

Related

Fetch data from Sqlite database

I am creating app in which i register user and store user's information in database,so i have created database and storing value in databse but i don't know how to fetch data from database and show in textview?Using below query to fetch data but it has error.What is correct way?
public void insertEntry(String fname, String lname, String gen,String weight)
{
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("firstname", fname);
values.put("lastname", lname);
values.put("gender", gen);
values.put("weight",weight);
}
public Cursor fetchData()
{
SQLiteDatabase mDB = dbHelper.getWritableDatabase();
return mDB.rawQuery("SELECT * FROM Register WHERE firstname=? lastname =?" , null);
}
Using this to set fetched value on textview in different activity
Cursor name = sqliteDataBase.fetchData();
tv_name.setText((CharSequence) name);
Try this,
try {
SQLiteDatabase mDB = dbHelper.getReadableDatabase();
String selectQuery = "SELECT * FROM Register WHERE firstname= "+first+" lastname =" + last + ";";
cursor = db.rawQuery(selectQuery, null);
if (cursor != null && cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
String firstName = cursor.getString(cursor.getColumnIndex("firstname")));
}
}
} catch(Exception e) {
e.printSTackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
public String fecthResults()
{
String name = null;
SQLiteDatabase sqLiteDatabase = getReadableDatabase();
Cursor cursor = sqLiteDatabase.query(TABLE_NAME, null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
name = cursor.getString(cursor.getColumnIndex("firstname")
} while (cursor.moveToNext());
cursor.close();
}
sqLiteDatabase.close();
return name;
Get the name and then set it directly to a texView
A Cursor is an interface that provides random read-write access to the result set returned by the query. It contains multiple rows of data and this data can be easily processed by help of For loop.
Lets take an example to understand the process. Suppose, you need to access data from a column name "col_1" and show the data in TextView. The For loop for the process will be as follows.
for (cursor.moveToNext()) {
textView.setText(cursor.getString(cursor.getColumnIndex("col_1")));
}
Now, if we need only one value (from only one record or tuple) then, we can opt out the For loop and change the code as shown below.
if (cursor.moveToFirst()) {
textView.setText(cursor.getString(cursor.getColumnIndex("col_1")));
}
Always remember to close the cursor after using it.
To close the cursor, use the following line of code.
cursor.close();
For more information, please visit the following links:
https://developer.android.com/reference/android/database/Cursor.html
https://developer.android.com/training/basics/data-storage/databases.html#ReadDbRow

DatabaseLocked exception even after closing with db.close() and db.setTransactionSuccessful()

The application am working on will initially have one database with a table, say tbl_usr which will have only one record. Basically we are trying to keep one user per device. When the user logs in from the device with an auth code, his details will be fetched from server and stored in database. Next time if he tries to enter different auth code, which is valid but is not in table then he will not be allowed to proceed. Below is a common DBHelper class.
But whatever approach am trying, I am getting databaselocked exception, when tried for the 2nd time login. I've referred various links where in it was suggested to use different instance of database within method, but still it comes with error. Below is my Helper class
public class DBaseHelper extends SQLiteOpenHelper {
private static String CREATE_TABLE;
private static final String DATABASE_NAME="IPDB";
private static String UserMessage="";
private int tableType=0;
private ContentValues cValues;
private Cursor cursor;
public enum TableTypes{
Table1
};
public DBaseHelper(Context context){
super(context,context.getExternalFilesDir(null).getAbsolutePath()+"/"+DATABASE_NAME,null,1);
}
#Override
public void onCreate(SQLiteDatabase db){
TableTypes tableTypes=TableTypes.values()[tableType];
switch (tableTypes){
case Table1:
CREATE_TABLE="CREATE TABLE IF NOT EXISTS tbl_usr....";
break;
default:
break;
}
db.execSQL(CREATE_TABLE);
db.close();
System.out
.println("onCreate Method Done.");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
/*db.execSQL("DROP TABLE IF EXISTS "+LOGIN_TABLE);*/
onCreate(db);
}
/*this is the method which gets called from other class Like*/
/*helper.insertRecord(tableParams);*/
public HashMap<String,String> insertRecord(HashMap<String,String> dbaseParams){
HashMap<String,String> response=new HashMap<String,String>();
tableType=Integer.parseInt(dbaseParams.get("tableType"));
cValues = new ContentValues();
String TableName="";
TableTypes tableTypes=TableTypes.values()[tableType];
switch (tableTypes){
case Table1:
String AuthCode=dbParams.get("AuthCode");
/*if user exists then check if its the same user*/
if( CheckUserRecordExists(AuthCode) && empty(UserMessage) ){
response.put("isSuccess","true");
return response;
}
else {
if (!empty(UserMessage)) {
response.put("isSuccess", "false");
response.put("message",UserMessage);
return response;
}
/*add new user
Fill cValues declared above*/
TableName = "Table1";
}
break;
default:
break;
}
SQLiteDatabase dataBase = getWritableDatabase();
/*insert data into database*/
try {
dataBase.beginTransaction();
long rowID = dataBase.insertOrThrow(TableName, null, cValues);
dataBase.setTransactionSuccessful();
}
catch(Exception ex){
ex.printStackTrace();
}
finally {
dataBase.close();
}
response.put("isSuccess", "true");
return response;
}
private boolean CheckUserRecordExists(String authCode){
UserMessage="";
SQLiteDatabase dataBase=getReadableDatabase();
/*Exception here when comes for 2nd time after new installation*/
cursor = dataBase.query("Table1", new String[]{"COUNT(*)"}, null, null, null, null, null);
cursor.moveToFirst();
int iCount=cursor.getInt(0);
/*check if any record exist*/
if(iCount>0){
dataBase.close();
if(!cursor.isClosed()) cursor.close();
/*check if the code entered matches with the record existing*/
if(!CheckIsDataAlreadyInDBorNot("Table1","Auth_Code",authCode))
{
UserMessage="Invalid login!";
return false;
}
else return true;
}
else{
dataBase.close();
if(!cursor.isClosed()) cursor.close();
return false;
}
}
private boolean CheckIsDataAlreadyInDBorNot( String TableName,
String dbfield, String fieldValue) {
/*checking if user is same user*/
SQLiteDatabase dataBase=getReadableDatabase();
String[] columns = { dbfield };
String selection = dbfield + " =?";
String[] selectionArgs = { fieldValue };
String limit = "1";
Cursor cursor = dataBase.query(TableName, columns, selection, selectionArgs, null, null, null, limit);
boolean exists = (cursor.getCount() > 0);
cursor.close();
dataBase.close();
return exists;
}
public static boolean empty( final String s ) {
return s == null || s.trim().isEmpty();
}
}
I know its a huge code, but logic is simple. But the problem is database lock. Could someone let me know how I can make sure that database is always in valid state on each operation?
You have beginTransaction() but no matching calls to endTransaction(). An ongoing transaction keeps the database in a locked state and also keeps the internal reference count nonzero, so close() does not yet actually close the database.
The conventional pattern for transactional operations is
db.beginTransaction();
try {
// db operations that can throw
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
Also in your onCreate() you should not be closing the database since you don't own it.

Android List to Database

I have a custom List which holds information stored from a online mysql database. I now want to put this List into a sqlite internal database. The table has already been created in the database. I also have a databasehelper class which is working fine.
All the list information is stored in FoodInfoModel class which is made of get and set properties.
Do I create a method in the databasehelper class to insert the whole list at once? not sure how to go about it.
Current Method in databasehelper
public void addDiet(FoodInfoModel foodinfomodel) {
SQLiteDatabase db = getReadableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_DIET_ID, foodinfomodel.getDietID());
values.put(KEY_DAY, foodinfomodel.getDay());
values.put(KEY_QTY, foodinfomodel.getQty());
values.put(KEY_TIME_FOOD, foodinfomodel.getTime());
values.put(KEY_ITEM_FOOD, foodinfomodel.getItem());
values.put(KEY_MEASURE, foodinfomodel.getMeasure());
// Inserting Row
db.insert("my_diet", null, values);
db.close(); //
}
Function to set List and Adapter
public void onFetchComplete(List<FoodInfoModel> data) {
this.data = data;
System.out.println("data is " + data);
if(dialog != null) dialog.dismiss();
// create new adapter
adapter = new DietAdapterNew(this, data);
// set the adapter to list
setListViewHeightBasedOnChildren(listview);
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
How do i add that data list to the internal sqlite db?
Thanks!
You basically need one more method.
public void addDiet(List<FoodInfoModel> foodinfomodels) {
SQLiteDatabase db = getReadableDatabase();
for( FoodInfoModel foodinfomodel : foodinfomodels ){
ContentValues values = new ContentValues();
values.put(KEY_DIET_ID, foodinfomodel.getDietID());
values.put(KEY_DAY, foodinfomodel.getDay());
values.put(KEY_QTY, foodinfomodel.getQty());
values.put(KEY_TIME_FOOD, foodinfomodel.getTime());
values.put(KEY_ITEM_FOOD, foodinfomodel.getItem());
values.put(KEY_MEASURE, foodinfomodel.getMeasure());
// Inserting Row
db.insert("my_diet", null, values);
}
db.close(); //
}
Yes, you have to create this kind of methods in DatabaseHelper class
public class DatabaseHandler extends SQLiteOpenHelper {
public void insertFoodInfo(ChatBase chat) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_DIET_ID, foodinfomodel.getDietID());
values.put(KEY_DAY, foodinfomodel.getDay());
values.put(KEY_QTY, foodinfomodel.getQty());
values.put(KEY_TIME_FOOD, foodinfomodel.getTime());
values.put(KEY_ITEM_FOOD, foodinfomodel.getItem());
values.put(KEY_MEASURE, foodinfomodel.getMeasure());
db.insert("my_diet", null, values);
db.close();
}
public void updateFoodInfo(FoodInfoModel model) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_DIET_ID, foodinfomodel.getDietID());
values.put(KEY_DAY, foodinfomodel.getDay());
values.put(KEY_QTY, foodinfomodel.getQty());
values.put(KEY_TIME_FOOD, foodinfomodel.getTime());
values.put(KEY_ITEM_FOOD, foodinfomodel.getItem());
values.put(KEY_MEASURE, foodinfomodel.getMeasure());
db.update("my_diet", values, KEY_DIET_ID + "=" + model.getId(),null);
db.close();
}
}
and then update or insert each FoodInfoModel inside the loop
And for bulk insert can use this code
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
What you should create is a separate class with public static functions that process the CRUD (Create, Read, Update and Delete) functions associated with the SQL transactions.
Example (SQLcrud.java):
public static boolean insertObject(SQLdatabase localDB, Object insertObject)
{
// Test if things are not null and that the DB is open and writable.
// Insert the object
// If insert successful, return TRUE.
// If anything wrong or insert not successful return FALSE (or int indicating what went wrong.
}
Actual Example:
public static boolean insertLocalAdr(SQLiteDatabase db, PersonAddress adr, boolean deleteCurrent, boolean transaction)
throws SQLFunctionFailed {
if(db != null && adr != null)
{
try
{
// If the connection is open and writable.
SQLiteGeneral.openAndWritable(db);
if(deleteCurrent)
{
deleteLocalAdr(db, transaction);
}
String sqlStmt = GeneralSQLfunctions.getUserAdrInsert(
adr,
PersonAddress.ADR_TABLE_NAME,
GeneralSQLfunctions.databaseType.SQLITE);
return StmtExecution(db, sqlStmt, transaction);
}
catch (SQLException e)
{
e.printStackTrace();
throw new SQLFunctionFailed(e.getMessage());
}
}
else
{
throw new SQLFunctionFailed("Given DB or Adr was NULL! FATAL ERROR!");
}
}
Note: GeneralSQLfunctions.getUserAdrInsert just gets a simple formatted INSERT statement and StmtExecution simply executes the statement on the SQL DB. They are there for simplification. SQLiteGeneral.openAndWritable(db) throws a (custom) SQLFunctionFailed exception so the function fails and does not proceed.
While iterating over each list items, you can start a new AsyncTask or Thread to to make it faster.

Insert only if the value does not exist in sqlite data base otherwise overwrite

I had created sqlite database,What I want to do is that when user enter value then i want to check that the value is already exist if value already exist then UPDATE otherwise INSERT that value, I had tried is...
public long insertDataCat(String id,String cat)
{
try {
SQLiteDatabase db;
db = this.getWritableDatabase(); // Write Data
ContentValues Val = new ContentValues();
Val.put("IDD", id);
Val.put("Categoryy", cat);
long rows = db.insert(TABLE_CATEGARY_MASTER, null, Val);
db.close();
return rows; // return rows inserted.
} catch (Exception e) {
return -1;
}
}
First you get the cursor count of table if any record found in the table mean it's return the cursor count 1 otherwise return zero.If cursor count one mean you perform UPDATE Operation otherwise Perform Insert Operation.
public long insertDataCat(String id,String cat)
{
try {
SQLiteDatabase db;
db = this.getWritableDatabase(); // Write Data
ContentValues Val = new ContentValues();
Val.put("IDD", id);
Val.put("Categoryy", cat);
String selectQuery = "select * from TABLE_CATEGARY_MASTER";
Cursor cursor = db.rawQuery(selectQuery, null);`
if(cursor.getCount()==1)
{
//execute update query here
long updaterow=db.update(TABLE_CATEGARY_MASTER,val);
return updaterow; // return rows inserted.
}
else
{
//Perform the insert query
long rows = db.insert(TABLE_CATEGARY_MASTER, null, Val);
return rows; // return rows inserted.
}
db.close();
} catch (Exception e) {
return -1;
}
}

SQLite queries to create a defined Java Object

I have a SQLite table of this tipe
Table Vehicles:
CATEGORY COUNTRY ID NAME EMAIL
A GE 1 BMW sample1#salple.it
A GE 2 Lamborghini sample2#salple.it
B GE 3 BMW sample3#salple.it
I want to select all the entries that have a specified name or a specified category and pass all the parameters how each row in a constructor
Vehicle(String category, String country, int id, String name, String email)
I have implemented this adapter using some tutorials:
public class TestAdapter
{
protected static final String TAG = "DataAdapter";
private final Context mContext;
private SQLiteDatabase mDb;
private DataBaseHelper mDbHelper;
public TestAdapter(Context context)
{
this.mContext = context;
mDbHelper = new DataBaseHelper(mContext);
}
public TestAdapter createDatabase() throws SQLException
{
try
{
mDbHelper.createDataBase();
}
catch (IOException mIOException)
{
Log.e(TAG, mIOException.toString() + " UnableToCreateDatabase");
throw new Error("UnableToCreateDatabase");
}
return this;
}
public TestAdapter open() throws SQLException
{
try
{
mDbHelper.openDataBase();
mDbHelper.close();
mDb = mDbHelper.getReadableDatabase();
}
catch (SQLException mSQLException)
{
Log.e(TAG, "open >>"+ mSQLException.toString());
throw mSQLException;
}
return this;
}
public void close()
{
mDbHelper.close();
}
public boolean SaveVehicles(String category , String country, String id, String name, String email)
{
try
{
ContentValues cv = new ContentValues();
cv.put("Category", category);
cv.put("Country", country);
cv.put("id", id);
cv.put("Name", name);
cv.put("Email", email);
mDb.insert("Vehicles", null, cv);
Log.d("SaveVehicles", "informationsaved");
return true;
}
catch(Exception ex)
{
Log.d("SaveVehicles", ex.toString());
return false;
}
}
}
But I don't know how I could implement the various get methods that I need, to meet a solution to my problem.
Creating an object from a SQL query would look something like this
/**
* #return Returns a list of all objects.
*/
public ArrayList<Object> getAllObjects()
{
// Select All Query
String selectQuery = "SELECT * FROM SOME_TABLE";
// Get the isntance of the database
SQLiteDatabase db = this.getWritableDatabase();
//get the cursor you're going to use
Cursor cursor = db.rawQuery(selectQuery, null);
//this is optional - if you want to return one object
//you don't need a list
ArrayList<Object> objectList = new ArrayList<Object>();
//you should always use the try catch statement incase
//something goes wrong when trying to read the data
try
{
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
//the .getString(int x) method of the cursor returns the column
//of the table your query returned
Object object= new Object(Integer.parseInt(cursor.getString(0)),
Integer.parseInt(cursor.getString(1)),
Integer.parseInt(cursor.getString(2)),
cursor.getString(3),
cursor.getString(4),
cursor.getString(5),
Boolean.parseBoolean(cursor.getString(6))
);
// Adding contact to list
objectList.add(object);
} while (cursor.moveToNext());
}
}
catch (SQLiteException e)
{
Log.d("SQL Error", e.getMessage());
return null;
}
finally
{
//release all your resources
cursor.close();
db.close();
}
return objectList;
}
The code above assumes you have some table in your database named "SOME_TABLE" and that you have an object that takes 7 parameters but you should be able to alter the snippet to make it work for you.
You need to query your database for the data, and then iterate through the returned cursor to pull out the data you need and put it into strings to feed into your constructor.
The query would look something like this (using the info you provided and the query method):
public Cursor fetchList(String category) {
return mDb.query("Vehicles", new String[] { "CATEGORY", "COUNTRY", "ID", "NAME", "EMAIL" }, "Category =" + category,
null, null, null, null);
}
Note that this is a basic query and subject to SQL injection attacks, It should be parameterized to make it less vulnerable, unless you are not going to allow the user to type in the category and rather have them pick from a list you provide.
Anyway, that would return your data in a cursor, with one row for each record that matched the search parameters. From there, you would need to iterate through the returned cursor and pull the data out of it and into strings you can use.

Categories

Resources