SQLite Android RunTimeError - java

I am trying to follow this tutorial (Part 3) about getting SQLite Database to work with Android application. I've made some changes to the content but the code should be the same. The android application crashes after it opens without displaying anything and this is the output from LogCat:
11-25 11:42:43.281: E/AndroidRuntime(1098): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.munroproject/com.example.munroproject.MainActivity}: android.database.sqlite.SQLiteException: near "drop": syntax error (code 1): , while compiling: CREATE TABLE munro (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, area TEXT, height TEXT, grid TEXT, drop TEXT, feature TEXT, country TEXT, geographurl TEXT, latitude TEXT, longitude TEXT)
and this is the contents of the database helper:
package com.example.munroproject;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "munro_directory";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
public void onCreate(SQLiteDatabase db){
String sql = "CREATE TABLE munro (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"area TEXT, " +
"height TEXT, " +
"grid TEXT, " +
"drop TEXT, " +
"feature TEXT, " +
"country TEXT, " +
"geographurl TEXT, " +
"latitude TEXT, " +
"longitude TEXT)";
db.execSQL(sql);
ContentValues values = new ContentValues();
String inputvalue = "Ben Chonzie,Loch Tay to Perth,931,NN773308,645,cairn/shelter,S,NN7732430857,56.453851,-3.992057");
String[] msplit = inputvalue.split(",");
int j=0;
values.put("name",msplit[j++]);
values.put("area",msplit[j++]);
values.put("height",msplit[j++]);
values.put("grid",msplit[j++]);
values.put("drop",msplit[j++]);
values.put("feature",msplit[j++]);
values.put("country",msplit[j++]);
values.put("geograph",msplit[j++]);
values.put("latitute",msplit[j++]);
values.put("longitude",msplit[j++]);
db.insert("munro", "name", values);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS munro");
onCreate(db);
}
}
And the mainActivity file looks like this:
package com.example.munroproject;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends Activity {
protected EditText searchText;
protected SQLiteDatabase db;
protected Cursor cursor;
protected ListAdapter adapter;
protected ListView munroList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = (new DatabaseHelper(this)).getWritableDatabase();
searchText = (EditText) findViewById (R.id.searchText);
munroList = (ListView) findViewById (R.id.list);
}
#SuppressWarnings("deprecation")
public void search(View view) {
// || is the concatenation operation in SQLite
cursor = db.rawQuery("SELECT _id, name, height, region FROM munro WHERE name || ' ' || height LIKE ?",
new String[]{"%" + searchText.getText().toString() + "%"});
adapter = new SimpleCursorAdapter(this,R.layout.munro_list_item,cursor,new String[] {"name", "height", "region"},new int[] {R.id.name, R.id.height, R.id.region});
munroList.setAdapter(adapter);
}
Any suggestions ?

"drop" is a reserved keyword in SQLite used to drop (or delete) tables. If you really want to use it, you can, by enclosing it in double quotes. See example below
CREATE TABLE "[tablename]" ("drop" text)

In sqlite INTEGER PRIMARY KEY is Autoincrement by default no need to specify INTEGER PRIMARY KEY AUTOINCREMENT In addition sql has inbuilt command drop so change the column/attribute name

Related

My app keeps crashing when I go to another activity

I am trying to make an app named 'moviesinfo', in which I have a login page, with sign up and forgot password option. When I try to log in, the app crashes. I also don't know if the data entered on the sign-up page is being stored in the database or not.
This is my mainactivity.java
package com.example.moviesinfo;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
SQLiteDatabase db;
SQLiteOpenHelper openHelper;
private EditText user;
private EditText password;
private Button btn;
private Button btn2;
private Button forgot;
Cursor cursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
forgot=findViewById(R.id.forgot);
btn2=(Button) findViewById(R.id.signup);
user= (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
btn = (Button) findViewById(R.id.login);
openHelper= new DatabaseHelper(this);
db=openHelper.getReadableDatabase();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String username1= user.getText().toString();
String password1= password.getText().toString();
cursor = db.rawQuery("SELECT * FROM " +DatabaseHelper.TABLENAME + " WHERE " + DatabaseHelper.COL2 + "=? AND " + DatabaseHelper.COL3+"=?", new String[]{username1,password1});
if (cursor!=null){
if (cursor.getCount()>0){
cursor.moveToNext();
Intent intent = new Intent(MainActivity.this,listmenu.class);
startActivity(intent);
//Toast.makeText(getApplicationContext(),"Login Successful", Toast.LENGTH_SHORT).show();//
}else{
Toast.makeText(getApplicationContext(),"Error" , Toast.LENGTH_SHORT).show();
}
}
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sign_up();
}
});
forgot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
forgot();
}
});
}
private void sign_up()
{
Intent intent= new Intent(MainActivity.this, signup.class);
startActivity(intent);
}
private void forgot()
{
Intent intent= new Intent(MainActivity.this, forgot.class);
startActivity(intent);
}
}
This is the signup.java class
package com.example.moviesinfo;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.lang.String;
import java.util.ArrayList;
public class signup extends AppCompatActivity {
SQLiteOpenHelper openHelper;
DatabaseHelper db;
SQLiteDatabase db1;
public String uname = "";
public String pwd = "";
public ArrayList<String> cpwd = new ArrayList<String>();
EditText e1, e2, e3;
Button b1,b2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup);
openHelper= new DatabaseHelper(this);
e1 = (EditText) findViewById(R.id.username);
e2 = (EditText) findViewById(R.id.password);
e3 = (EditText) findViewById(R.id.cpwd);
b1 = (Button) findViewById(R.id.save);
b2 = (Button) findViewById(R.id.login2);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db1=openHelper.getWritableDatabase();
String username =e1.getText().toString();
String password =e2.getText().toString();
String confirm_password =e3.getText().toString();
insert_data(username,password,confirm_password);
}
});
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(signup.this,MainActivity.class);
startActivity(intent);
}
});
}
public void insert_data(String username, String password, String confirm_password)
{
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.COL2, username);
contentValues.put(DatabaseHelper.COL3, password);
contentValues.put(DatabaseHelper.COL4, confirm_password);
long id=db1.insert(DatabaseHelper.TABLENAME, null, contentValues);
}
}
This is the DatabseHelper.java class
package com.example.moviesinfo;
import com.example.moviesinfo.signup;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME="userdetails.db";
public static final String TABLENAME="user details";
public static final String COL1="id";
public static final String COL2="username";
public static final String COL3="password";
public static final String COL4="confirmpassword";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null,1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + "TABLENAME(ID INTEGER PRIMARY KEY AUTOINCREMENT,USERNAME TEXT,PASSWORD TEXT,CONFIRMPASSWORD TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " +TABLENAME);
onCreate(db);
}
}
I expect that when I click the login button it should jump to the next activity with checking the login details from the database.
Issue 1
The first issue you will encounter is that the table name user details has a space. user will be extracted as the identifier but then the SQL parser is not expecting details, it is not a keyword or clause and thus a syntax error as per the following which would be found in the log :-
5-19 14:09:14.335 26779-26779/s.e.so56180693anotheractivity E/AndroidRuntime: FATAL EXCEPTION: main
Process: s.e.so56180693anotheractivity, PID: 26779
java.lang.RuntimeException: Unable to start activity ComponentInfo{s.e.so56180693anotheractivity/s.e.so56180693anotheractivity.MainActivity}: android.database.sqlite.SQLiteException: near "details": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE IF NOT EXISTS user details(_id INTEGER PRIMARY KEY,username TEXT,password TEXT, confirmpassword TEXT)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.database.sqlite.SQLiteException: near "details": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE IF NOT EXISTS user details(_id INTEGER PRIMARY KEY,username TEXT,password TEXT, confirmpassword TEXT)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1769)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1698)
at s.e.so56180693anotheractivity.DatabaseHelper.onCreate(DatabaseHelper.java:33)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:393)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:322)
at s.e.so56180693anotheractivity.MainActivity.onCreate(MainActivity.java:35)
at android.app.Activity.performCreate(Activity.java:7136)
see Debug your app
An identifier can have normally unacceptable characters, such as a space, start with a number, if it is enclosed in specific characters as per :-
If you want to use a keyword as a name, you need to quote it. There are four ways of quoting keywords in SQLite:
'keyword' A keyword in single quotes is a string literal.
"keyword" A keyword in double-quotes is an identifier.
[keyword] A keyword enclosed in square brackets is an identifier. This is not
standard SQL. This quoting mechanism is used by MS Access and SQL
Server and is included in SQLite for compatibility.
keyword A keyword enclosed in grave accents (ASCII code 96) is an identifier.
This is not standard SQL. This quoting mechanism is used by MySQL and is included in SQLite for compatibility.
e.g. you could have :-
public static final String TABLENAME="user details"; //<<<<<<<<<< cannot have spaces in a name unless enclosed
//!!!!NOTE!!!! ONLY 1 of the below would be allowed
public static final String TABLENAME="`user details`"; //<<<<<<<<<< e.g (with space)
public static final String TABLENAME= "[user details]";
public static final String TABLENAME = "\"user details\"";
public static final String TABLENAME = "'user details'";
public static final String TABLENAME="user_details"; //<<<<<<<<<< changed to this for testing.
Read the comments
Fix for Issue 1
public static final String TABLENAME="user details";
was changed to :-
public static final String TABLENAME="user_details";
The App was uninstalled and rerun.
Issue 2
The next issue is that the SQL to create the table will not create a table named according to the value that the constant TABLENAME (user_details after applying the Fix 1) has. The table is named TABLENAME as the word TABLENAME is in quotes.
It results in the exception :-
2019-05-19 13:56:15.118 26443-26443/s.e.so56180693anotheractivity E/SQLiteLog: (1) no such table: user_details
Fix for Issue 2
The following is how it would be suggested that the CREATE TABLE sql is setup:-
//Uses the identifiers (names) as per the variables
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLENAME + "(" +
COL1 + " INTEGER PRIMARY KEY," + // NO NEED FOR INEFFICIENT AUTOINCREMENT
COL2 + " TEXT UNIQUE," + //ADDED UNIQUE so that user names are not duplicated
COL3 + " TEXT, " +
COL4 + " TEXT" +
")"
);
That is constants are used for the names.
IMPORTANT as this is a change to the database schema and that the database exists you MUST delete the database so that the DatabaseHelper onCreate method will run.
The keyword UNIQUE has been added, otherwise the same user could be added multiple times
Question
I also don't know if the data entered on the sign-up page is being
stored in the database or not.
To enable you to know or not and as you should now be aware of looking in the log then amending the insert_data method as follows will enable you to see if the data is being stored.
public long insert_data(String username, String password, String confirm_password) // Signature changed to return long (id)
{
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.COL2, username);
contentValues.put(DatabaseHelper.COL3, password);
contentValues.put(DatabaseHelper.COL4, confirm_password);
long id=db1.insert(DatabaseHelper.TABLENAME, null, contentValues);
//TODO REMOVE LOGGING BEFORE PUBLISHING THE APP
if (id > 0) {
Log.d("INSERTUSERDETAILSROW","The row was successfully inserted into the " + DatabaseHelper.TABLENAME + " table.");
} else {
Log.d("INSERTUSERDETAILSROW","Row not inserted!!!!!!!!!!");
}
return id; // Can be useful to have access to the id that was generated. Note method signature change
}
Example output :-
in the log :-
D/INSERTUSERDETAILSROW: The row was successfully inserted into the user_details table.
Issue 4
If the password and confirm_password values do not match, the row is still added i.e. the confirm_password values serves no purpose.
Fix for Issue 4
A check is added to only add data if the password and confirm_password values match. If they do not then a Toast is issued.
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db1=openHelper.getWritableDatabase();
String username =e1.getText().toString();
String password =e2.getText().toString();
String confirm_password =e3.getText().toString();
if (password.equals(confirm_password)) {
insert_data(username, password, confirm_password);
} else {
Toast.makeText(v.getContext(),"Password and Confirm Password do not match. Data not added.",Toast.LENGTH_LONG).show();
}
}
});
Issue 5
Although it won't appear to be a problem your should not start the activity when you want to return from an activity as that will destroy the initial activity and start another. The correct way is to finish the activity and it will then return to the actual activity from which it is was started from.
Fix for Issue 5
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Intent intent = new Intent(signup.this,MainActivity.class);
//startActivity(intent);
finish(); //<<<<<<<<<< Proper way to return
}
});
Done
That's it. The App should now be relatively functional as far as logging in and signing up is concerned.

I want to save user profile in local sqlite database and the user information

I've done firebase authentication for login and sign up and now i want
to save user profile in local sqlite database. I've fetched the user
information from firebase and storing them in a string variable and
passing these variables to the Adduser function to save this data in
the local database.But data is not getting stored and showing "Error
with saving user" ,that is rowid is "-1" always. i'm new to android.
please help me to solve this issue. thanks in advance
java file
package com.example.mansi.busezon;
import android.app.Application;
import android.content.ContentValues;
mport android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.mansi.busezon.data.dbContract;
import com.example.mansi.busezon.data.dbHelper;
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
i
public class SELL_BUY extends AppCompatActivity {
// private dbHelper mDbHelper;
String name;
String email ;
String address ;
String phoneno ;
String password ;
//String userId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the content of the activity to use the activity_main.xml layout file
setContentView(R.layout.activity_sell__buy);
check();
TextView BUY= (TextView) findViewById(R.id.buy);
BUY.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//create intent to open the activity
Intent BUYintent= new Intent(SELL_BUY.this,HomeActivity.class);
//start the new activity
startActivity(BUYintent);
}
});
TextView SELL= (TextView) findViewById(R.id.sell);
SELL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//create intent to open the activity
Intent SELLintent= new Intent(SELL_BUY.this,SellHomepage.class);
//start the new activity
startActivity(SELLintent);
}
});
}
public void sendMessage(View view)
{
Intent intent = new Intent(SELL_BUY.this, profile_page.class);
startActivity(intent);
}
private void check()
{
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
//database reference pointing to demo node
// DatabaseReference demoRef = rootRef.child("CI8hvEW0sfZ0oU1GziTpGYPJv2z2");
// String value = "User22";
// //push creates a unique id in database
// demoRef.push().setValue(value);
rootRef.addListenerForSingleValueEvent(new ValueEventListener()
{
String userId=getIntent().getStringExtra("Id");
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren())
{
if(ds.getKey().equals(userId))
{
//name1="aakritijohar";
name = ds.child("name").getValue(String.class);
email = ds.child("email").getValue(String.class);
address = ds.child("addres").getValue(String.class);
phoneno = ds.child("phoneno").getValue(String.class);
TextView textView = (TextView) findViewById(R.id.test);
textView.setText(phoneno);
password = ds.child("password").getValue(String.class);
Toast.makeText(SELL_BUY.this, email + " " + ds.getKey(), Toast.LENGTH_SHORT).show();
insertUser(name,email,address,phoneno,password);
}
}
Bundle extras=getIntent().getExtras();
if(extras!=null) {
String name = extras.getString("name");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
}
private void insertUser(String nameString,String EMAILString,String addressString,String numbertString,String pass) {
// Create database helper
dbHelper mDbHelper = new dbHelper(this);
// Gets the database in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(dbContract.userEntry.COLUMN_USER_NAME, nameString);
values.put(dbContract.userEntry.COLUMN_EMAIL, EMAILString);
values.put(dbContract.userEntry.COLUMN_number, numbertString);
values.put(dbContract.userEntry.COLUMN_address, addressString);
values.put(dbContract.userEntry.COLUMN_password, pass);
// Insert a new row for user in the database, returning the ID of that new row.
long newRowId = db.insert(dbContract.userEntry.TABLE_NAME, null, values);
// Show a toast message depending on whether or not the insertion was successful
if (newRowId == -1) {
// If the row ID is -1, then there was an error with insertion.
Toast.makeText(this, "Error with saving user", Toast.LENGTH_SHORT).show();
} else {
// Otherwise, the insertion was successful and we can display a toast with the row ID.
Toast.makeText(this, "user saved " + newRowId, Toast.LENGTH_SHORT).show();
}
}
}
database helper class
package com.example.mansi.busezon.data;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Database helper for Pets app. Manages database creation and version management.
*/
public class dbHelper extends SQLiteOpenHelper {
public static final String LOG_TAG = dbHelper.class.getSimpleName();
/** Name of the database file */
private static final String DATABASE_NAME = "user.db";
/**
* Database version. If you change the database schema, you must increment the database version.
*/
private static final int DATABASE_VERSION = 1;
/**
* Constructs a new instance of {#link dbHelper}.
*
* #param context of the app
*/
public dbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* This is called when the database is created for the first time.
*/
#Override
public void onCreate(SQLiteDatabase db) {
// Create a String that contains the SQL statement to create the pets table
String SQL_CREATE_USER_TABLE = "CREATE TABLE " + dbContract.userEntry.TABLE_NAME + " ("
+ dbContract.userEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ dbContract.userEntry.COLUMN_USER_NAME + " TEXT NOT NULL, "
+ dbContract.userEntry.COLUMN_address + " VARCHAR, "
+ dbContract.userEntry.COLUMN_number + " VARCHAR NOT NULL, "
+ dbContract.userEntry.COLUMN_EMAIL + " VARCHAR NOT NULL, "
+ dbContract.userEntry.COLUMN_password + " VARCHAR NOT NULL );";
// Execute the SQL statement
db.execSQL(SQL_CREATE_USER_TABLE);
}
/**
* This is called when the database needs to be upgraded.
*/
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// The database is still at version 1, so there's nothing to do be done here.
}
}
There doesn't appear to be anything wrong with the code as it is.
As such I suspect that your issue may be that you have changed the table structure since running the App.
e.g. by adding a new column and then changing the code accordingly
However, that you have then not taken into consideration that the onCreate method only gets automatically invoked when the database is created.
That is the 'onCreate' method does not run every time the App is started.
I'd suggest that deleting the App's data or uninstalling the App and then rerunning the App will resolve the issue.
If that doesn't resolve the issue then please check the log as that should contain a stack-trace for when the insert comes across the issue even though the App doesn't itself crash (you could use the insertOrThrow method instead of insert which would then result in an exception/crash).
If you then still have issues, please update the question to include the stack-trace.

SQLite DB table not created in Android while DB created

I am working towards creating an Android app. I am beginner in Android and Java application development while I have good experience of web development.
I am trying to create a DB and then creating my first table in SQLite. It is creating DB but not DB table.
I have created Contaract class.
package com.haafiz.project;
import android.provider.BaseColumns;
public final class ProjectContaract {
public ProjectContaract(){}
public static abstract class Site implements BaseColumns{
public static final String TABLE_NAME = "site";
public static final String COLUMN_NAME_SITE_NAME = "site_name";
public static final String COLUMN_NAME_LOGIN = "login_name";
public static final String COLUMN_NAME_HOST = "host";
public static final String COLUMN_NAME_PASSWORD = "password";
}
}
And then DB helper class.
package com.haafiz.project;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper {
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + ProjectContaract.Site.TABLE_NAME + " (" +
projectContaract.Site._ID + " INTEGER PRIMARY KEY," +
projectContaract.Site.COLUMN_NAME_SITE_NAME + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_LOGIN + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_HOST + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_PASSWORD + TEXT_TYPE + " )";
private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + ProjectContaract.Site.TABLE_NAME;
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "Project";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
#Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
And here my main activity using that DB Helper as below:
package com.haafiz.project;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
projectDBHelper dbHelper = new projectDBHelper(getApplicationContext());
// Gets the data repository in read mode
SQLiteDatabase db = dbHelper.getWritableDatabase();
// Projection that specifies which columns from the database
String[] projection = {
projectContaract.Site._ID,
projectContaract.Site.COLUMN_NAME_SITE_NAME,
projectContaract.Site.COLUMN_NAME_LOGIN,
projectContaract.Site.COLUMN_NAME_HOST,
projectContaract.Site.COLUMN_NAME_PASSWORD
};
// How you want the results sorted in the resulting Cursor
String sortOrder =
projectContaract.Site.COLUMN_NAME_SITE_NAME + " DESC";
Cursor c = db.query(
projectContaract.Site.TABLE_NAME, // The table to query
projection, // The columns to return
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
setContentView(R.layout.activity_main);
}
#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_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
DB is being created but table is not, I check that with adb shell attach with emulator. What am I doing wrong? The table is not being created.
And an important thing is that I am not getting errors related to this in log.
But in logcat with "no filter" in drop down where it was "show only selected application" previously and with "sql" in filter search box, it shows following messages in log cat:
08-04 00:41:35.494 403-474/android.process.media V/MediaScanner﹕ pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor#41302da8
08-04 00:41:35.494 403-474/android.process.media V/MediaScanner﹕ /pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor#41302da8
08-04 00:54:02.685 623-632/com.haafiz.project E/SQLiteDatabase﹕ close() was never explicitly called on database '/data/data/com.haafiz.project/databases/project'
android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1943)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:770)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
at com.haafiz.project.MainActivity.onCreate(MainActivity.java:20)
at android.app.Activity.performCreate(Activity.java:4466)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
08-04 00:54:02.766 623-632/com.haafiz.project E/System﹕ java.lang.IllegalStateException: Don't have database lock!
at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2090)
at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2182)
at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2178)
at android.util.LruCache.trimToSize(LruCache.java:197)
at android.util.LruCache.evictAll(LruCache.java:285)
at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2143)
at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1914)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
at java.lang.Thread.run(Thread.java:856)
Other than first two lines, other lines in output of log cat, all other lines are highlighted in red color.
Seems like the database didn't get closed correctly. Sometimes this can happen during development when you are often reinstalling builds of the app.
Uninstall the app and reinstall it. Alternatively open Settings > Apps > [your app] and tap the Clear Data button. Either of these will remove the existing database file so the next attempt to open it will create a new one.
SQLLite operates in many modes, one of which is that everything is stored in memory and not flushed to disk unless certain conditions are met (like high mem usage or db being closed). You are not closing the db which is why you are not able to see the tables in the sqlite file.
For your example to work, store dbHelper as a class property, assign new object to it when activity initializes, and then close it before the activity is closed/destroyed. That should solve your issue.
You're missing a semicolon at the end of your create table SQL statement. Also, your primary key should be autoincrement.
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + ProjectContaract.Site.TABLE_NAME + " (" +
projectContaract.Site._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
projectContaract.Site.COLUMN_NAME_SITE_NAME + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_LOGIN + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_HOST + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_PASSWORD + TEXT_TYPE + " );";

How can I insert the date into the table enter by the user if it is not in that table in Android

I am getting the input from the user as a date and I want to check that if that date is in the table then fetch the data corresponding to that date otherwise insert the date in that table.
I am using the following code and getting problem in the select query. My code is below:
package com.foursquaregame.in;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class Astro_talk extends Activity{
EditText dob;
Button submit;
SQLiteDatabase db_sunshine=null;
String Data="";
String Data1="";
String TableName="tb_astro";
String dob_var;
String date_var;
String quote;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.astro_talk);
//quote="Don't worry, Be happy";
dob=(EditText)findViewById(R.id.dob);
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
submit=(Button)findViewById(R.id.submit);
submit.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
java.util.Date dateObject;
System.out.println("submit data");
dob_var=dob.getText().toString();
try {
dateObject = sdf.parse(dob_var);
date_var = new SimpleDateFormat("yyyy/MM/dd").format(dateObject);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(dob_var);
try
{
db_sunshine=Astro_talk.this.openOrCreateDatabase("db_hellosunshine", MODE_PRIVATE, null);
db_sunshine.execSQL("CREATE TABLE IF NOT EXISTS "+ TableName + " (d_o_b NUMERIC,astro_quote DATE))");
Cursor c=db_sunshine.rawQuery("SELECT astro_quote FROM "+ TableName +"WHERE d_o_b='"+ date_var +"'" , null);
System.out.println("query executed");
int column1=c.getColumnIndex("d_o_b");
int column2=c.getColumnIndex("astro_quote");
c.moveToFirst();
if(c!=null)
{
{
String date=c.getString(column1);
String astro =c.getString(column2);
Data=Data+date+"\n";
Data1=Data1+astro+"\n";
System.out.println("name"+date+" score"+astro);
}while(c.moveToNext());
}
if(Data.equals(dob_var)){
RelativeLayout rel_astro=(RelativeLayout)findViewById(R.id.rel_astro);
TextView tv_astro=(TextView)findViewById(R.id.tv_astro);
tv_astro.setText(Data);
setContentView(rel_astro);
}
else{
db_sunshine.execSQL("INSERT INTO "+TableName+"(d_o_b,astro_quote)"+" VALUES ('"+dob_var+"','"+quote+"');");
Toast customToast = new Toast(getBaseContext());
customToast = Toast.makeText(getBaseContext(), "Your quote is submit", Toast.LENGTH_SHORT);
customToast.setGravity(Gravity.CENTER_HORIZONTAL, 0, 0);
customToast.show();
Intent newIntent = new Intent(Astro_talk.this,selectoption.class);
startActivity(newIntent);
finishActivity(0);
}
}catch(Exception ex)
{
Log.e("ERROR","ERROR" ,ex);
}
finally
{
if(db_sunshine!=null)
db_sunshine.close();
}
}
});
}
}
Please tell me where I am doing something wrong.
Cursor c=db_sunshine.rawQuery("SELECT astro_quote FROM "+ TableName +"WHERE d_o_b='"+ date_var +"'" , null);
System.out.println("query executed");
int column1=c.getColumnIndex("d_o_b");
int column2=c.getColumnIndex("astro_quote");
c.moveToFirst();
if(c!=null)
{
{
String date=c.getString(column1);
String astro =c.getString(column2);
Data=Data+date+"\n";
Data1=Data1+astro+"\n";
System.out.println("name"+date+" score"+astro);
}while(c.moveToNext());
}
Here you are querying for one column but trying to get two columns
you can get only one date that is
int column1=c.getColumnIndex("astro_quote");
String astro =c.getString(column1);
Try using :
Cursor c=db_sunshine.rawQuery("SELECT astro_quote FROM "+ TableName +" WHERE d_o_b="+ date_var, null);
I am not sure,these were the only problem but thats might be because you didn't add a space character before WHERE in your query(which i have added in above one).And your d_o_b is numeric then i think,you don't need to use " ' " before and after date_var in your query.
EDIT :
It seems from your code that you are trying to access the table just after you create it.So there is no data in table and hence,you will get empty cursor.when you try to access data from that cursor,you are getting exception.
First fill the table with data.and then try to fetch it.
so basically what you need to do is-
db_sunshine=Astro_talk.this.openOrCreateDatabase("db_hellosunshine", MODE_PRIVATE, null);
db_sunshine.execSQL("CREATE TABLE IF NOT EXISTS "+ TableName + " (d_o_b NUMERIC,astro_quote DATE))");
// call a function to add data to table ( you will have to add data here to the table created just now )
Cursor c=db_sunshine.rawQuery("SELECT astro_quote FROM "+ TableName +" WHERE d_o_b="+ date_var, null);
if(c.getCount()>0)
{
// cursor contains data ( which can never be a option for your case )
}
else
{
// empty cursor
}

Adding Information in SQLite

I am having trouble with my Android App when adding information into SQLite. I am relatively new to Java/SQLite and though I have followed a lot of tutorials on SQLite and have been able to get the example code to run I am unable to get tables to be created and data to import when running my own app. I have included my code in two Java files Questions (Main Program) and QuestionData (helper class represents the database).
Questions.java:
public class Questions extends Activity {
private QuestionData questions;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.quiztest);
questions = new QuestionData(this);
try {
Cursor cursor = getQuestions();
showQuestions(cursor);
} finally {
questions.close();
}
}
private Cursor getQuestions() {
//Select Query
String loadQuestions = "SELECT * FROM questionlist";
SQLiteDatabase db = questions.getReadableDatabase();
Cursor cursor = db.rawQuery(loadQuestions, null);
startManagingCursor(cursor);
return cursor;
}
private void showQuestions(Cursor cursor) {
// Collect String Values from Query and Display them this part of the code is wokring fine when there is data present.
QuestionData.java
public class QuestionData extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "TriviaQuiz.db" ;
private static final int DATABASE_VERSION = 2;
public QuestionData(Context ctx) {
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE questionlist (_id INTEGER PRIMARY KEY AUTOINCREMENT, QID TEXT, QQuestion TEXT, QAnswer TEXT, QOption1 TEXT, QOption2 TEXT, QOption3 TEXT, QCategoryTagLvl1 TEXT, QCategoryTagLvl2 TEXT, QOptionalTag1 TEXT, QOptionalTag2 TEXT, QOptionalTag3 TEXT, QOptionalTag4 TEXT, QOptionalTag5 TEXT, QTimePeriod TEXT, QDifficultyRating TEXT, QGenderBias TEXT, QAgeBias TEXT, QRegion TEXT, QWikiLink TEXT, QValidationLink1 TEXT, QValidationLink2 TEXT, QHint TEXT, QLastValidation TEXT, QNotes TEXT, QMultimediaType TEXT, QMultimediaLink TEXT, QLastAsked TEXT);");
db.execSQL("INSERT INTO questionlist (_id, QID, QQuestion, QAnswer, QOption1, QOption2, QOption3, QCategoryTagLvl1, QCategoryTagLvl2, QOptionalTag1, QOptionalTag2, QOptionalTag3, QOptionalTag4, QOptionalTag5, QTimePeriod, QDifficultyRating, QGenderBias, QAgeBias, QRegion, QWikiLink, QValidationLink1, QValidationLink2, QHint, QLastValidation, QNotes, QMultimediaType, QMultimediaLink, QLastAsked)"+
"VALUES (null,'Q00001','Example','Ans1','Q1','Q2','Q3','Q4','','','','','','','','','','','','','','','','','','','','')");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
Any suggestions at all would be great. I have tried debugging which suggests that the database does not exist. Thanks in advance for your assistance.
I removed the constants setup which had a capitalisation in it which was not referenced elsewhere. I knew it was going to be something simple but I could not locate the issue. Thanks again!

Categories

Resources