Przewodnik krok po kroku.
1. Utwórz bazę danych za pomocą odpowiedniego narzędzia do zarządzania SQLite z tabelą teksty wypełnione wymaganymi danymi. Zapewnienie zapisania bazy danych.
- W tym przypadku użyto NaviCat, a do utworzenia i zapełnienia tabeli tekstów użyto następującego kodu SQL.
:-
CREATE TABLE IF NOT EXISTS lyrics (
id INTEGER PRIMARY KEY,
song TEXT,
year TEXT,
artist TEXT,
genre TEXT,
lyrics TEXT
);
INSERT INTO lyrics (song, year, artist, genre, lyrics) VALUES
('song1','1970','Fred','Rock','Rock rock rock'),
('song2','1980','Mary','Pop','Pop pop pop'),
('song3','1960','Sue','Folk','Folk folk folk');
- Uwaga indeks jest słowem kluczowym, więc nie jest prawidłową nazwą kolumny, chyba że jest ujęta, więc id został użyty zamiast indeksu.
2. Plik został zapisany jako lyrics.db i skopiowane do folderu zasobów projektu.
3. DbHelper.java (różne modyfikacje)
public class DbHelper extends SQLiteOpenHelper {
private static String DB_NAME = "lyrics.db";
private SQLiteDatabase vDatabase;
private Context vContext;
public DbHelper(Context context) {
super(context, DB_NAME, null, 1);
this.vContext = context;
// Copy the DB if need be when instantiating the DbHelper
if (!checkDataBase()) {
copyDB();
}
vDatabase = this.getWritableDatabase(); //Get the database when instantiating
}
/**
* No need for build version check as getDataBasePath works for all versions
* No need for open and close of Database, just open it once for the lifetime (more efficient)
*/
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
/**
* Does not open the database instead checks to see if the file exists
* also creates the databases directory if it does not exists
* (the real reason why the database is opened, which appears to result in issues)
*/
File db = new File(vContext.getDatabasePath(DB_NAME).getPath()); //Get the file name of the database
Log.d("DBPATH","DB Path is " + db.getPath());
if (db.exists()) return true; // If it exists then return doing nothing
// Get the parent (directory in which the database file would be)
File dbdir = db.getParentFile();
// If the directory does not exist then make the directory (and higher level directories)
if (!dbdir.exists()) {
db.getParentFile().mkdirs();
dbdir.mkdirs();
}
return false;
}
public void copyDB() throws SQLiteException{
try {
InputStream myInput = vContext.getAssets().open(DB_NAME);
String outputFileName = vContext.getDatabasePath(DB_NAME).getPath(); //<<<<<<<<<< changed
Log.d("LIFECYCLE", outputFileName);
OutputStream myOutput = new FileOutputStream(outputFileName);
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 ( IOException e) {
e.printStackTrace();
}
}
public List<Lyric> getAllSong(){
List<Lyric> temp = new ArrayList<>();
Cursor cursor = vDatabase.query("lyrics",null,null,null,null,null,null);
//Cursor cursor = db.rawQuery( "SELECT * FROM lyrics" , null); // used query method generally preferred to rawQuery
//if( cursor == null) return null; // Cursor will not be null may be empty
//cursor.moveToFirst(); // changed to use simpler loop
while (cursor.moveToNext()) {
Lyric lyric = new Lyric(
//cursor.getString(cursor.getColumnIndex("index")), //<<<<<<< changed due to column name change
cursor.getString(cursor.getColumnIndex("id")),
cursor.getString(cursor.getColumnIndex("song")),
cursor.getString(cursor.getColumnIndex("year")),
cursor.getString(cursor.getColumnIndex("artist")),
cursor.getString(cursor.getColumnIndex("genre")),
cursor.getString(cursor.getColumnIndex("lyrics"))
);
temp.add(lyric);
}
cursor.close();
//db.close(); // inefficient to keep on opening and closing db
return temp;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
- Sprawdź komentarze dotyczące modyfikacji
4. Odinstaluj istniejącą aplikację lub usuń dane aplikacji (WAŻNE)
5. Przetestuj.
Poniżej znajduje się ćwiczenie, które przetestuje powyższe.
public class MainActivity extends AppCompatActivity {
DbHelper vDBHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vDBHlpr = new DbHelper(this);
List<Lyric> mylyricslist = vDBHlpr.getAllSong();
for (Lyric l: mylyricslist) {
Log.d("LYRICFROMDB","Song is " + l.getSong() + " Year is " + l.getYear() + " Artist is " + l.getArtist() + " Genre is " + l.getGenre() + " Lyrics are " + l.getLyrics());
}
}
}
Dziennik powinien zawierać (pierwsze uruchomienie):-
03-17 19:42:11.067 16057-16057/? D/DBPATH: DB Path is /data/data/com.example.so55199382lyrics/databases/lyrics.db
03-17 19:42:11.067 16057-16057/? D/LIFECYCLE: /data/data/com.example.so55199382lyrics/databases/lyrics.db
03-17 19:42:11.086 16057-16057/? D/LYRICFROMDB: Song is song1 Year is 1970 Artist is Fred Genre is Rock Lyrics are Rock rock rock
03-17 19:42:11.086 16057-16057/? D/LYRICFROMDB: Song is song2 Year is 1980 Artist is Mary Genre is Pop Lyrics are Pop pop pop
03-17 19:42:11.086 16057-16057/? D/LYRICFROMDB: Song is song3 Year is 1960 Artist is Sue Genre is Folk Lyrics are Folk folk folk
lub dla kolejnych przejazdów :-
03-17 19:49:11.275 16136-16136/? D/DBPATH: DB Path is /data/data/com.example.so55199382lyrics/databases/lyrics.db
03-17 19:49:11.279 16136-16136/? D/LYRICFROMDB: Song is song1 Year is 1970 Artist is Fred Genre is Rock Lyrics are Rock rock rock
03-17 19:49:11.279 16136-16136/? D/LYRICFROMDB: Song is song2 Year is 1980 Artist is Mary Genre is Pop Lyrics are Pop pop pop
03-17 19:49:11.279 16136-16136/? D/LYRICFROMDB: Song is song3 Year is 1960 Artist is Sue Genre is Folk Lyrics are Folk folk folk
- Uruchom notatkę dwukrotnie, aby sprawdzić zarówno proces kopiowania, jak i obsługę istniejącej bazy danych.
Powyższe zostało przetestowane na emulatorach z systemem Android Lollipop i Pie