Como você está tendo dificuldades, o seguinte é um tutorial montado às pressas junto com o código.
-
Crie o banco de dados e as tabelas em uma ferramenta SQLite, adicionando os dados conforme necessário e depois salve.
-
Feche o banco de dados e abra-o novamente para verificar se as tabelas e os dados estão conforme o esperado. Caso contrário, faça as alterações e repita 2 até ter certeza de que o banco de dados salvo corresponde.
-
Obtenha o nome do arquivo do banco de dados salvo e registre-o incluindo a extensão do arquivo.
-
Se você ainda não criou um projeto para o aplicativo, faça isso e salve o projeto.
-
Fora do IDE, navegue até a pasta app/src/main de projetos e crie uma pasta chamada assets se ainda não existir.
-
Copie o arquivo de banco de dados na pasta de ativos.
-
Abra o projeto no Android Studio.
-
Crie uma nova classe Java chamada DatabaseHelper com SuperClass como SQLiteOpenHelper (resolverá paraandroid.database.sqlite.SQLiteOpenHelper
) e marque Mostrar substituições de seleção Caixa de diálogo. O clique em OK.
Deve ficar assim:-
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) {
}
}
-
Adicione uma linha, como uma variável de classe, apóspublic class DatabaseHelper extends SQLiteOpenHelper {
é como :-
public static final String DBNAME = "my_dic.db";
- Observando que é importante que o valor entre aspas seja exatamente o mesmo que o nome do arquivo que foi copiado para a pasta de recursos.
.
- Adicione as seguintes variáveis de classe
:-
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;
- Observando que os valores entre aspas precisam corresponder aos nomes de tabela/coluna de referência que foram definidos no banco de dados para TB_BOOKMARK, COL_BOOKMARK_KEY, COL_BOOKMARK_VALUE e COl_BOOKMARK_DATE.
- DBVERSION será o número da versão armazenado no campo user_version do banco de dados.
- SQliteDatabase mDB é uma declaração para uma variável manter o SQLiteDatabase quando ele for aberto. OBSERVE atualmente seu valor é nulo até que seja definido.
.
-
Altere o construtor para a classe Databasehelper de:-
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}
para :-
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}
- Isso faz com que uma instância da classe Databasehelper possa ser criada com apenas um parâmetro, o context. Os outros valores foram definidos ou no caso da fábrica nenhum será usado, então null significa isso.
.
- Adicione um método,
ifDBExists
para a classe DatabaseHelper para verificar se o banco de dados existe (você só deseja copiá-lo do arquivo de ativos uma vez)
:-
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();
}
- Além de verificar se o arquivo de banco de dados existe (observe que é considerado um arquivo de banco de dados válido),
- Além disso, se o banco de dados não existir, pode ser que o diretório do banco de dados não exista, isso o criará se não existir.
.
- Adicione outro método
copyDBFromAssets
para copiar o arquivo de ativos para o banco de dados
:-
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;
}
- Observe que isso é intencionalmente prolixo, para que qualquer falha possa ser identificada.
A classe completa do DatabaseHelper agora seria:-
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;
}
}
.
- Altere o construtor para executar o
copyDBFromAssets
método quando/se o banco de dados não existir (usando o métodoifDBExists
método)
:-
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();
}
- Observe se houver um problema ao copiar o banco de dados, o aplicativo será interrompido devido ao
RunTimeExcpetion
emitido.
.
- Última alteração do método onCreate de uma atividade (normalmente seria a atividade principal) para criar uma instância da classe DatabaseHelper. Em seguida, execute o aplicativo (se o aplicativo foi executado, seria melhor excluir os dados do aplicativo antes de fazer isso, caso um banco de dados, talvez vazio, tenha sido criado.)
O código a seguir também inclui uma consulta que informará quais tabelas existem no banco de dados:-
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();
}
}
Com base na captura de tela e em um arquivo de banco de dados chamado
my_dic.db
. A saída no log é:- 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
- Isso indica que:-
- O banco de dados não existia e o diretório de bancos de dados foi criado (ou seja,
data/data/<package name>/databases
) - 12.288 bytes foram copiados do arquivo de recurso para o arquivo de banco de dados (ou seja, uma cópia bem-sucedida foi feita).
- O banco de dados resultante tem três entradas na tabela sqlite_master, a tabela BookMark, uma tabela chamada android_metadata (uma tabela criada automaticamente para dispositivos Android pelo SDK que armazena a localidade) e um índice gerado automaticamente para a tabela BookMark. l>
- O banco de dados não existia e o diretório de bancos de dados foi criado (ou seja,
Edição subsequente
Basicamente, o objeto não tem um método chamado getClass, em vez disso você precisa usar o método getClass herdado do Fragment. Então você precisa colocar o fragmento retornado entre parênteses.
Então, em vez de:-
String activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
Você poderia usar:-
String activeFragment = (getSupportFragmentManager().findFragmentById(R.id.fragment_container)).getClass().getSimpleName();
Alternativamente, você pode usar:-
Fragment activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
junto com o uso:-
if (activeFragment instanceOf BookmarkFragment) { ...... rest of your code
em vez de usar
if (activeFragment.equals(BookmarkFragment.class.getSimpleName())) { ......