I have an app already in google store.I am using a builtin database having 3 tables and copying it on first launch of app. Now i want to do upgrade to the app and add another table. Below is my code.
public DataBaseHelper(Context context)
{
super(context, DB_NAME, null, 1);
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
this.mContext = context;
}
public void createDataBase() throws IOException
{
//If database not exists copy it from the assets
boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}
//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
#Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}
#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");
String sql = "CREATE TABLE IF NOT EXISTS CKRecordings (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT , filepath TEXT , creationDate TEXT)";
db.execSQL(sql);
db.execSQL("DROP TABLE IF EXISTS data");
onCreate(db);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
I want to ask few questions. The above code is not upgrading.
Now if i am new user of the app, do i have to edit the old database and make another CKRecording table and replacing it with current database placed in asset or above code will work for new users too?
super(context, DB_NAME, null, 1);
in this statement last argument is database version.. set it to 2 for new updated APK. so existing user can have newly added table Or Column.
on updated apk onUpgrade will call. and there you can copy database from asset. but than exisiting user will have loss of data.. so best option is to add table dynamically in database.
Related
I am developing an app that uses sqlite database, and I am storing them in the assets folder.
I need the files to have descriptive numbers(like db_42_2_43_3.sqlite) but they don't work, I understood that this limitation is present with the files inside the res/raw folder (file names without capital letters, without numbers greater than 9, etc) but these files are not there, They are in the assets folder.
Note: the app works with filenames without numbers greater than 9 (as if the file would be in the res/raw folder)
Any suggestion? This is my SqlLiteDbHelper class
public class SqlLiteDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
public String DATABASE_NAME;
private static final String DB_PATH_SUFFIX = "/databases/";
static Context ctx;
public SqlLiteDbHelper(Context context, String db_filename) {
super(context, db_filename, null, DATABASE_VERSION);
ctx = context;
DATABASE_NAME = db_filename;
}
public ArrayList<Poi> getDetails(double lat, double lng, double radius) {//radius in meters
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<Poi> poiList = new ArrayList<>();
String query = "SELECT * FROM puentes";
Cursor cursor = db.rawQuery(query, null);
if (cursor != null) {
while (cursor.moveToNext()) {
Poi cont = new Poi(cursor.getLong(0), cursor.getLong(1), cursor.getDouble(2), cursor.getDouble(3), cursor.getString(4), cursor.getString(6));
poiList.add(cont);
}
cursor.close();
db.close();
}
return poiList;
}
public void CopyDataBaseFromAsset() throws IOException {
InputStream myInput = ctx.getAssets().open(DB_PATH_SUFFIX + DATABASE_NAME);
String outFileName = getDatabasePath();
File f = new File(ctx.getApplicationInfo().dataDir + DB_PATH_SUFFIX);
if (!f.exists())
f.mkdir();
OutputStream myOutput = new FileOutputStream(outFileName);
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();
}
private String getDatabasePath() {
return ctx.getApplicationInfo().dataDir + DB_PATH_SUFFIX + DATABASE_NAME;
}
public SQLiteDatabase openDataBase() throws SQLException {
File dbFile = ctx.getDatabasePath(DATABASE_NAME);
if (!dbFile.exists()) {
try {
CopyDataBaseFromAsset();
System.out.println("Copying sucess from Assets folder");
} catch (IOException e) {
throw new RuntimeException("Error creating source database", e);
}
}
return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.CREATE_IF_NECESSARY);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
yoh...
I was trying to retrieve data from my external database in assets
but when I run the app, seems like it created another database in /data/data/packagename/databases/ :-( not the external database from assets I inserted and causing an error(Unfortunately, App has stopped). Here's my Code:
ingameinterface .java*
public class ingameinterface extends Activity {
DBHelper dbhelper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ingameinterface);
String[] from = new String[] { "CtrlNo", "Prima", "Key_Word", "Val" };
int[] to = new int[] { R.id.itmCc1, R.id.itmCc2, R.id.itemCc3, R.id.itemCc4};
dbhelper = new DBHelper(this);
try {
dbhelper.createDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Cursor c = dbhelper.getData();
if (c.getCount() == 0) {
showmessage("Error!", "Nothing found.");
return;
}
StringBuffer buff = new StringBuffer();
while (c.moveToNext()) {
buff.append("Controlnum: " + c.getString(0) + "\n");
buff.append("Prima: " + c.getString(1) + "\n");
buff.append("Word: " + c.getString(2) + "\n");
buff.append("Value: " + c.getString(3) + "\n\n");
}
showmessage("Data", buff.toString());
}
public void showmessage(String title, String Message){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(Message);
}
}
and
DBHelper.Java*
public class DBHelper extends SQLiteOpenHelper {
private static String DB_NAME = "db_vocabulary";
private SQLiteDatabase db;
private final Context context;
private String DB_PATH;
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
this.context = context;
DB_PATH = "/data/data/" + context.getPackageName() + "/" + "databases/";
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
// throw new Error("Error copying database");
}
}
}
private boolean checkDataBase() {
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
private void copyDataBase() throws IOException {
InputStream myInput = context.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);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public Cursor getData() {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
Cursor c = db.rawQuery("SELECT * FROM TblWords WHERE Prima = 1", null);
return c;
}
#Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
use this in your DBHelper.java file:
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table if not exists "+TABLE_NAME+"(PHONENUMBER VARCHAR,NAME VARCHAR)");
}
so that it will wont create another table if already that table exits in database.
I'm using a premade database and I seem to be getting an error when I try to update a row. The exact error from logcat is: (1) no such table: AUD. Heres what my dbhelper class looks like:
public class DataBaseHelper extends SQLiteOpenHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "/data/data/com.example.simplecurrency3/databases/";
private static String DB_NAME ="Currencies";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 2);// 1? its Database Version
if(android.os.Build.VERSION.SDK_INT >= 17){
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
}
else
{
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
this.mContext = context;
}
public void createDataBase() throws IOException {
//If database not exists copy it from the assets
boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}
//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
#Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.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
}
}
And when I try to update a row:
Context context = getActivity().getApplicationContext();
DataBaseHelper dbHelper = new DataBaseHelper(context);
dbHelper.openDataBase();
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("UPDATE AUD SET AUD = 2.0")
You have never called createDataBase() method! You can put it into onCreate() method.
Good luck
Instead of updating a row, first check whether the table really exists by using the following query.
SELECT name FROM sqlite_master WHERE type='table'
This question already has answers here:
Copy Database from assets folder in unrooted device
(6 answers)
copy database from assets to databases folder [duplicate]
(1 answer)
Closed 9 years ago.
I want to copy my sample database from my asset folder to the /data/data/packagename/databases/ directory to use it later in the application.
I have viewed many tutorial and other solution like here( Copy Database from assets folder in unrooted device) and here (copy database from assets to databases folder) but it not work for me. I have no error but the database that has been copied is empty. Is there something wrong with my coding?
Here is my coding for copying the database.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_dictionary_type);
File dbfile=new File("data/data/com.example.myidictionary/databases","DefinitionDB");
if (!dbfile.exists()) {
try {
copyDatabase(dbfile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Sample data is being copied", Toast.LENGTH_LONG).show();
}
else
Toast.makeText(getApplicationContext(), "Database Exist", Toast.LENGTH_LONG).show();
}
private void copyDatabase(File dbFile) throws IOException
{
InputStream is = this.getAssets().open("DefinitionDB");
OutputStream os = new FileOutputStream(dbFile);
byte[] buffer = new byte[1024];
while (is.read(buffer) > 0)
{
os.write(buffer);
}
os.flush();
os.close();
is.close();
}
Try below code and let me know whether is it working properly?
public class DataBaseWrapper extends SQLiteOpenHelper
{
private static String TAG = DataBaseWrapper.class.getName();
private String DB_PATH; //= "/data/data/com.example.yourproject/databases/";
private static String DB_NAME = "Database.sqlite";
private SQLiteDatabase myDataBase = null;
private final Context myContext;
public DataBaseWrapper(Context context)
{
super(context, DB_NAME, null, 1);
this.myContext = context;
DB_PATH="/data/data/" + context.getPackageName() + "/" + "databases/";
Log.v("log_tag", "DBPath: " + DB_PATH);
// File f=getDatabasePath(DB_NAME);
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
Log.v("log_tag", "database does exist");
}else{
Log.v("log_tag", "database does not exist");
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
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();
}
private boolean checkDataBase(){
File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
myDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return myDataBase != null;
}
#Override
public synchronized void close()
{
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db)
{
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.v(TAG, "Upgrading database, this will drop database and recreate.");
}
}
In my Android application I created a database using sqlite browser and cpoied it into asset folder. then I created a table named EMPerson.
I need to add user defined data(user can insert details such as personName,date_of_birth,age,gender & bloodGrp) into this EMPerson table when the user click save button.
My DBHelper class is like this.
package my.easymedi.db;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import my.easymedi.entity.Person;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;
public class DBHelper extends SQLiteOpenHelper {
/*Database attributes - the Android's default system path for your application database*/
private static final String pkg = "my.easymedi.controller";
private static String DB_PATH = "/data/data/" + pkg + "/databases/";
private static String DB_NAME = "EasyMediInfo.jpeg";
private static final int DB_VERSION = 1;
private final Context myContext;
private SQLiteDatabase myDatabase;
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.myContext = context;
}
public void createDataBase() {
boolean dbExist = checkDataBase();
if (dbExist) {
// do nothing - database already exist
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
Toast.makeText(myContext, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("CREATE_DB", e.getMessage());
}
}
}
private void copyDataBase() throws IOException {
InputStream databaseInput = null;
String outFileName = DB_PATH + DB_NAME; //path to copy the database
OutputStream databaseOutput = new FileOutputStream(outFileName); //open the empty db as an output stream
databaseInput = myContext.getAssets().open(DB_NAME);
byte[] buffer = new byte[512];
int length = databaseInput.read(buffer);
while(length > 0){
databaseOutput.write(buffer, 0, length);
databaseOutput.flush();
}
databaseOutput.flush();
databaseInput.close();
databaseOutput.close();
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
} catch (SQLiteException e) {
Toast.makeText(myContext, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("Check_DB", e.getMessage());
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
public void openDatabase() {
String myPath = DB_PATH + DB_NAME;
myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
}
public void closeDatabase() {
if(myDatabase != null){
myDatabase.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
}
public boolean insertIntoDatabase(Person person) {
String query = "INSERT INTO EMPerson (COLUMN_PERSON_NAME, COLUMN_DOB , COLUMN_AGE, COLUMN_GENDER, COLUMN_BLOODGRP) "
+ " VALUES ('" + person.getName() + "', '" + person.getDate_of_birth() + "', '" + person.getAge() + "', '" + person.getGender() + "', '" + person.getBloodGrp() + "')";
try {
myDatabase.execSQL(query);
return true;
} catch (Exception e) {
return false;
}
}
}
And this is my AddNewPerson class segment.
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnSave:
personName = etName.getText().toString();
date_of_birth = tvDOB.getText().toString();
age = tvAge.getText().toString();
int selected_rb_ID = genderGrp.getCheckedRadioButtonId();
RadioButton rb = (RadioButton) findViewById(selected_rb_ID);
gender = rb.getText().toString();
bloodGrp = spiBloodGrp.getSelectedItem().toString();
Person person = new Person();
person.setName(personName);
person.setDate_of_birth(date_of_birth);
person.setAge(age);
person.setGender(gender);
person.setBloodGrp(bloodGrp);
//personArrayList.add(person);
DBHelper dbHelper = new DBHelper(this);
dbHelper.createDataBase();
dbHelper.openDatabase();
//SQLiteDatabase sqliteDatabase = dbHelper.getWritableDatabase();
boolean flag = dbHelper.insertIntoDatabase(person);
//long affectedColumnId = sqliteDatabase.insert(AndroidOpenDbHelper.TABLE_NAME_GPA, null, contentValues);
if(flag){
Toast.makeText(getApplicationContext(), "Values inserted", Toast.LENGTH_SHORT).show();
}
dbHelper.closeDatabase();
break;
When I run the application log cat says 'no such table:EMPerson'
Can anyone plz explain what's wrong with these codes.
Thanx in advance
There seem to be two problems:
Change the extension of your database to ".db" from ".jpeg" (just a suggestion for good coding practice)
It seems you do not properly initialize "mydatabase" variable in your code:
The line:
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
should be calling this.openDatabase(...)
Similarly, when your database doesn't exist you copy the database but doesn't initialize mydatabase again (you should call openDatabase again)
Also, you can then modify the function openDatabase as
public boolean openDatabase() {
String myPath = DB_PATH + DB_NAME;
myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return myDatabase!= null ? true : false;
}
Change the DB_NAME to EasyMediInfo.db in Assets
B/coz the extension of Database file is .db
private static String DB_NAME = "EasyMediInfo.db";
Edited:-
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.myContext = context;
if (android.os.Build.VERSION.SDK_INT >= 4.2) {
DB_PATH = myContext.getApplicationInfo().dataDir
+ "/databases/";
} else {
DB_PATH = "/data/data/" + myContext.getPackageName()
+ "/databases/";
}
}