Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как вместе с программой установить файл базы данных?


tria

Вопрос

Перевожу проект с WinCE (Lazarus) под Андроид (Ембарк Делфи 10.4).

До этого под Андроид не писал.

В проекте используется файл базы данных. Его при установке ПО нужно сразу положить в доступном месте.

В БД будут писаться данные.

Как это сделать?

Я так понял, нужно указать файл БД в Deployment, но что нужно указывать в Remote path и что потом указать в FDConnection1.params.database?

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Если будете загружать файл в deployment тогда ваша база будет здесь 

Для remote path: assets\internal

TPath.Combine(TPath.GetDocumentsPath, 'filename')  { Internal }

Для remote path: assets

TPath.Combine(TPath.GetPublicPath, 'filename')  { External }

Есть же в конце то концов https://docwiki.embarcadero.com/RADStudio/Sydney/en/Creating_an_Android_App#Loading_and_Deploying_Files

Ссылка на комментарий
  • 0

Только возникли след. вопросы.

В каком модуле TPath? А то я пока обошелся GetHomePath.

И главное, в Deployment в колонке Overwrite стоит Always, а при отладке вижу, что база не перезаписана (я пробовал делать запись в БД и вижу, что при каждой отладке эта запись уже есть).

Ссылка на комментарий
  • 0
procedure TForm1.UpdateAsset(AssetName, FilePath: String);
var
  inputStream: JInputStream;
  FileOutputStream: JFileOutputStream;
  WData: TJavaArray<Byte>;
  LData: Integer;
begin

  try
  InputStream :=  TAndroidHelper.Context.getAssets.open(StringToJString(AssetName));
  except
    exit;
  end;

  try
  FileOutputStream := TJFileOutputStream.JavaClass.init(StringToJString(FilePath));
  except
    exit;
  end;

  WData := TJavaArray<Byte>.Create(4096);
  repeat
   try
       LData := InputStream.read(WData);
   except
       LData := -1;
   end;

  if LData <> -1 then
     begin
        FileOutputStream.write(WData, 0, LData);
     end;
  until (LData = -1) or (LData = 0);

  FileOutputStream.flush;
  FileOutputStream.close;
  inputStream.close;

end;

Обновление файла из assets в папку с программой

Пользоваться так проверяете при Form.Create что версия новая и вызываете UpdateAsset('internal/base.db', ApplicationPath + 'base.db');

 

 

Ссылка на комментарий
  • 0
29 минут назад, OnePeople сказал:
procedure TForm1.UpdateAsset(AssetName, FilePath: String);
var
  inputStream: JInputStream;
  FileOutputStream: JFileOutputStream;
  WData: TJavaArray<Byte>;
  LData: Integer;
begin

  try
  InputStream :=  TAndroidHelper.Context.getAssets.open(StringToJString(AssetName));
  except
    exit;
  end;

  try
  FileOutputStream := TJFileOutputStream.JavaClass.init(StringToJString(FilePath));
  except
    exit;
  end;

  WData := TJavaArray<Byte>.Create(4096);
  repeat
   try
       LData := InputStream.read(WData);
   except
       LData := -1;
   end;

  if LData <> -1 then
     begin
        FileOutputStream.write(WData, 0, LData);
     end;
  until (LData = -1) or (LData = 0);

  FileOutputStream.flush;
  FileOutputStream.close;
  inputStream.close;

end;

Обновление файла из assets в папку с программой

Пользоваться так проверяете при Form.Create что версия новая и вызываете UpdateAsset('internal/base.db', ApplicationPath + 'base.db');

 

 

а почему вообще возникает необходимость писать этот костыль?

почему Overwrite = Always в деплойменте не работает???

Ссылка на комментарий
  • 0
1 час назад, Sascha сказал:

а почему вообще возникает необходимость писать этот костыль?

почему Overwrite = Always в деплойменте не работает???

Можно не писать в startupcopy.pas есть методы обновления ассетов. Самому лень писать))))

I feel that files that need to be deployed are files that should not and need not be changed by the application. They are resources like images. If an application changes a file, it does so with intent. The user via the developer wanted it that way. Changing it back through an update causes data loss. As a consequence all files that could be subject to change should not be deployed but generated when used.

Ссылка на комментарий
  • 0

Насколько помню по своей возне четырёхлетней давности с тогдашним Rad Studio. Проблема перезаписи БД из Deployment решалась постоянным увеличением версии программы, т.е. перед запуском на тест уcтройстве, надо заходить в настройки проекта и менять Version. Как сейчас обстоят дела - хз.

Ссылка на комментарий
  • 0

Сравнить (как файлы) можно размеры... Разные - значит обновлять.
Как данные - сравнением данных - сохранить как временную базу и позаписьно сравнивать

Изменено пользователем Slym
Ссылка на комментарий
  • 0

То есть доступа к информации о файле базы данных в Assert в Delphi нет? Нужно временно копировать в память смартфона и затем сравнивать (по дате, размеру...) - не очень красиво.

Ссылка на комментарий
  • 0

Я делаю так, сравниваю версию приложения (а именно билд), если версия новее, то обновляю асеты, если нет то нет. Можно сделать при обновлении асетов сохранять в настройки данные о базе и при обновлении сравнивать эти данные (например дату обновления базы, или версия базы) вариантов много.

Ссылка на комментарий
  • 0

Разумно. Правда билд всегда будет выше (иначе не загрузить на маркетплейс), а база может быть той же. В настройках получше. Хотелось автоматически.

Изменено пользователем bfarid
Ссылка на комментарий
  • 0

Все верно, но только если база обновится при установке новой версии на ту же самую ни чего страшного не произойдет, а вы будете уверены что база у вас в актуальном состоянии. Конечно если вы не обновляете свое приложение каждый час, тогда да будет запуск долгий каждый раз, а так раз в месяц на секунду запуск дольше, думаю пользователи это перенесут, ИМХО сугубо мое мнение.

Ссылка на комментарий
  • 0

После того, как обновили программу (apk), билд программы будет только один и его нельзя сравнить. Тогда скорее при запуске программы нужно сравнить дату apk и базы данных на смартфоне. Или использовать дату в настройках. Или возможно что-то не понимаю.

Изменено пользователем bfarid
Ссылка на комментарий
  • 0

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

PackageManager := TAndroidHelper.context.getPackageManager;

PackageManager.getPackageInfo(TAndroidHelper.context.getPackageName, 0).versionCode;

А дальше смотрим билд в настройках     

SPStart := TAndroidHelper.Context.getSharedPreferences(OptionsFile, TJContext.JavaClass.MODE_PRIVATE);

buildApkInSet := SPStart.getInt(StringToJString('apkBuild'), 0);

 

Ссылка на комментарий
  • 0

Не получалось обновить файл. Нашел свою ошибку -  вместо UpdateAsset('fcatalog.sqlite', System.IOUtils.TPath.GetPublicPath) нужно UpdateAsset('fcatalog.sqlite', System.IOUtils.TPath.Combine(System.IOUtils.TPath.GetPublicPath,'fcatalog.sqlite')). Подумал, что FilePath это путь, а не путь с файлом.

Изменено пользователем bfarid
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...