2016-06-23 3 views
2

私は手動で作成したデータベース(.sqlite3)を持っています。私は私がなぜわからないんだけど、それは私に「ErrorCopyingdatabase」エラーを投げ続け、このquestion/answerAndroidはデータベースをアセットフォルダにコピーできません

に基づいて自分のアプリケーションに組み込むことを試みました。私はエミュレータを使ってテストしています。

私のデータベースをアプリケーションに組み込むためのコードです。私は2つのクラスを作った。

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

    public DataBaseHelper(Context context) 
    { 
     super(context, DB_NAME, null, 1); // 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 the database does not exist, 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(); 
    } 
} 

と...

public class TestAdapter { 
    protected static final String TAG = "DataAdapter"; 

    private final Context mContext; 
    private SQLiteDatabase mDb; 
    private DataBaseHelper mDbHelper; 

    public TestAdapter(Context context){ 
     this.mContext = context; 
     mDbHelper = new DataBaseHelper(mContext); 
    } 

    public TestAdapter createDatabase() throws SQLException{ 
     try { 
      mDbHelper.createDataBase(); 
     } 
     catch (IOException mIOException) 
     { 
      Log.e(TAG, mIOException.toString() + " UnableToCreateDatabase"); 
      throw new Error("UnableToCreateDatabase"); 
     } 
     return this; 
    } 

    public TestAdapter open() throws SQLException{ 
     try{ 
      mDbHelper.openDataBase(); 
      mDbHelper.close(); 
      mDb = mDbHelper.getReadableDatabase(); 
     } 
     catch (SQLException mSQLException){ 
      Log.e(TAG, "open >>"+ mSQLException.toString()); 
      throw mSQLException; 
     } 
     return this; 
    } 

    public void close(){ 
     mDbHelper.close(); 
    } 

    public ArrayList getTestData(int numberId){ 
     try { 
      ArrayList<String> details = new ArrayList<>(); 
      String name = ""; 
      String summary = ""; 
      String trivia = ""; 
      String abilities = ""; 
      Cursor mcur = mDb.rawQuery("SELECT Name FROM CharactersInfo WHERE _id=?", new String[]{numberId + ""}); 

      if (mcur.getCount() > 0) { 

       mcur.moveToFirst(); 
       name = mcur.getString(mcur.getColumnIndex("Name")); 
       summary = mcur.getString(mcur.getColumnIndex("Summary")); 
       trivia = mcur.getString(mcur.getColumnIndex("Trivia")); 
       abilities = mcur.getString(mcur.getColumnIndex("Abilities")); 


       details.add(name); 
       details.add(summary); 
       details.add(trivia); 
       details.add(abilities); 

      } 
      return details; 
     } catch (SQLException mSQLException) { 
      Log.e(TAG, "getTestData >>"+ mSQLException.toString()); 
      throw mSQLException; 
     } 
    } 
} 

私は私が言ったように、データベースをコピーすることができないよう ...私のニーズに合うように、コードを少し変更してみました、と私を送信し続けますErrorCopyingDatabaseエラー(最初のコードスニペット)。

このため、その後の試行では、クエリを実行するデータベースが最初にありません。

ところで、私はフラグメントのボタンからすべてをアクティブにします。

TestAdapter mDbHelper = new TestAdapter(getActivity()); 
mDbHelper.createDatabase(); 
mDbHelper.open(); 
ArrayList cursor = mDbHelper.getTestData(indentifier); 
TextView textView = (TextView) view.findViewById(R.id.character_trivia); 
String string = "" + cursor; 
textView.setText(string); 

mDbHelper.close(); 

私は少し調べましたが、本当に助けに感謝します。

EDIT:あなたはより良いAndroidSqliteAssetHelperを使用する必要があり、あなたの事前に定義されたデータとデータベースを使用するために

FATAL EXCEPTION: main 
Process: com.lumberjackapps.dailyhero, PID: 2395 
java.lang.Error: ErrorCopyingDataBase 
    at com.lumberjackapps.dailyhero.DataBaseHelper.createDataBase(DataBaseHelper.java:57) 
    at com.lumberjackapps.dailyhero.TestAdapter.createDatabase(TestAdapter.java:34) 
    at com.lumberjackapps.dailyhero.CharacterInfo$1.onClick(CharacterInfo.java:46) 
    at android.view.View.performClick(View.java:5198) 
    at android.view.View$PerformClick.run(View.java:21147) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
E/EGL_emulation: tid 955: eglCreateSyncKHR(1294): error 0x3004 (EGL_BAD_ATTRIBUTE) 
E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property 
E/Surface: getSlotFromBufferLocked: unknown buffer: 0xa15d3f80 
E/audio_hw_generic: Error opening input stream format 1, channel_mask 0010, sample_rate 16000 
+0

copyDataBaseはlogcat – W0rmH0le

+0

を共有...例外をスローしていますが、マニフェストに適切な権限を設定することがありますか? –

+0

logcatを共有してください。 – aditya

答えて

1

: ここでは、後半のエントリのために残念logcat(唯一の致命的な例外一部)、です。

Androidのヘルパークラスアプリケーションの生のアセットファイルを使用して、データベースの作成およびバージョン 管理を管理する:ここで

はそれの一部は、READMEです。

このクラスは、( データで予め取り込まれてもよい)は、既存のSQLiteデータベースとそれらのAndroid アプリを出荷すると、その初期の作成を管理するための簡単な方法を開発者に提供し、任意のアップグレードは、その後のバージョンのリリースで を必要としました。

それのContentProvider実装が最初の使用まで、データベースをアップグレードする開口と を延期するため 効率的な方法を提供し、SQLiteOpenHelperの拡張機能として実装されます。

にonCreate()メソッドとonUpgrade()メソッドを実装するのではなく、適切な名前のファイルアセットをプロジェクトのassetsディレクトリに追加するだけです。 これらには、作成用の初期SQLiteデータベースファイルと、オプションで任意のSQLアップグレードスクリプト が含まれます。

0

少し変更することをお勧めします。copyDataBase()また、私はthrows傷を取り除いた。この方法で、logcatは、より良い情報を印刷します:

private void copyDataBase() { 
    Log.v(TAG, "copyDataBase() - start"); 
    try { 
     InputStream myInput = mContext.getAssets().open(DATABASE_NAME); 

     // I think this line should solve your problem... Maybe, you are not setting the output file properly... Try like below: 
     OutputStream myOutput = new FileOutputStream(mContext.getDatabasePath(DATABASE_NAME)); 

     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myInput.read(buffer))>0){ 
      myOutput.write(buffer, 0, length); 
     } 

     myOutput.flush(); 
     myOutput.close(); 
     myInput.close(); 

    } catch (Exception e) { 
     Log.e(TAG, "copyDataBase(): " + e); 

     StackTraceElement trace[] = e.getStackTrace(); 
     for(StackTraceElement element : trace) { 
      Log.e(TAG, element.toString()); 

     } 
    } 
    Log.v(TAG, "copyDataBase() - end"); 
} 

次に、あなたがこの削除することができます:

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

そして、この変更:これに

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

を:

if(!mDataBaseExist) { 
    this.getReadableDatabase(); 
    this.close(); 
    copyDataBase(); 
    Log.e(TAG, "createDatabase database created"); 
} 
関連する問題