вторник, 14 января 2014 г.

Delphi и Android. Странная бага в TSQLConnection dbExpress .

Решил прикрутить SQLite к программе на андроид.
Делал все как по инструкции Using SQLite (iOS_and_Android), однако когда у свойства Connected
объекта TSQLConnection выставляю True и запускаю прогу на устройство, программа android  уходит в черный экран и зависает до появления предложения ОС Android о закрытии зависшего приложения.

При этом в дизайнере все показывается нормально (я имею ввиду информацию с БД - в List.Item - Дачный дом берется из записи таблицы БД). Если отключить подключение к БД (Connected - False) и запустить приложение то все нормально.
В Deployment тоже все настроено по инструкции:
Код подключения для к БД для Android аналогичный примеру.

procedure TfrmMain.SQLConnectionBeforeConnect(Sender: TObject);
begin
  {$IF DEFINED(iOS) or DEFINED(ANDROID)}
  SQLConnection.Params.Values['ColumnMetadataSupported'] := 'False';
  SQLConnection.Params.Values['Database'] :=
      TPath.Combine(TPath.GetDocumentsPath, 'Ksital.s3db');
  {$ENDIF}
end;

В общем третий день чудеса. Может кто встречался с такой проблемой?

PS. Скриншот с эмулятора. 


четверг, 9 января 2014 г.

Android и Delphi XE. Хранение пользовательских данных Preferens. Аналог INI-файлов Windows

Пользовательские данные в Androide могут хранится либо в пользовательских файлах Preferens либо в БД Sql Lite, либо в обычных файлах  (например на SD-карте). Для начала рассмотрим хранение в пользовательских файлах Preferens поддерживающихся OC Android.Код простой:

unit Main;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Edit, FMX.DateTimeCtrls,
  AndroidApi.Jni.JavaTypes, AndroidApi.Jni.App,
  AndroidApi.Jni.GraphicsContentViewText,
  FMX.Helpers.Android;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    NumberBox1: TNumberBox;
    CalendarEdit1: TCalendarEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    Prefs: JSharedPreferences;
  public
    { Public declarations }
    Procedure Save;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.fmx}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
 Save;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  // Cохранение данных. Сначала с помощью метода getSharedPreferences получаем объект sPref класса SharedPreferences,
  // который позволяет работать с данными (читать и писать). Константа MODE_PRIVATE используется для настройки доступа и означает,
  // что после сохранения, данные будут видны только этому приложению.
 
  // MyData - имя файла для хранения данных.
  Prefs  := SharedActivity.getSharedPreferences(StringToJString('MyData'),  TJActivity.JavaClass.MODE_PRIVATE);
 
  Edit1.Text  := JStringToString(Prefs.getString(StringToJString('Edit1'), StringToJString('')));
  NumberBox1.Value := Prefs.getFloat(StringToJString('NumberBox1'), 0);
  CalendarEdit1.Date := StrToDate(
                  JStringToString(Prefs.getString(StringToJString('CalendarEdit1'), StringToJString('10.01.2014'))));
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
 Save;
end;
 
procedure TForm1.Save;
var
  Editor: JSharedPreferences_Editor;
begin
  // Чтобы редактировать данные, необходим объект Editor – получаем его из sPref.
  Editor := Prefs.edit;
  Editor.putString(StringToJString('Edit1'), StringToJString(Edit1.Text));
  Editor.putFloat(StringToJString('NumberBox1'), NumberBox1.Value);
  Editor.putString(StringToJString('CalendarEdit1'), StringToJString(DateToStr(CalendarEdit1.Date)));
  Editor.apply;
end;

Помимо getSharedPreferences использовать getPreferences, если хотите не выдумывать имя файла. Имя файла будет задана автоматом по имени текущего окна.
Использовать getSharedPreferences, нужно когда данные - общие для нескольких окон, а также если сами хотите выбирать имя файла для сохранения.