2016-05-27 4 views
-2

Ich habe eine einfache Wörterbuch-App, die diese Datenbank-Handler-Klasse verwendet. (Ich habe gefüllt bereits die Datenbank DB Browser verwenden und es mit der App versenden)Warum App-Datenbank nicht auf Android-Gerät kopiert?

public class DictionaryDatabase extends SQLiteOpenHelper { 
    private static final String DB_NAME = "dict.db"; 
    private static String DB_PATH = "/data/data/com.dictshop.dict/databases/"; 
    private static final String TABLE_DICTIONARY = "dictionary"; 
    private static final String FIELD_WORD = "word"; 
    private static final String FIELD_DEFINITION = "definition"; 
    private static final int DATABASE_VERSION = 1; 
    private Context myContext; 


    DictionaryDatabase(Context context) { 
     super(context, DB_NAME, null, DATABASE_VERSION); 
     this.myContext = context; 
    } 


    public void crateDatabase() throws IOException { 
     boolean vtVarMi = isDatabaseExist(); 

     if (!vtVarMi) { 
      this.getReadableDatabase(); 

      try { 
       copyDataBase(); 
      } catch (IOException e) { 
       throw new Error("Error copying database"); 
      } 
     } 
    } 


    private boolean isDatabaseExist() { 
     SQLiteDatabase kontrol = null; 

     try { 
      String myPath = DB_PATH + DB_NAME; 
      kontrol = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

     } catch (SQLiteException e) { 
      kontrol = null; 
     } 

     if (kontrol != null) { 
      kontrol.close(); 
     } 
     return kontrol != null ? true : false; 
    } 



    private void copyDataBase() throws IOException { 

     // Open your local db as the input stream 
     InputStream myInput = myContext.getAssets().open(DB_NAME); 

     // Path to the just created empty db 
     String outFileName = DB_PATH + DB_NAME; 

     // Open the empty db as the output stream 
     OutputStream myOutput = new FileOutputStream(outFileName); 

     // transfer bytes from the inputfile to the outputfile 
     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(); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL("CREATE TABLE " + TABLE_DICTIONARY + 
       "(_id integer PRIMARY KEY," + 
       FIELD_WORD + " TEXT, " + 
       FIELD_DEFINITION + " TEXT);"); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     //Handle database upgrade as needed 
    } 

    public void saveRecord(String word, String definition) { 
     long id = findWordID(word); 
     if (id>0) { 
      updateRecord(id, word,definition); 
     } else { 
      addRecord(word,definition); 
     } 

    } 

    public long addRecord(String word, String definition) { 
     SQLiteDatabase db = getWritableDatabase(); 
     ContentValues values = new ContentValues(); 
     values.put(FIELD_WORD, word); 
     values.put(FIELD_DEFINITION, definition); 
     return db.insert(TABLE_DICTIONARY, null, values); 
    } 
    public int updateRecord(long id, String word, String definition) { 
     SQLiteDatabase db = getWritableDatabase(); 
     ContentValues values = new ContentValues(); 
     values.put("_id", id); 
     values.put(FIELD_WORD, word); 
     values.put(FIELD_DEFINITION, definition); 
     return db.update(TABLE_DICTIONARY, values, "_id = ?", 
       new String[]{String.valueOf(id)}); 
    } 
    public int deleteRecord(long id) { 
     SQLiteDatabase db = getWritableDatabase(); 
     return db.delete(TABLE_DICTIONARY, "_id = ?", new 
       String[]{String.valueOf(id)}); 
    } 

    public long findWordID(String word) { 
     long returnVal = -1; 
     SQLiteDatabase db = getReadableDatabase(); 
     Cursor cursor = db.rawQuery(
       "SELECT _id FROM " + TABLE_DICTIONARY + 
         " WHERE " + FIELD_WORD + " = ?", new String[]{word}); 
     Log.i("findWordID","getCount()="+cursor.getCount()); 
     if (cursor.getCount() == 1) { 
      cursor.moveToFirst(); 
      returnVal = cursor.getInt(0); 
     } 
     return returnVal; 
    } 


    public String getWord(long id) { 
     String returnVal = ""; 
     SQLiteDatabase db = getReadableDatabase(); 
     Cursor cursor = db.rawQuery(
       "SELECT word FROM " + TABLE_DICTIONARY + 
         " WHERE _id = ?", new String[]{String.valueOf(id)}); 
     if (cursor.getCount() == 1) { 
      cursor.moveToFirst(); 
      returnVal = cursor.getString(0); 
     } 
     return returnVal; 
    } 


    public String getDefinition(long id) { 
     String returnVal = ""; 
     SQLiteDatabase db = getReadableDatabase(); 
     Cursor cursor = db.rawQuery(
       "SELECT definition FROM " + TABLE_DICTIONARY + 
         " WHERE _id = ?", new String[]{String.valueOf(id)}); 
     if (cursor.getCount() == 1) { 
      cursor.moveToFirst(); 
      returnVal = cursor.getString(0); 
     } 
     return returnVal; 
    } 


    public Cursor getWordList() { 
     SQLiteDatabase db = getReadableDatabase(); 
     String query = "SELECT _id, " + FIELD_WORD + 
       " FROM " + TABLE_DICTIONARY + " ORDER BY " + FIELD_WORD + 
       " ASC"; 
     return db.rawQuery(query, null); 
    } 
} 

ich dict.db zum Projekt gestoßen haben:

[email protected]:~$ ~/Android/Sdk/platform-tools/adb -s emulator-5554 push /home/me/Desktop/Dict/dict.db /data/data/com.dictshop.Dict/databases/dict.db 

und die App funktioniert auf Emulator Das heißt, ich sehe, dass die Daten angezeigt werden.

Wenn ich jedoch die App auf Geräten (eine verwurzelt, eine unbewurzelt) versuche, werden keine Daten angezeigt. Was könnte hier falsch sein?

Ich habe verschiedene Tricks ausprobiert, um diese Klasse zum Laufen zu bringen. Dies ist meine erste App und ich bin seit Tagen auf Lager. Also, schätze deine Hinweise wirklich.

UPDATE: hier ist die MainActivity, dass die Anwendungen auf die Datenbank verwendet:

public class MainActivity extends AppCompatActivity { 
    EditText mEditTextWord; 
    EditText mEditTextDefinition; 
    DictionaryDatabase mDB; 
    ListView mListView; 

     @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


      Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
      setSupportActionBar(toolbar); 
      // Get a support ActionBar corresponding to this toolbar 
      ActionBar ab = getSupportActionBar(); 
      // Enable the Up button 
      ab.setDisplayHomeAsUpEnabled(true); 

     mDB = new DictionaryDatabase(this); 




     mListView = (ListView)findViewById(R.id.listView); 
     mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View 
        view, int position, long id) { 
       String nextId = String.valueOf(id+1); 
       Intent intent = new Intent(view.getContext(),DetailActivity.class); 
       intent.putExtra("key" ,mDB.getWord(id)+""); 
       intent.putExtra("value",mDB.getDefinition(id)+""); 
       intent.putExtra("nextId",nextId+""); 
       startActivity(intent); 
      } 
     }); 

     mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 
      @Override 
      public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 
       Toast.makeText(MainActivity.this, 
         "Records deleted = " + mDB.deleteRecord(id), 
         Toast.LENGTH_SHORT).show(); 
       updateWordList(); 
       return true; 
      } 
     }); 
     updateWordList(); 

    } 


    private void saveRecord() { 
     mDB.saveRecord(mEditTextWord.getText().toString(), 
       mEditTextDefinition.getText().toString()); 
     mEditTextWord.setText(""); 
     mEditTextDefinition.setText(""); 
     updateWordList(); 
    } 

    private void updateWordList() { 
     SimpleCursorAdapter simpleCursorAdapter = new 
       SimpleCursorAdapter(this, 
       android.R.layout.simple_list_item_1, 
       mDB.getWordList(), 
       new String[]{"word"}, 
       new int[]{android.R.id.text1}, 
       0); 
     mListView.setAdapter(simpleCursorAdapter); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.share_app: 

       Intent sendIntent = new Intent(); 
       sendIntent.setAction(Intent.ACTION_SEND); 
       sendIntent.putExtra(Intent.EXTRA_TEXT, "this is the app"); 
       sendIntent.setType("text/plain"); 
       startActivity(sendIntent); 

       return true; 


      default: 
       // If we got here, the user's action was not recognized. 
       // Invoke the superclass to handle it. 
       return super.onOptionsItemSelected(item); 
     } 
    } 
} 
+0

Eine Fehlermeldung? logcat? – Nabin

+0

Es klingt nicht so, als hätten Sie dict.db auf die Geräte geschoben. Warum also erwartest du es dort zu sehen? –

+0

@NabinKhadka Ich sehe keinen Fehler in der Konsole. Nicht sicher, was Logcat ist. – narad

Antwort

0

Der SQLiteAssetHelper ist das, was Sie wollen. Gehen Sie wie folgt:

Fügen Sie die Abhängigkeit zu Ihrer App Moduls build.gradle Datei:

dependencies { 
    compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+' 
} 

Kopieren Sie die Datenbank in das Vermögen Verzeichnis, in einem Unterverzeichnis namens assets/databases. Also:

assets/databases/dict.db 

Erstellen Sie eine Klasse:

public class MyDatabase extends SQLiteAssetHelper { 

    private static final String DATABASE_NAME = "dict.db"; 
    private static final int DATABASE_VERSION = 1; 

    public MyDatabase(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 
} 

Zum Vergleich: https://github.com/jgilfelt/android-sqlite-asset-helper

+0

Ich habe kurz 'sqliteassethelper' versucht. Es hat meine App kaputt gemacht, also habe ich beschlossen, mich davon fern zu halten.IMHO, es ist ein extra Aufwand statt eine Lösung. Aber wenn Sie es um meine vorhandene Klasse wickeln könnten, werde ich es gerne ausprobieren. – narad

+0

Ich sehe, gut, eine andere vorgeschlagene Lösung ist, dass Sie Ihre vorbelegte DB in den Ordner Assets platzieren und dann in das reguläre Datenbankverzeichnis kopieren. Siehe [dies] (http://blog.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/). In der Tat scheint Ihr Code ihnen sehr ähnlich zu sein, jedoch haben Sie 'createDatabase()' nie in 'onCreate()' aufgerufen. Versuch das. –

+0

Richtig, aber ich weiß nicht, wie ich crateDatabase() in meiner MainActivity aufrufen soll. Ich habe verschiedene Dinge ausprobiert, aber immer Fehler bekommen. Kannst du bitte darüber helfen? – narad

0

Dies ist Beispiel SQLite

public class SqliteHelper extends SQLiteOpenHelper { 

public static String DB_PATH = "/data/data/com.dictshop.dict/databases/"; 
private static String DB_NAME = "dict.db"; 
private final Context context; 

public SqliteHelper(Context context) { 
    super(context, DB_NAME, null, 1); 
    this.context = context; 
} 

/** 
* copy database from assets to the device if not existed 
**/ 
public boolean isCreatedDatabase() throws IOException { 
    // Default is database have data 
    boolean result = true; 
    // check data 
    if (!checkExistDataBase()) { 
     this.getReadableDatabase(); 
     try { 
      copyDataBase(); 
      result = false; 
     } catch (Exception e) { 
      throw new Error("Error copying database"); 
     } 

    } 
    return result; 
} 


/** 
* check database exist on the device? 
*/ 
private boolean checkExistDataBase() { 

    try { 
     String myPath = DB_PATH + DB_NAME; 
     File fileDB = new File(myPath); 
     if (fileDB.exists()) { 
      return true; 
     } else 
      return false; 
    } catch (Exception e) { 
     return false; 
    } 
} 

/** 
* copy database from assets folder to the device 
* 
* @throws IOException 
*/ 
private void copyDataBase() throws IOException { 
    InputStream myInput = context.getAssets().open(DB_NAME); 
    OutputStream myOutput = new FileOutputStream(DB_PATH + DB_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(); 
} 

@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 

} 
} 

in MainActivity.class

public class MainActivity extends Activity { 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_test); 
    // create DB 
    isCreateDB(); 
} 

/* 
* Copy db from asset to database 
*/ 
private boolean isCreateDB() { 
    SqliteHelper data = new SqliteHelper(this); 
    try { 

     return data.isCreatedDatabase(); 

    } catch (IOException e) { 
     Toast.makeText(this, "Error Copy data", Toast.LENGTH_LONG).show(); 
     e.printStackTrace(); 
     return false; 
    } 
} 

Hoffnung. Es wird dir helfen !!!

Verwandte Themen