Protože máte potíže, následuje narychlo sestavený tutoriál spolu s kódem.
-
Vytvořte databázi a tabulky v nástroji SQLite, přidejte data podle potřeby a poté je uložte.
-
Zavřete databázi a znovu ji otevřete a zkontrolujte, zda jsou tabulky a data podle očekávání. Pokud ne, proveďte změny a pak opakujte 2, dokud si nejste jisti, že uložená databáze odpovídá.
-
Získejte název souboru uložené databáze a zaznamenejte jej včetně přípony souboru.
-
Pokud jste ještě nevytvořili projekt pro aplikaci, udělejte tak a projekt uložte.
-
Mimo IDE přejděte do složky project/src/main a vytvořte složku s názvem assets pokud již neexistuje.
-
Zkopírujte soubor databáze do složky aktiv.
-
Otevřete projekt v Android Studio.
-
Vytvořte novou třídu Java s názvem DatabaseHelper se SuperClass jako SQLiteOpenHelper (vyřeší se jako
android.database.sqlite.SQLiteOpenHelper
) a zaškrtněte možnost Zobrazit přepisy výběru Zaškrtávací políčko dialogu. Klepněte na tlačítko OK.
Mělo by to vypadat takto :-
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) {
}
}
-
Přidejte řádek jako proměnnou třídy za
public class DatabaseHelper extends SQLiteOpenHelper {
to je jako :-public static final String DBNAME = "my_dic.db";
- Upozorňujeme, že je důležité, aby hodnota v uvozovkách byla přesně stejná jako název souboru, který byl zkopírován do složky aktiv.
.
- Přidejte následující proměnné třídy
:-
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;
- Všimněte si, že hodnoty v uvozovkách musí odpovídat názvům tabulek/sloupců respektování, které byly definovány v databázi pro TB_BOOKMARK, COL_BOOKMARK_KEY, COL_BOOKMARK_VALUE a COl_BOOKMARK_DATE.
- DBVERSION bude číslo verze uložené v poli user_version databáze.
- SQliteDatabase mDB je deklarace proměnné, která má uchovávat SQLiteDatabase, když byla otevřena. POZNÁMKA v současnosti je jeho hodnota nulová, dokud nebude nastavena.
.
-
Změňte konstruktor pro třídu Databasehelper z :-
public DatabaseHelper(kontext kontextu, název řetězce, továrna SQLiteDatabase.CursorFactory, verze int) {super(kontext, název, továrna, verze);}
do :-
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}
- To umožňuje vytvořit instanci třídy Databasehelper pouze s jedním parametrem, kontextem. Ostatní hodnoty byly definovány nebo v případě továrny nebudou použity žádné, takže null to znamená.
.
- Přidejte metodu,
ifDBExists
do třídy DatabaseHelper a zkontrolujte, zda databáze existuje (chcete ji zkopírovat ze souboru aktiv pouze jednou)
:-
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();
}
- Kromě kontroly, zda databázový soubor existuje (všimněte si, že se předpokládá, že je platný databázový soubor),
- Navíc, pokud databáze neexistuje, je možné, že neexistuje adresář databází, pokud neexistuje, vytvoří se tímto.
.
- Přidejte další metodu
copyDBFromAssets
zkopírujte soubor aktiv do databáze
:-
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;
}
- Upozorňujeme, že toto je záměrně zdlouhavé, takže případné selhání lze přesně označit.
Kompletní třída DatabaseHelper by nyní byla :-
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;
}
}
.
- Změňte konstruktor tak, aby spouštěl
copyDBFromAssets
metoda když/pokud databáze neexistuje (pomocíifDBExists
metoda)
:-
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();
}
- Upozorňujeme, že pokud došlo k problému s kopírováním databáze, aplikace bude zastavena kvůli
RunTimeExcpetion
vydáno.
.
- Poslední úprava metody onCreate aktivity (normálně by to byla hlavní aktivita) za účelem vytvoření instance třídy DatabaseHelper. Poté spusťte aplikaci (pokud byla aplikace spuštěna, bylo by nejlepší před tím smazat data aplikace, pro případ, že by byla vytvořena databáze, možná prázdná.)
Následující kód také obsahuje dotaz, který vám řekne, jaké tabulky existují v databázi :-
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();
}
}
Na základě snímku obrazovky a databázového souboru s názvem my_dic.db
. Výstup v protokolu je :-
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
- To znamená, že :-
- Databáze neexistovala a byl vytvořen adresář databází (tj.
data/data/<package name>/databases
) - 12288 bajtů bylo zkopírováno ze souboru aktiv do souboru databáze (tj. byla vytvořena úspěšná kopie).
- Výsledná databáze má tři položky v tabulce sqlite_master, tabulku BookMark, tabulku nazvanou android_metadata (tabulka automaticky vytvořená pro zařízení Android pomocí sady SDK, která ukládá národní prostředí) a automaticky generovaný index pro tabulku BookMark. li>
- Databáze neexistovala a byl vytvořen adresář databází (tj.
Následný problém
Objekt v zásadě nemá metodu nazvanou getClass, ale musíte použít zděděnou metodu getClass od Fragmentu. Takže musíte vrácený fragment uzavřít do závorek.
Takže místo :-
String activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
Můžete použít :-
String activeFragment = (getSupportFragmentManager().findFragmentById(R.id.fragment_container)).getClass().getSimpleName();
Alternativně můžete použít :-
Fragment activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
spolu s použitím :-
if (activeFragment instanceOf BookmarkFragment) { ...... rest of your code
místo použití if (activeFragment.equals(BookmarkFragment.class.getSimpleName())) { ......