Da du har problemer, er følgende en hastigt sammensat tutorial sammen med kode.
-
Opret databasen og tabellerne i et SQLite-værktøj, tilføj data efter behov, og gem dem derefter.
-
Luk databasen, og åbn den igen for at kontrollere, at tabellerne og dataene er som forventet. Hvis ikke, foretag ændringer og gentag derefter 2, indtil du er sikker på, at den gemte database matcher.
-
Få filnavnet på den gemte database, og optag det inklusive filtypenavnet.
-
Hvis du endnu ikke har oprettet et projekt til appen, så gør det og gem projektet.
-
Uden for IDE naviger til projektappen/src/hovedmappen og opret en mappe med navnet aktiver hvis det ikke allerede eksisterer.
-
Kopier databasefilen til aktivemappen.
-
Åbn projektet i Android Studio.
-
Opret en ny Java-klasse ved navn DatabaseHelper med SuperClass som SQLiteOpenHelper (vil løses til
android.database.sqlite.SQLiteOpenHelper
) og marker Vis udvalgte tilsidesættelser Dialogboks. Klik på OK.
Det skulle se ud som :-
public class DatabaseHelper extends SQLiteOpenHelper {
public Databasehelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
-
Tilføj en linje, som en klassevariabel, efter
public class DatabaseHelper extends SQLiteOpenHelper {
det er ligesom :-public static final String DBNAME = "my_dic.db";
- Bemærk, at det er vigtigt, at værdien inden for anførselstegnene er nøjagtig den samme som filnavnet, der blev kopieret til aktivmappen.
.
- Tilføj følgende klassevariable
:-
public static final int DBVERSION = 1;
public static final String TB_BOOKMARK = "Bookmark";
public static final String COL_BOOKMARK_KEY = "key";
public static final String COL_BOOKMARK_VALUE = "value";
public static final String COL_BOOKMARK_DATE = "date";
SQLiteDatabase mDB;
- Bemærk, at værdierne i anførselstegn skal matche de respetice-tabel-/kolonnenavne, der blev defineret i databasen for TB_BOOKMARK, COL_BOOKMARK_KEY, COL_BOOKMARK_VALUE og COl_BOOKMARK_DATE.
- DBVERSION vil være versionsnummeret, der er gemt i databasens user_version-felt.
- SQliteDatabase mDB er en erklæring for en variabel, der skal indeholde SQLiteDatabasen, når den er blevet åbnet. BEMÆRK i øjeblikket er dens værdi null, indtil den er blevet indstillet.
.
-
Skift konstruktøren for Databasehelper-klassen fra :-
public DatabaseHelper(Kontekstkontekst, Strengnavn, SQLiteDatabase.CursorFactory fabrik, int version) {super(kontekst, navn, fabrik, version);}
til :-
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}
- Dette gør det så en forekomst af Databasehelper-klassen kan oprettes med kun én parameter, konteksten. De andre værdier er blevet defineret, eller i tilfælde af fabrikken vil ingen blive brugt, så null betyder dette.
.
- Tilføj en metode,
ifDBExists
til DatabaseHelper-klassen for at kontrollere, om databasen eksisterer (du vil kun kopiere den fra aktivfilen én gang)
:-
private boolean ifDBExists(Context context) {
String dbparent = context.getDatabasePath(DBNAME).getParent();
File f = context.getDatabasePath(DBNAME);
if (!f.exists()) {
Log.d("NODB MKDIRS","Database file not found, making directories."); //<<<< remove before the App goes live.
File d = new File(dbparent);
d.mkdirs();
//return false;
}
return f.exists();
}
- Ud over at kontrollere, at databasefilen eksisterer (bemærk, at den antages at være en gyldig databasefil),
- Hvis databasen ikke eksisterer, kan det desuden være, at databasebiblioteket ikke eksisterer, dette vil oprette det, hvis det ikke eksisterer.
.
- Tilføj en anden metode
copyDBFromAssets
for at kopiere aktivfilen til databasen
:-
private boolean copyDBFromAssets(Context context) {
Log.d("CPYDBINFO","Starting attemtpt to cop database from the assets file.");
String DBPATH = context.getDatabasePath(DBNAME).getPath();
InputStream is;
OutputStream os;
int length = 8192;
long bytes_read = 0;
long bytes_written = 0;
byte[] buffer = new byte[length];
try {
is = context.getAssets().open(DBNAME);
} catch (IOException e) {
Log.e("CPYDB FAIL - NO ASSET","Failed to open the Asset file " + DBNAME);
e.printStackTrace();
return false;
}
try {
os = new FileOutputStream(DBPATH);
} catch (IOException e) {
Log.e("CPYDB FAIL - OPENDB","Failed to open the Database File at " + DBPATH);
e.printStackTrace();
return false;
}
Log.d("CPYDBINFO","Initiating copy from asset file" + DBNAME + " to " + DBPATH);
while (length >= 8192) {
try {
length = is.read(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - RD ASSET",
"Failed while reading in data from the Asset. " +
String.valueOf(bytes_read) +
" bytes read ssuccessfully."
);
e.printStackTrace();
return false;
}
bytes_read = bytes_read + length;
try {
os.write(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - WR ASSET","failed while writing Database File " +
DBPATH +
". " +
String.valueOf(bytes_written) +
" bytes written successfully.");
e.printStackTrace();
return false;
}
bytes_written = bytes_written + length;
}
Log.d("CPYDBINFO",
"Read " + String.valueOf(bytes_read) + " bytes. " +
"Wrote " + String.valueOf(bytes_written) + " bytes."
);
try {
os.flush();
is.close();
os.close();
} catch (IOException e ) {
Log.e("CPYDB FAIL - FINALISING","Failed Finalising Database Copy. " +
String.valueOf(bytes_read) +
" bytes read." +
String.valueOf(bytes_written) +
" bytes written."
);
e.printStackTrace();
return false;
}
return true;
}
- Bemærk, at dette med vilje er langtrukkent, så enhver fejl kan identificeres.
Den komplette DatabaseHelper-klasse ville nu være :-
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "my_dic.db"; // <<<< VERY IMPORTANT THAT THIS MATCHES DATABASE FILE NAME
public static final int DBVERSION = 1;
public static final String TB_BOOKMARK = "Bookmark";
public static final String COL_BOOKMARK_KEY = "key";
public static final String COL_BOOKMARK_VALUE = "value";
public static final String COL_BOOKMARK_DATE = "date";
SQLiteDatabase mDB;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
if (!ifDBExists(context)) {
if (!copyDBFromAssets(context)) {
throw new RuntimeException("Failed to Copy Database From Assets Folder");
}
}
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
private boolean ifDBExists(Context context) {
String dbparent = context.getDatabasePath(DBNAME).getParent();
File f = context.getDatabasePath(DBNAME);
if (!f.exists()) {
Log.d("NODB MKDIRS","Database file not found, making directories.");
File d = new File(dbparent);
d.mkdirs();
//return false;
}
return f.exists();
}
private boolean copyDBFromAssets(Context context) {
Log.d("CPYDBINFO","Starting attemtpt to cop database from the assets file.");
String DBPATH = context.getDatabasePath(DBNAME).getPath();
InputStream is;
OutputStream os;
int length = 8192;
long bytes_read = 0;
long bytes_written = 0;
byte[] buffer = new byte[length];
try {
is = context.getAssets().open(DBNAME);
} catch (IOException e) {
Log.e("CPYDB FAIL - NO ASSET","Failed to open the Asset file " + DBNAME);
e.printStackTrace();
return false;
}
try {
os = new FileOutputStream(DBPATH);
} catch (IOException e) {
Log.e("CPYDB FAIL - OPENDB","Failed to open the Database File at " + DBPATH);
e.printStackTrace();
return false;
}
Log.d("CPYDBINFO","Initiating copy from asset file" + DBNAME + " to " + DBPATH);
while (length >= 8192) {
try {
length = is.read(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - RD ASSET",
"Failed while reading in data from the Asset. " +
String.valueOf(bytes_read) +
" bytes read ssuccessfully."
);
e.printStackTrace();
return false;
}
bytes_read = bytes_read + length;
try {
os.write(buffer,0,length);
} catch (IOException e) {
Log.e("CPYDB FAIL - WR ASSET","failed while writing Database File " +
DBPATH +
". " +
String.valueOf(bytes_written) +
" bytes written successfully.");
e.printStackTrace();
return false;
}
bytes_written = bytes_written + length;
}
Log.d("CPYDBINFO",
"Read " + String.valueOf(bytes_read) + " bytes. " +
"Wrote " + String.valueOf(bytes_written) + " bytes."
);
try {
os.flush();
is.close();
os.close();
} catch (IOException e ) {
Log.e("CPYDB FAIL - FINALISING","Failed Finalising Database Copy. " +
String.valueOf(bytes_read) +
" bytes read." +
String.valueOf(bytes_written) +
" bytes written."
);
e.printStackTrace();
return false;
}
return true;
}
}
.
- Skift konstruktøren for at køre
copyDBFromAssets
metode, når/hvis databasen ikke eksisterer (ved hjælp afifDBExists
metode)
:-
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
if (!ifDBExists(context)) {
if (!copyDBFromAssets(context)) {
throw new RuntimeException("Failed to Copy Database From Assets Folder");
}
}
mDB = this.getWritableDatabase();
}
- Bemærk, hvis der var et problem med at kopiere databasen, vil appen blive stoppet på grund af
RunTimeExcpetion
udstedt.
.
- Sidste ændring af en aktivitets onCreate-metode (vil normalt være hovedaktiviteten) for at oprette en forekomst af DatabaseHelper-klassen. Kør derefter appen (hvis appen er blevet kørt, ville det være bedst at slette appens data, før du gør det, bare hvis en database, måske tom, er blevet oprettet.)
Følgende kode indeholder også en forespørgsel, der fortæller dig, hvilke tabeller der findes i databasen:-
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper mDBHlpr = new DatabaseHelper(this);
Cursor csr = mDBHlpr.getWritableDatabase().query(
"sqlite_master",
null,null,null,null,null,null
);
while (csr.moveToNext()) {
Log.d("DB TABLES", csr.getString(csr.getColumnIndex("name")));
}
csr.close();
}
}
Baseret på skærmbilledet og en databasefil med navnet my_dic.db
. Outputtet i loggen er :-
06-16 02:28:45.208 4467-4467/? D/NODB MKDIRS: Database file not found, making directories.
06-16 02:28:45.208 4467-4467/? D/CPYDBINFO: Starting attemtpt to cop database from the assets file.
Initiating copy from asset filemy_dic.db to /data/data/com.mydictionaryapp.mydictionaryapp/databases/my_dic.db
Read 12288 bytes. Wrote 12288 bytes.
06-16 02:28:45.224 4467-4467/? D/DB TABLES: Bookmark
sqlite_autoindex_Bookmark_1
android_metadata
- Dette indikerer, at :-
- Databasen eksisterede ikke, og databasebiblioteket blev oprettet (dvs.
data/data/<package name>/databases
) - 12288 bytes blev kopieret fra aktivfilen til databasefilen (dvs. en vellykket kopi blev lavet).
- Den resulterende database har tre poster i sqlite_master-tabellen, BookMark-tabellen, en tabel kaldet android_metadata (en tabel, der automatisk oprettes til Android-enheder af SDK'et, som gemmer lokaliteten) og et automatisk genereret indeks for BookMark-tabellen.
- Databasen eksisterede ikke, og databasebiblioteket blev oprettet (dvs.
Efterfølgende udgave
Dybest set har objektet ikke en metode kaldet getClass, snarere skal du bruge Fragmentets nedarvede getClass-metode. Så du skal omslutte det returnerede fragment i parentes.
Så i stedet for :-
String activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
Du kunne bruge :-
String activeFragment = (getSupportFragmentManager().findFragmentById(R.id.fragment_container)).getClass().getSimpleName();
Alternativt kan du bruge :-
Fragment activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
sammen med at bruge :-
if (activeFragment instanceOf BookmarkFragment) { ...... rest of your code
i stedet for at bruge if (activeFragment.equals(BookmarkFragment.class.getSimpleName())) { ......