Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying SQLite database from assets folder issue

Can someone point me in the right direction. I am able to create an empty database in /data/data/mypacket/databases but i cant copy my database from the assets folder? Any suggestions? Thanks for the help

CODE:

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import android.content.Context; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.util.Log; 

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 = "";  
private static String DB_NAME ="MyDatabase";// Database name 
private SQLiteDatabase mDataBase;  
private final Context mContext; 

public DataBaseHelper(Context context)  
{ 
    super(context, DB_NAME, null, 1);// 1? its Database Version 
    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 arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    } 

} 

LOGCAT:

 09-03 02:22:32.459: E/AndroidRuntime(19099): FATAL EXCEPTION: main
    09-03 02:22:32.459: E/AndroidRuntime(19099): java.lang.IllegalStateException: Could not execute method of the activity
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.view.View$1.onClick(View.java:3597)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.view.View.performClick(View.java:4202)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.view.View$PerformClick.run(View.java:17340)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.os.Handler.handleCallback(Handler.java:725)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.os.Handler.dispatchMessage(Handler.java:92)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.os.Looper.loop(Looper.java:137)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.app.ActivityThread.main(ActivityThread.java:5039)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at java.lang.reflect.Method.invokeNative(Native Method)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at java.lang.reflect.Method.invoke(Method.java:511)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at dalvik.system.NativeStart.main(Native Method)
    09-03 02:22:32.459: E/AndroidRuntime(19099): Caused by: java.lang.reflect.InvocationTargetException
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at java.lang.reflect.Method.invokeNative(Native Method)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at java.lang.reflect.Method.invoke(Method.java:511)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at android.view.View$1.onClick(View.java:3592)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    ... 11 more
    09-03 02:22:32.459: E/AndroidRuntime(19099): Caused by: java.lang.Error: Error copying database
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at com.petermihaylov.scjajavaexamquestions.DataBaseHelper.createDataBase(DataBaseHelper.java:56)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at com.petermihaylov.scjajavaexamquestions.TestAdapter.createDatabase(TestAdapter.java:25)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    at com.petermihaylov.scjajavaexamquestions.TrueAndFalse.testasd(TrueAndFalse.java:25)
    09-03 02:22:32.459: E/AndroidRuntime(19099):    ... 14 more
like image 757
FC_Inter_Fan Avatar asked Jul 12 '26 01:07

FC_Inter_Fan


2 Answers

A few pointers:

  • Check that the file `DB_NAME` is present in the app's "assets" folder (instead of in the "raw" folder).
  • If the asset file extension is ".gz", the extension will be removed.
  • The asset file should not be bigger than 1MB. If that's the case, try to compress it and decompress it to the database folder.
  • Check that the path to `outFileName` exists before copying the file (i.e. `new File(outFileName).getParentFile().mkdirs();`
  • Check the `DB_PATH` is properly built depending on the API version.

As explained in this answer:

if(android.os.Build.VERSION.SDK_INT >= 4.2){
    DB_PATH = context.getApplicationInfo().dataDir + "/databases/";         
}
else
{
    DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}

Additionally, don't forget to create the android_metadata table, as explained in this answer.

like image 108
rbarriuso Avatar answered Jul 13 '26 16:07

rbarriuso


The solution to my problem is this:

Since Android Studio uses the new Gradle-based build system, you should be putting assets/ inside of the source sets example myproject/src/main/assets/.

I created my own assets folder and put it where Eclipse usually puts it... which caused all these problems for me.

like image 29
FC_Inter_Fan Avatar answered Jul 13 '26 14:07

FC_Inter_Fan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!