данные вставлены во внешнюю базу данных sqlite, но не сохранены в Android Studio - PullRequest
0 голосов
/ 21 декабря 2018

Я использую внешнюю базу данных sqlite , а не создаю ее в моем проекте Android Studio , поскольку в базе данных будет уже заполненных данных .Но я должен добавить еще некоторые данные.И когда я вставляю какие-либо новые данные, он показывает новые данные, но когда я закрываю свое приложение для Android и снова открываю, чтобы увидеть данные, вновь вставленные данные через приложение как-то удаляются , отображаются только предварительно заполненные данные.

Я использую браузер БД для sqlite, чтобы создать внешнюю базу данных sqlite и предварительно заполнить ее некоторыми данными.В моем проекте Android Studio я добавил эту базу данных в папку ресурсов и реализовал класс SQLiteOpenHelper для доступа к этой базе данных.Чтение данных из таблицы базы данных прошло успешно.Теперь, когда я вставляю новые данные, я могу также временно прочитать новые данные.Временно в том смысле, что после закрытия приложения новые данные теряются.

таблица моей внешней базы данных sqlite:

CREATE TABLE `table_name` (
`Id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`Content`   TEXT NOT NULL
);

Класс SQLiteOpenHelper:

public class ProcessExternalDBHelper {
private static final String DATABASE_NAME = "database_name.db";
private static final int DATABASE_VERSION = 1;
private static String DATABASE_PATH = "";

private static final String DATABASE_TABLE = "table_name";
private static final String KEY_ROWID = "Id";
private static final String KEY_CONTENT = "Content";

private ExternalDbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;

private static class ExternalDbHelper extends SQLiteOpenHelper {

    public ExternalDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        if (Build.VERSION.SDK_INT >= 17) {
            DATABASE_PATH = context.getApplicationInfo().dataDir + 
"/databases/";
        } else {
            DATABASE_PATH = "/data/data/" + context.getPackageName() + 
"/databases/";
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int 
newVersion) {

    }
}

public ProcessExternalDBHelper(Context context) {
    ourContext = context;
}
//for reading
public ProcessExternalDBHelper openRead() throws SQLException {
    ourHelper = new ExternalDbHelper(ourContext);
    ourDatabase = ourHelper.getReadableDatabase();
    return this;
}
//for writing
public ProcessExternalDBHelper openWrite() throws SQLException{
    ourHelper = new ExternalDbHelper(ourContext);
    ourDatabase = ourHelper.getWritableDatabase();
    return this;
}

public void close() {
    if (ourHelper != null) {
        ourHelper.close();
    }
}

//Create database in activity
public void createDatabase() throws IOException {
    createDB();
}
//Create db if not exists
private void createDB() {
    boolean dbExists = checkDatabase();
    if (!dbExists) {
        openRead();             
        try {
            this.close();
            copyDatabase();
        } catch (IOException ie) {
            throw new Error("Error copying database");
        }
    }
}

private boolean checkDatabase() {
    boolean checkDB = false;
    try {
        String myPath = DATABASE_PATH + DATABASE_NAME;
        File dbfile = new File(myPath);
        checkDB = dbfile.exists();
    } catch (SQLiteException e) {

    }
    return checkDB;
}

private void copyDatabase() throws IOException {
    InputStream myInput = null;
    OutputStream myOutput = null;
    String outFileName = DATABASE_PATH + DATABASE_NAME;

    try {
        myInput = ourContext.getAssets().open(DATABASE_NAME);
        myOutput = new FileOutputStream(outFileName);

        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 ie) {
        throw new Error("Copydatabase() error");
    }
}
//To show all available contents in my database
public List<Model> findallContents() {
    List<Model> mContents = new ArrayList<>();

    String[] columns = new String[]{KEY_CONTENT};
    Cursor cursor = ourDatabase.query(DATABASE_TABLE, columns, null, null, 
null, null, null);
    int iContent = cursor.getColumnIndex(KEY_CONTENT);

    for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) 
    {
        Model model= new Model();
        model.setContent(cursor.getString(iContent));

        mContents.add(model);
    }

    cursor.close();
    return mContents;
}

public void addContent(String content) {
    ContentValues contentValues = new ContentValues();
    contentValues.put(KEY_CONTENT, content);

    ourDatabase.insert(DATABASE_TABLE, null, contentValues);
    ourDatabase.close();
}

}

Мой класс Model.java:

public class Model {
    private String mContent;

    public String getContent() {
    return mContent;
    }

    public void setContent(String content) {
        this.mContent = content;
    }
}

Наконец мой класс деятельности, где я читаю и записываю данные:

public class MainActivity extends AppCompatActivity {

private EditText editText_Content;
private ImageButton imageButton_Save;
private List<Model> mContentsArrayList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ProcessExternalDBHelper myDbHelper = new ProcessExternalDBHelper(this);
    try {
        myDbHelper.createDatabase();
    } catch (IOException ioe) {
        throw new Error("Unable to CREATE DATABASE");
    } finally {
        myDbHelper.close();
    }

    initialize();

    GetContents();

    imageButton_Save.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!(editText_Content.getText().toString().trim().isEmpty())) 
            {
                SaveContents();
            } 
        }
    });
}

private void initialize() {
    editText_Content = findViewById(R.id.editText_contents);
    imageButton_Save = findViewById(R.id.imageButton_save);

    mContentsArrayList = new ArrayList<>();
}
//GetContents and show them later in my RecyclerView
private void GetContents() {
    try {
        mContentsArrayList.clear();
        ProcessExternalDBHelper autoProcess = new 
    ProcessExternalDBHelper(this);
        autoProcess.openRead();
        mContentsArrayList.addAll(autoProcess.findallContents();
        autoProcess.close();
    } catch (Exception e) {

    }
}
//For saving content into database    
private void SaveContents() {
    String content = editText_Content.getText().toString();

    try {
        ProcessExternalDBHelper autoProcess = new 
ProcessExternalDBHelper(this);
        autoProcess.openWrite();   //for writing into database
        autoProcess.addContent(content);
        autoProcess.close();
        editText_Content.getText().clear();
    } catch (Exception e) {

    }
}

}

Наконец, я использую DB Browser для Sqlite (версия 3.10.1), Android Studio (версия 3.0.1), minSdkVersion 19.

Я ожидаю, что только что вставленные данные будут сохранены в базе данных, а затем увидены, даже когда я закрою свое приложение и перезапущу приложение позже. Спасибо!

1 Ответ

0 голосов
/ 21 декабря 2018

Ваша проблема в том, что DATABASE_PATH не сбрасывается и поэтому пусто при вызове createDatabase .

Поэтому проверка, чтобы увидеть, существует ли база данных, не может найти базу данных (он ищет только файл database_db.db на самом высоком уровне файловой системы, так как такой файл не будет существовать) и база данных копируется с перезаписью базы данных, в которой сохранены данные.

Я бы предложил следующие изменения: -

private boolean checkDatabase() {
    File dbfile = new File(ourContext.getDatabasePath(DATABASE_NAME).getPath());
    if ( dbfile.exists()) return true;
    File dbdir = dbfile.getParentFile();
    if (!dbdir.exists()) {
        dbdir.mkdirs();
    }
    return false;
}
  • Преимущество этого заключается в том, чтоесли каталог базы данных не существует, он будет создан и полагается исключительно на имя базы данных для пути.
  • Также нет необходимости в конструкции try / catch.

и необязательно: -

private void copyDatabase() throws IOException {
    InputStream myInput = null;
    OutputStream myOutput = null;
    String outFileName = ourContext.getDatabasePath(DATABASE_NAME).getPath(); //<<<<<<<<<< CHANGED

    try {
        myInput = ourContext.getAssets().open(DATABASE_NAME);
        myOutput = new FileOutputStream(outFileName);

        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 ie) {
        throw new Error("Copydatabase() error");
    }
}
  • Обратите внимание, что при применении вышеуказанного нет необходимости проверять версию SDK, поскольку метод getDatabasePath получает правильный путь.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...