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.");
}
}
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) {
}
}
i have an app that has database inside the assets folder.
But i want to get the database from my sdcard not from the assets, as i'm new to this, i did these steps :
I downloaded the new DB and put it inside the custom folder.
I changed the DB_PATH from
DB_PATH = "/data/data/com.test.project/databases/";
to
DB_PATH = Environment.getExternalStorageDirectory() + "/my_custom_folder/";
but when i try to access it, the app crashes , and that DB got deleted from my phone, any help ?
Here is the code to load it :
public class book_DB_Helper extends SQLiteOpenHelper {
public final static int DB_VERSION = 1;
private final static String DB_NAME = "my_book";
public static SQLiteDatabase db;
//// --- the old PATH 'from assets folder
//private static String DB_PATH = "/data/data/com.test.project/databases/";
//// --- my new path in the sdcard
private static String DB_PATH = Environment.getExternalStorageDirectory() + "/my_folder/";
private final Context context;
private final String TABLE_NAME = "tbl_recipes";
private final String ID = "id";
private final String RECIPE_NAME = "recipe_name";
private final String IMAGE_PREVIEW = "image_preview";
private final String COOK_TIME = "cook_time";
public my_book_DB_Helper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
SQLiteDatabase db_Read = null;
if (dbExist) {
//do nothing - database already exist
deleteDataBase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
} else {
db_Read = this.getReadableDatabase();
db_Read.close();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
private void deleteDataBase() {
File dbFile = new File(DB_PATH + DB_NAME);
dbFile.delete();
}
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);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
#Override
public void close() {
db.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public ArrayList<ArrayList<Object>> getAllData(String RecipeNameKeyword) {
ArrayList<ArrayList<Object>> dataArrays = new ArrayList<ArrayList<Object>>();
Cursor cursor = null;
if (RecipeNameKeyword.equals("")) {
try {
cursor = db.query(
TABLE_NAME,
new String[]{ID, RECIPE_NAME, IMAGE_PREVIEW, COOK_TIME},
null, null, null, null, null);
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
do {
ArrayList<Object> dataList = new ArrayList<Object>();
dataList.add(cursor.getLong(0));
dataList.add(cursor.getString(1));
dataList.add(cursor.getString(2));
dataList.add(cursor.getString(3));
dataArrays.add(dataList);
}
while (cursor.moveToNext());
}
cursor.close();
} catch (SQLException e) {
Log.e("DB Error", e.toString());
e.printStackTrace();
}
} else {
try {
cursor = db.query(
TABLE_NAME,
new String[]{ID, RECIPE_NAME, IMAGE_PREVIEW, COOK_TIME},
RECIPE_NAME + " LIKE '%" + RecipeNameKeyword + "%'",
null, null, null, null);
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
do {
ArrayList<Object> dataList = new ArrayList<Object>();
dataList.add(cursor.getLong(0));
dataList.add(cursor.getString(1));
dataList.add(cursor.getString(2));
dataList.add(cursor.getString(3));
dataArrays.add(dataList);
}
while (cursor.moveToNext());
}
cursor.close();
} catch (SQLException e) {
Log.e("DB Error", e.toString());
e.printStackTrace();
}
}
return dataArrays;
}
public ArrayList<Object> getDetail(long id) {
ArrayList<Object> rowArray = new ArrayList<Object>();
Cursor cursor;
try {
String SUMMARY = "summary";
String PREP_TIME = "prepare_time";
String SERVES = "serves";
String INGREDIENTS = "ingredients";
String DIRECTIONS = "directions";
cursor = db.query(
TABLE_NAME,
new String[]{RECIPE_NAME, IMAGE_PREVIEW, COOK_TIME},
ID + "=" + id,
null, null, null, null, null);
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
do {
rowArray.add(cursor.getString(0));
rowArray.add(cursor.getString(1));
rowArray.add(cursor.getString(2));
rowArray.add(cursor.getString(3));
rowArray.add(cursor.getString(4));
rowArray.add(cursor.getString(5));
rowArray.add(cursor.getString(6));
rowArray.add(cursor.getString(7));
}
while (cursor.moveToNext());
}
cursor.close();
} catch (SQLException e) {
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
return rowArray;
}
}
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'
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.