从资产文件夹问题复制SQLite数据库

时间:2013-09-03 04:22:49

标签: android android-sqlite

有人能指出我正确的方向吗?我能够在/ data / data / mypacket / databases中创建一个空数据库,但我无法从assets文件夹中复制我的数据库?有什么建议?谢谢你的帮助

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

3 个答案:

答案 0 :(得分:2)

一些指示:

  • 检查应用程序的“assets”文件夹(而不是“raw”文件夹)中是否存在“DB_NAME”文件。
  • 如果资产文件扩展名为“.gz”,则会删除扩展程序。
  • 资产文件不应大于1MB。如果是这种情况,请尝试压缩它并将其解压缩到数据库文件夹。
  • 在复制文件之前检查`outFileName`的路径是否存在(即`new File(outFileName).getParentFile()。mkdirs();`
  • 根据API版本检查`DB_PATH`是否正确构建。

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/";
}

另外,请不要忘记创建android_metadata表,如this answer中所述。

答案 1 :(得分:1)

我的问题的解决方案是:

由于Android Studio使用新的基于Gradle的构建系统,因此您应该将资源/放在源集内部示例myproject / src / main / assets /。

我创建了自己的资源文件夹并将其放在Eclipse通常放置的位置...这给我带来了所有这些问题。

答案 2 :(得分:0)

这是从资产数据库文件夹复制到外部存储文件夹的一些代码。 文件需要位于assets \ databases文件夹下。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.media.MediaScannerConnection;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;

public class Options extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.options);
    }            

    public void backupDatabase(View v) throws IOException {                 
        if (Environment.getExternalStorageState() != null)
        {
            File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyApp");
            if (dir.exists()) {
                //dir.delete();
            }
            else {
                dir.mkdir();
            }

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

            String toPath = dir.getAbsolutePath() + "/wl.db";

            fileCopy(new File(fromPath), new File(toPath));

            //This is to refresh the folders in Windows USB conn.
            MediaScannerConnection.scanFile(this, new String[] { Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyApp" }, null, null);         
            MediaScannerConnection.scanFile(this, new String[] { toPath }, null, null);         
        }                   
    }

    public void fileCopy(File src, File dst) throws IOException {
        InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);

        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }
}