tria Опубликовано 14 декабря, 2021 Поделиться Опубликовано 14 декабря, 2021 Перевожу проект с WinCE (Lazarus) под Андроид (Ембарк Делфи 10.4). До этого под Андроид не писал. В проекте используется файл базы данных. Его при установке ПО нужно сразу положить в доступном месте. В БД будут писаться данные. Как это сделать? Я так понял, нужно указать файл БД в Deployment, но что нужно указывать в Remote path и что потом указать в FDConnection1.params.database? Цитата Ссылка на комментарий
0 OnePeople Опубликовано 15 декабря, 2021 Поделиться Опубликовано 15 декабря, 2021 Если будете загружать файл в 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 Ingalime 1 Цитата Ссылка на комментарий
0 tria Опубликовано 15 декабря, 2021 Автор Поделиться Опубликовано 15 декабря, 2021 Спасибо. Сегодня с утра сдвинулось. Цитата Ссылка на комментарий
0 tria Опубликовано 15 декабря, 2021 Автор Поделиться Опубликовано 15 декабря, 2021 Только возникли след. вопросы. В каком модуле TPath? А то я пока обошелся GetHomePath. И главное, в Deployment в колонке Overwrite стоит Always, а при отладке вижу, что база не перезаписана (я пробовал делать запись в БД и вижу, что при каждой отладке эта запись уже есть). Цитата Ссылка на комментарий
0 tria Опубликовано 15 декабря, 2021 Автор Поделиться Опубликовано 15 декабря, 2021 TPath нашел в System.IOUtils. Вопрос с перезаписью не решился... Цитата Ссылка на комментарий
0 OnePeople Опубликовано 16 декабря, 2021 Поделиться Опубликовано 16 декабря, 2021 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'); Ingalime 1 Цитата Ссылка на комментарий
0 Sascha Опубликовано 16 декабря, 2021 Поделиться Опубликовано 16 декабря, 2021 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 OnePeople Опубликовано 16 декабря, 2021 Поделиться Опубликовано 16 декабря, 2021 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. Ingalime 1 Цитата Ссылка на комментарий
0 Tot999 Опубликовано 19 декабря, 2021 Поделиться Опубликовано 19 декабря, 2021 Насколько помню по своей возне четырёхлетней давности с тогдашним Rad Studio. Проблема перезаписи БД из Deployment решалась постоянным увеличением версии программы, т.е. перед запуском на тест уcтройстве, надо заходить в настройки проекта и менять Version. Как сейчас обстоят дела - хз. Саня 1 Цитата Ссылка на комментарий
0 bfarid Опубликовано 1 августа Поделиться Опубликовано 1 августа А как сравнить даты баз данных в Assert и на смартфоне, чтобы переписать новый файл? Цитата Ссылка на комментарий
0 Slym Опубликовано 1 августа Поделиться Опубликовано 1 августа (изменено) Сравнить (как файлы) можно размеры... Разные - значит обновлять. Как данные - сравнением данных - сохранить как временную базу и позаписьно сравнивать Изменено 1 августа пользователем Slym Цитата Ссылка на комментарий
0 bfarid Опубликовано 1 августа Поделиться Опубликовано 1 августа То есть доступа к информации о файле базы данных в Assert в Delphi нет? Нужно временно копировать в память смартфона и затем сравнивать (по дате, размеру...) - не очень красиво. Цитата Ссылка на комментарий
0 bfarid Опубликовано 1 августа Поделиться Опубликовано 1 августа Или получить дату apk как-то. Цитата Ссылка на комментарий
0 OnePeople Опубликовано 1 августа Поделиться Опубликовано 1 августа Я делаю так, сравниваю версию приложения (а именно билд), если версия новее, то обновляю асеты, если нет то нет. Можно сделать при обновлении асетов сохранять в настройки данные о базе и при обновлении сравнивать эти данные (например дату обновления базы, или версия базы) вариантов много. Цитата Ссылка на комментарий
0 bfarid Опубликовано 1 августа Поделиться Опубликовано 1 августа (изменено) Разумно. Правда билд всегда будет выше (иначе не загрузить на маркетплейс), а база может быть той же. В настройках получше. Хотелось автоматически. Изменено 1 августа пользователем bfarid Цитата Ссылка на комментарий
0 OnePeople Опубликовано 1 августа Поделиться Опубликовано 1 августа Все верно, но только если база обновится при установке новой версии на ту же самую ни чего страшного не произойдет, а вы будете уверены что база у вас в актуальном состоянии. Конечно если вы не обновляете свое приложение каждый час, тогда да будет запуск долгий каждый раз, а так раз в месяц на секунду запуск дольше, думаю пользователи это перенесут, ИМХО сугубо мое мнение. Цитата Ссылка на комментарий
0 bfarid Опубликовано 1 августа Поделиться Опубликовано 1 августа (изменено) После того, как обновили программу (apk), билд программы будет только один и его нельзя сравнить. Тогда скорее при запуске программы нужно сравнить дату apk и базы данных на смартфоне. Или использовать дату в настройках. Или возможно что-то не понимаю. Изменено 1 августа пользователем bfarid Цитата Ссылка на комментарий
0 OnePeople Опубликовано 1 августа Поделиться Опубликовано 1 августа Да конечно вы обновляете программу при старте программа проверяет билд(дату или любые данные которые позволяют узнать что база новее) сохраненный в настройках с текущим билдом(датой и т.д). По другому никак, так как установочный файл и установленная программа к друг другу не имеют ни какого отношения. Почему я писал что я проверяю по билду, мне кажется что так удобнее билд это 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 bfarid Опубликовано 3 августа Поделиться Опубликовано 3 августа (изменено) Не получалось обновить файл. Нашел свою ошибку - вместо UpdateAsset('fcatalog.sqlite', System.IOUtils.TPath.GetPublicPath) нужно UpdateAsset('fcatalog.sqlite', System.IOUtils.TPath.Combine(System.IOUtils.TPath.GetPublicPath,'fcatalog.sqlite')). Подумал, что FilePath это путь, а не путь с файлом. Изменено 4 августа пользователем bfarid Цитата Ссылка на комментарий
Вопрос
tria
Перевожу проект с WinCE (Lazarus) под Андроид (Ембарк Делфи 10.4).
До этого под Андроид не писал.
В проекте используется файл базы данных. Его при установке ПО нужно сразу положить в доступном месте.
В БД будут писаться данные.
Как это сделать?
Я так понял, нужно указать файл БД в Deployment, но что нужно указывать в Remote path и что потом указать в FDConnection1.params.database?
Ссылка на комментарий
18 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.