Android: How to create an external Sqlite database dynamically?

0

I have been thoroughly researching on this and all the examples I found and tested did not work. To leave the code more organized I would like to do this using the OpenHelper class but I have already tested the openOrCreate () method on both OpenHelper and Activity itself. Here is my code:

public class CriaBancoApp extends SQLiteOpenHelper {

    private static final String NOME_BANCO = "BD_AppNome.db";
    private static final String CAMINHO_BANCO = Environment.getExternalStorageDirectory() + "/AppNome/Databases/";
    private static final int VERSAO = 1;


    public CriaBancoApp(Context contexto) {
        super(contexto, CAMINHO_BANCO, null, VERSAO); 
       //SQLiteDatabase.openOrCreateDatabase(CAMINHO_BANCO, null); 
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE NomeTabela (" 
                + "Id INTEGER PRIMARY KEY AUTOINCREMENT,"
                + "AutorTraducao TEXT)";
                db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS NomeTabela");
        onCreate(db);
    }

}

Then I create the instance in MainActivity:

CriaBancoApp banco = new CriaBancoApp(this);

And when starting the app date. Regarding the path the app folders are created before creating the database I even commented this line to check if the folders are created and are. The xml Manifest already has write permission that automatically includes the read permission.

    
asked by anonymous 18.06.2018 / 20:18

1 answer

0

Well, after a lot of research I decided to study the parent class SQLiteOpenHelper and found that it uses the context to define the path where the database will be created. Based on this I have changed the focus of the search to how to customize a context with the path I want. In this search I came up with this answer: link that solved the problem. As it was all in English, I made my adaptation of this answer to Portuguese it looked like this:

In the CreateBancoApp class I modified the constructor:

    public CriaBancoApp(Context contexto) {
        super(new ContextoBanco(contexto, CAMINHO_BANCO), NOME_BANCO, null, VERSAO);
    }

Then I created a class responsible for customizing the context:

public class ContextoBanco extends ContextWrapper {
    private static final String DEPURAR_CONTEXTO = "ContextoBanco";
    private String caminho;

    public ContextoBanco(Context base, String caminho) {
        super(base);
        this.caminho = caminho;
    }

    @Override
    public File getDatabasePath(String name)  {
        String caminho_banco = caminho + name;
        if (!caminho_banco.endsWith(".db")) {
            caminho_banco += ".db" ;
        }

        File result = new File(caminho_banco);

        if (!result.getParentFile().exists()) {

            result.getParentFile().mkdirs();
        }

        if (Log.isLoggable(DEPURAR_CONTEXTO, Log.WARN)) {
         Log.w(DEPURAR_CONTEXTO, "getDatabasePath(" + name + ") = " + result.getAbsolutePath());
        }

        return result;
    }

    /* Esta versão é chamada para dispositivos Android >= api-11. */
    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
        return openOrCreateDatabase(name,mode, factory);
    }

    /* Esta versão é chamada para dispositivos Android < api-11 */
    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
        SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
        if (Log.isLoggable(DEPURAR_CONTEXTO, Log.WARN)) {
         Log.w(DEPURAR_CONTEXTO, "openOrCreateDatabase(" + name + ",,) = " + result.getPath());
        }
        return result;
    }

}

And in MainActivity besides creating an instance of the class BankApp, it is necessary to make a query for the database to be created:

        SQLiteDatabase db;
        CriaBancoApp banco = new CriaBancoApp(this);
        String[] campos = {"Id","Nome","Idade","Etc"};
        String condicao = " Id > 0 ";
        Cursor dados = null;

        db = banco.getReadableDatabase();

        dados = db.query("Nome_da_Tabela", campos, condicao, null, null, null, null);

        if(dados != null) {

            if(dados.moveToNext()) {
                // Registro encontrado
            } else {
                // Não há registros na tabela
            }
        }

Even though I had found my answer, I felt it was my duty to publish to help others who might need it, after all it was very time consuming for me to find.

    
20.06.2018 / 01:01