I have my database created in event onCreate, in which I have a lot of tables, but I need add 1 more table, and I can't lose any data, So I need to use the event onUpgrade, So I hope you guys help me because I don't know how to use it.
Example :
public void onCreate(SQLiteDatabase db) {
sql = "CREATE TABLE IF NOT EXISTS funcionarios"
+"(codigo INTEGER PRIMARY KEY, funcionario TEXT, apelido TEXT , functionTEXT, cartao TEXT , foto TEXT , tipo_foto TEXT);";
db.execSQL(sql);
}
what i need is
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(oldVersion < 2){
db.execSQL("CREATE TABLE IF NOT EXISTS calibrar_aceleracao"+
"(limiteMaximo INTEGER, limiteMinimo INTEGER);");
}
}
but it doesn't work.
thanks.
You do not need to change you applications version to update your database - not saying it is incorrect but there is a more efficient way of doing it. And that is through the use of the super's constructor of your helper it would look something like the following:
public class MyDatabaseHelper extends SQLiteOpenHelper {
public MyDatabaseHelper(Context context) {
super(context, "My.db", null, 1 /* This is the version of the database*/);
}
#Override
public void onCreate(SQLiteDatabase database) {
sql = "CREATE TABLE IF NOT EXISTS funcionarios (codigo INTEGER PRIMARY KEY, funcionario TEXT, apelido TEXT , functionTEXT, cartao TEXT , foto TEXT , tipo_foto TEXT);";
db.execSQL(sql);
}
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
if(oldVersion < 2){
db.execSQL("CREATE TABLE IF NOT EXISTS calibrar_aceleracao (limiteMaximo INTEGER, limiteMinimo INTEGER);");
}
}
}
The method onUpgrade is called when your version database is incremented. Verify in your class where you define your database version and increment this value.
Run application. Your method onUpgrade is called.
For onUpgrade to get called you must increase the database version that you supply to the SqliteOpenHelper implementation constructor.
Use a field in your class to store the same and increment it when you change your database schema.
This is not the way onUpgrade works.This is a method which will be called when you release some new version of your application and make it available for download in google play(and which may be requiring some updations to the database of the application already installed on users' devices').For your problem's solution
Just add the query of CREATE TABLE IF NOT EXISTS in your onCreate() as you did for the creation of the other table in your onCreate() method already
public void onCreate(SQLiteDatabase db) {
sql = "CREATE TABLE IF NOT EXISTS funcionarios"
+"(codigo INTEGER PRIMARY KEY, funcionario TEXT, apelido TEXT , functionTEXT, cartao TEXT , foto TEXT , tipo_foto TEXT);";
///HERE YOUR Create Table QUERY and call db.execSQL
db.execSQL(sql);
}
The method is onUpgrade is not being called probably because there are errors in the sql code, for example in the onCreate:
functionTEXT
is missing a space before TEXT.
Also after,
calibrar_aceleracao"+ "(limiteMaximo
is missing a space before the bracket.
I had the same problem, I was caching the SQLiteException so I didn't see the error was there.
Put some logcat at the beginning and at the end of the method body and you'll see where the error is.
EDIT: another thing, why did you put that if?
if (oldVersion < 2)
It's not necessary at all.
Related
I am creating an android based Appointment management system. For storing appointments I'm using an SQLite database. The application works flawlessly but the only problem is that the Database gets recreated every time I restart the application it self. Following is my onCreate and onUpgrade methods. (PS. I used a video tutorial on creating and connecting the database. This worked fine on him. Only difference is I'm using a Mac and he was using Windows)
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, DATE TEXT, TIME TEXT, TITLE TEXT, DETAIL TEXT, UNIQUE(DATE, TITLE))");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXITS" + TABLE_NAME);
onCreate(db);
}
Just in case I have uploaded my full database connection code here, Database.java
Hard to tell without seeing the entire class, but you may be inadvertently deleting the database somewhere? Look for calls to deleteDatabase that may be buried somewhere, particularly if you based your code of a tutorial that may have left bits and pieces of code in place.
I'm creating an android application. I'm using schematic to generate a content provider.
I understand that the actual code used by the application is generated out of the classes I create. Based on that, I'd like to know what problems I will face if I reference the generated code in the source code.
The code I'm using is the following:
package com.example.movies.data;
#Database(
version = MovieDatabase.VERSION,
packageName = "com.example.movies.provider"
)
public class MovieDatabase {
public static final int VERSION = 1;
#Table(MovieColumns.class)
public static final String MOVIE = "movie";
// Some more tables here
#OnUpgrade
public static void onUpgrade(Context context, SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + MOVIE);
// The next SQL statement is generated out of the current class
db.execSQL(com.example.movies.provider.MovieDatabase.MOVIE);
}
}
The generated code is next:
package com.example.movies.provider;
public class MovieDatabase extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
// The next statement is the one I use in the source code
public static final String MOVIE = "CREATE TABLE movie ("
+ MovieColumns._ID + " INTEGER PRIMARY KEY,"
+ MovieColumns.TITLE + " TEXT NOT NULL,"
+ MovieColumns.SYNOPSIS + " TEXT,"
+ MovieColumns.POSTER_URL + " TEXT NOT NULL,"
+ MovieColumns.RELEASE_DATE + " INTEGER NOT NULL,"
+ MovieColumns.RATING + " REAL)";
// Some other SQL statements and functions
// The next function is generated out of onUpgrade
// in the source class MovieDatabase
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
com.example.movies.data.MovieDatabase.onUpgrade(context, db, oldVersion, newVersion);
}
}
As you can see, I need the SQL statements generated by the source code, and the idea of using the mentioned library is to avoid all the boilerplate code.
Are there other alternatives?
Slightly better approach would be:
#OnUpgrade
public static void onUpgrade(Context context, SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + MOVIE);
// The next SQL statement is generated out of the current class
com.example.movies.provider.MovieDatabase.getInstance(context).onCreate(db);
}
At least you do not need to specify each table.
Based on that, I'd like to know what problems I will face if I reference the generated code in the source code.
I would say no real problems.
The only noticeable thing is that Android Studio will highlight this as compilation error until class is generated (during the first build).
Hi I have been working on a project that requires a database to store answers, hints, etc and I have added one row into the database using a method. I also made a getAnswer method that uses a rawQuery() to get the answer in the specified row (1) for the first and only item added in the database.
So the database class is all finished and I want to use the database for my game. I'm assuming it has to run the method once to fill the database (couldn't figure out better way to do an internal database so it will run every time the game is opened, if you know a better way I'm all ears). However in my Main Activity I can't seem to call the method that fills the database or the method to retrieve an item from the database. I have been looking and I don't understand why it is not working.
I am posting the Main Activity first and then the Game Database. Any help on how to use my database is greatly appreciated.
Main Activity Class
package tekvision.codedecrypter;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import gameInfo.GameDatabase;
public class MainActivity extends ActionBarActivity {
//Runs before the application is created
public Button mCampaignButton;
//When the application is created
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//
// I wanted to call it heat and use it in a toast to make sure its working
//Gamedatabase. does not work to find my method
//
//Keeps screen on so it doesn't fall asleep
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//Finding button by button id after application is created
mCampaignButton = (Button)findViewById(R.id.campaignButtonID);
//Checks if the campaign button is clicked
mCampaignButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast pop up message
Toast toast = Toast.makeText(getApplicationContext(),
"campaign select",
Toast.LENGTH_SHORT);
toast.show();
//Intent to go from main activity to campaign Level Select Activity
Intent intent = new Intent(MainActivity.this, CampaignSelectLevel.class);
startActivity(intent);
}
});
}
}
Game Database Class
package gameInfo;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by User on 06/06/2015.
*/
//Extends the sql database open helper it will be error until the 2 methods are added plus the constructor
//the database is saved to a text file
public class GameDatabase extends SQLiteOpenHelper {
//Version number of the database
//Every update to the database will result in going up in the database version number
private static final int DATABASE_VERSION = 1;
//Private set of final strings, for the column names in the database
private static final String DATABASE_NAME =
"Database",
TABLE_1 = "Answers and Hints",
TABLE_2 = "classical",
TABLE_3 = "ancient",
KEY_ID = "id",
KEY_HINT = "hint",
KEY_ANSWER = "answer",
KEY_QUESTION = "question",
KEY_INFO = "info",
KEY_IMAGE = "image";
//Database Constructor, sets the databases named and the version of the database
public GameDatabase(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//Whenever database is created
//Creating a table with each column and specify each columns type such as text or integer that is the primary key
#Override
public void onCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE " + TABLE_1 + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_QUESTION + " TEXT" + KEY_ANSWER + " TEXT" + KEY_IMAGE + "IMAGEVIEW" + KEY_HINT + " TEXT" + KEY_INFO + " TEXT)");
}
//When the database is upgraded
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS " + TABLE_MODERN);
onCreate(db);
}
//Currently should have ONE row for level on in modern
public void fillGameDatabase(){
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
//Fills information for the first row by a few columns
//Modern ERA
values.put(KEY_QUESTION, "US President");
values.put(KEY_ANSWER, "Barack Obama");
values.put(KEY_HINT, "He is the first African American president");
values.put(KEY_INFO, "Barack Obama is the 44th President of the United States, and the first African American to hold the office. Born in Honolulu, Hawaii, Obama is a graduate of Columbia University and Harvard Law School, where he served as president of the Harvard Law Review. He was a community organizer in Chicago before earning his law degree. He worked as a civil rights attorney and taught constitutional law at University of Chicago Law School from 1992 to 2004. He served three terms representing the 13th District in the Illinois Senate from 1997 to 2004, running unsuccessfully for the United States House of Representatives in 2000.");
values.put(KEY_IMAGE, "R.drawable.obama.jpg");
db.insert(TABLE_MODERN, null, values); //inserted a new row into the database
db.close();
}
//Gets the answers based on the era nd level provided,
//db is database extension dont need to pass it
public Cursor getAnswer(String table, int level){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor;
//All one row of data
String[] projections = {KEY_QUESTION, KEY_ANSWER, KEY_HINT, KEY_INFO, KEY_IMAGE};
//Calling query method
//Pass table name, the projections(names of columns), selection (data argument), selection arguments, group rows
//filter by row groups, sort order, you can pass null for ones you dont want to enter
cursor = db.rawQuery("SELECT " + KEY_ANSWER + " FROM " + TABLE_MODERN + " WHERE " + KEY_ID + "=" + level, null);
db.close();
return cursor;
}
/*
public Cursor getKeyHint(String era, int level{
SQLiteDatabase db = getReadableDatabase();
}
public Cursor getKeyQuestion(String era, int level{
}
public Cursor getKeyInfo(String era, int level{
}
public Cursor getKeyInfo(String era, int level{
}
*/}
I made the database from watching videos and reading documentation, but I have no clue how to actually "use" it. Thank you for reading, hope you can help.
I would recommend you to learn some basic SQL queries. Find some lessons like here. It shouldn't take you more than an hour or two to get the hang of it.
For your code specifically, the getAnswer() is good, it generates a valid query to access the database. You never actually use this method anywhere though. Put it in your MainActivity, probably in some onClick() method where the user asks for the answer to the question. I don't think you have started implementing this yet.
I have used LogCat to determine the problem line.
The SQL String I am trying to execute in onCreate is..
CREATE TABLE Routines(_id integer primary key autoincrement, json TEXT);
When it tries to execute this, the problem occurs.
This may well be whats causing the NullPointerException. If you can't see anything wrong with that, please read on for a bit more background.
This database has not been created yet, I keep getting a NullpointerException, I have compared this to previous SQLite code and the problem is proving evasive.
However, I mention this as it still has to go through the onCreate method. I create a new DatabaseOpenHelper (extending SQliteOpenHelper) in my main code and call the helper's open() method as seen below.
public void open() throws SQLException
{
ssDatabase = databaseOpenHelper.getWritableDatabase();
}
If I am not mistaken, as my database has not been created (I made sure of that through uninstalling it prior). The onCreate SQLiteHelper is invoked when that open() method is called.
This is the code where I call that open method.
try
{
dbConnector = new DatabaseConnector (this);
debug = "2 ";
// This on first start will invoke the database onCreate method - throws SQLException
dbConnector.open(); /* PROBLEM LINE */
debug = "3 ";
}
catch (Exception e)
{
textView1.setText(debug + e.toString());
}
And this is the code containing my DatabaseOpenHelper and onCreate method
private class DatabaseOpenHelper extends SQLiteOpenHelper
{
public DatabaseOpenHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
Log.i(TAG, "Constructor");
}
// On initial creation of database
#Override
public void onCreate(SQLiteDatabase db)
{
Log.i(TAG, "Before SQL command");
String sqlCreateCommand = "CREATE TABLE Routines"
+ "(_id integer primary key autoincrement, "
+ "json TEXT);";
Log.i(TAG, sqlCreateCommand);
// I believe this to be the PROBLEM LINE
ssDatabase.execSQL(sqlCreateCommand);
Log.i(TAG, "Jab done");
}
// On upgrade - currently do nothing
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{}
}
Thanks for the help!
seems like i dont have the prvilege to just post a comment. One question: ssDatabase.execSQL(sqlCreateCommand); --> shouldn't this be db.execSQL(sqlCreateCommand);
since the parameter is SQLiteDatabase db. Secondly you use _id. is this index not created by default ? Nevermind if this has nothing to do with it. This were just my thoghts about it. :)
Hey
I'm building an Android app that contains a database.
My question is how can I know whether the app was updated?
I mean, I know the onUpgrade method is called when the DATABASE_VERSION from -
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
this.myContext = context;
}
is lower than the version of the app, but how do I increment it after the update, so the app won't update itself all the time?
You don't need to take care of keeping track of the version number. After onUpgrade() has been called, android takes care of all this stuff automatically. onUpgrade() will automatically be called when the next update is due (i.e. you increased DATABASE_VERSION once again).
To be even more clear: Just keep a static final int DATABASE_VERSION field, which you increase at development time, everytime you change something essential on the database structure.
You create a class that extends SQLLiteOpenHelper which basically looks like this:
public class ContentDatabase extends SQLiteOpenHelper {
// Whenever you change the DB structure, increment DATABASE_VERSION (it starts from 1, so your first upgrade should be 2)
// - note it's only used for upgrades; if it's a new install, onUpgrade won't be called and everything is done by onCreate instead
private static final int DATABASE_VERSION = 6;
public ContentDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
// Code to create the most recent version of your database
// i.e. CREATE TABLE xxx (....)
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Code to update an existing database structure to the most recent
// version.
if (oldVersion < 2) {
// do something to upgrade the DB to version 2
}
if (oldVersion < 3) {
// do something to upgrade the DB to version 3
}
if (oldVersion < 6) {
// Let's assume you added a new table in v4, and then added a field to that new table in v6
if (oldVersion < 4) {
// add the v6 version of the new table to the DB
}
else {
// add the new field to the existing v4 table in the DB
}
}
}
}
Everytime you need to change the structure of the table (i.e. add aditional columns or tables) you increase the DATABASE_VERSION variable by one and write code accordingly for the onCreate() and onUpdate() methods. These methods are called automatically by android.
Consider using SharedPreferences in the application context, you can keep track of lastVersion in there and your application will check it onCreate() to see if lastVersion matches the version of this application.
It is persistent between updates but not between installs.
you can make it so version 0 equates to not having it which you require you to setup the new database. By using SharedPreference mPref = getSharedPreference(String,int)
You can then have code like
if(mPref.getInt("DB_VERSION", 0) == 0 ) {
no db yet so create one
} else { db is there,
if (mPref.getInt("DB_VERSION",0) != DATABASE_VERSION) {
do some special update stuff here
}
}