
Полная версия:
Программирование для Android и работа с датчиками в среде Delphi 11
if Sender = Button1 then …… else ………..
Или для получения одного результата для разных компонентов: в Events на событие OnClick (или OnChange и т.п.) из выпадающего списка для нескольких компонентов выбрать нужный: например, Button1Click, с выполняемым везде кодом.
Или: Button2.OnClick (Sender); для Button1 – выполнит Button2.
Например, для приложения «Школьный Калькулятор» за счет свойства Sender можно значительно сократить код. Для функции power (степенная функция) в Uses ввести модуль Math.
Введем глобальную переменную S1:String; к которой можно будет иметь доступ из разных участков программы. Сбросим на Форму кнопки-числа и поставим их Text от 0 до 9, а также кнопку-сброс «C» (от Clear) и вспомогательное Edit2.
Для Button1Click:
with (Sender as TButton) do
begin
if Edit1.Text = «0» then Edit1.Text:= Text
else Edit1.Text:= Edit1.Text + Text; // Ввод числа
end;
Для остальных кнопок 2…9 и 0 введем ссылку: в Events на OnClick: Button1Click; // Ввод числа с любой кнопки
Теперь нажатие на любую кнопку-число отправит ее Text (0…9) в Edit1.Text.
Введем кнопки-действия: +, -, *, /, sqr, sqrt и power, sin, cos, Tan, Ln, Log. Для каждой определим сходный код:
S1:=Edit1.Text; // Первое число в глобальную переменную
Edit3.Text:= Button16.Text; // Выводим знак операции
Edit1.Text:= ' '; // Очищаем Edit1 от 1го числа для второго
Button21.OnClick (Sender); // Ссылка на действия с числами
Свойство Sender позволяет перейти на Button2, где имеет место код для всех действий:
//Если операция над 1-м числом – квадратный корень и др.
if Edit3.Text = ’sqrt’ then // Если первым вычисляем корень
begin
Edit2.Text:= «1»;
Edit1.Text:= FloatToStr (sqrt (StrToFloat (s1)));
s1:= Edit1.Text;
EXIT;
end;
//Если 1-е число из 2-х чисел
if Edit2.Text = «1» then
begin
Edit1.Text:= ' '; // Очищаем Edit1 от 1го числа для второго
Edit2.Text:= «2»; // Отмечаем следующее нажатие как 2-е
EXIT;
end
else // Если 2-е число введено
begin
if Edit3.Text = '+' then Edit1.Text:= FloatToStr (StrToFloat (s1) + StrToFloat (Edit1.Text));
************************
Введем также операции с памятью: M+, M-, MR, MC и возможность вводить тригонометрические функции: град или Пи.
В итоге мы имеем простейший калькулятор, который, однако, с высокой точностью производит необходимые операции.

Рис. 14. Программа для смартфона «Школьный калькулятор»

Рис. 15. Инспектор свойств компонентов.
5. Типы программ в DelpHi Android
В Delphi Android существует множество компонентов и еще больше свойств и методов, но далеко не все они нужны в обычном программировании. Можно выделить несколько типов программ в зависимости от задач и сложности.
Прикладные программы.
Прикладные программы как раз и являются основной задачей для Delphi изначально, хотя теснятся сейчас множеством любителей. Между тем, на Delphi можно создать (и создано) достаточно прикладных программ, которые по виду и функционалу близки к Word и Excel.
Для частных прикладных задач для профессионалов можно создавать сложные и функциональные программы минимумом средств как в Delphi 7, так и в Delphi Android. Фактически, для практически любой программы такого типа достаточны:
Label – для надписей,
Edit – для ввода данных,
Button – для запуска операций над ними,
Memo – для вывода результатов.
Для Базы данных таких программ достаточны:
StringGrid – для накопления и отображения данных,
Chart и Sharp – для графиков.
Для работы с файлами достаточно компонента Memo, который имеет сам методы сохранения и загрузки содержимого (в него можно направить данные *.txt для файла или из файла).
Из всего комплекса свойств компонентов необходимыми и достаточными являются:
Text (Line для Memo) – для ввода названий и данных,
Align – для выравнивания на любом экране (выбрать Scale).
Из методов: математические функции для обработки данных,
Перевод число/строка (StrToFloat и FloatToStr);
Операторы цикла и условия для работы с данными:
If… then..else,
For i = n1 to n2 do.
Таким образом, изучив за день буквально десяток компонентов с несколькими методами, можно создавать сложные прикладные программы. Примером этого является, например, созданная нами профессиональная программа «Тест Здоровья», позволяющая достаточно точно определить основные параметры физического здоровья и психической работоспособности.
Как украшения добавлены картинки эмблемы (ImageViewer) и картинки на кнопки (невизуальный компонент загрузки картинок ImageList и свойство ImageIndex для кнопок).
Программы – аналоги программ смартфона.
Это программы, имитирующие Проигрыватель звуковых файлов и Видео, работу с Микрофоном и Bluetooth, Интернет и пр.
Хотя можно добиться (путем достаточно сложного программирования) сходства с функционалом рабочих программ смартфона, однако, это совершенно непродуктивно, так как имеются собственные программы, написанные именно под данный смартфон. К тому же, для работы программ с внешними устройствами самого смартфона требуются разрешения, которые достаточно сложны и не всегда работают и не на всех смартфонах.
Базы данных.
Работам с Базами данных посвящено больше половины компонентов Delphi Android, в том числе специально разработанные класс Fire…, что делает этот раздел специальным направлением программирования. Однако, для Android он практически бесполезен (в отличие от обычного типа Delphi 7), так как круг задач и возможностей для Android узок, а для прикладных программ, как видно из рисунок выше, вполне хватает для создания внутренних Баз данных уже имеющихся компонентов и методов.

Рис. 16. Ввод данных в программу «Тест Здоровье».

Рис. 17. Вывод заключения программы «Тест Здоровье».

Рис. 18. «Тест Здоровье»: База данных и график с зонами нормы.
Специальные программы.
Существуют специальные возможности работы со звуком, видео, Bluetoth и др., которые используют для создания таких программ, как:
Эквалайзер – улучшение качества звука;
Осциллоскоп – для визуализации звука;
Пульсометр – для работы с видео-сигналом;
Осциллограф – для работы с внешними сигналами; и пр.
Кроме Пульсометра, который может быть создан стандартными средствами Delphi Android (как показано в отдельной главе, посвященной работе со звуком), для таких программ требуются дополнительные библиотеки (Bass. dll), освоение которых часто сложнее обычного Delphi, причем часто бибилотеки не встраиваются в те или иные версии Delphi Android. К тому же, существует достаточно много уже реализованных программ такого типа, обычно написанных на другом языке, так как, например, Пульсометр в Delphi Android 10 и 11 оказывается недостаточно быстр и позволяет получить 5—10 кадров в сек при требованиях для кардиоинтервалографии – 20.
Для работы с внешними сигналами необходимы внешние устройства, часто создаваемые самими, или распространенные микроконтроллеры типа Arduino со своим функционалом, программированием и программами. К тому же, Осциллограф на базе смартфона или компьютера ограничен возможностями его звуковой платы, тогда как существуют дешевые аппараты осциллографы для гораздо более высоких диапазонов, в том числе способные связываться со смартфоном для передачи данных.
6. ТИПЫ ДАННЫХ В DELPHI Android
Типы данных, как обычно, объявляются перед началом самым программы (до begin) используя инициацию var:
var
x,y:Integer;
m: Double;
str1:String; // Строковая переменная.
Mas: array [1..100] of String; // Массив одномерный из 100 строк, начало с 1
Ar: array [0..9] of array [0..9] integer; // Многомерный массив,
D: array of real; // Динамический массив
MyChar: Char; // Тип для хранения простого символа.
R: TRect; //Область, ограниченную R. Left,.Top,.Right,.Bottom;
Point: TPointF;.
Численные значения: Word, Integer, Single, Double, Real; учитывая, что точность составляет 5—6 знаков, обычно используют Integer для целочисленных и Double для чисел с запятой, которые могут быть представлены также в формате Е: 3.14E+2 = 3.14E+00 = 3.14; 23.5Е-2 = 0.235. Для округления числа «x» удобно использовать Round (x), округляющий до ближайшего целого (например, превратить Single в Integer); также можно использовать для выделения целой части Trunc (x) и дробной части Frac (x); Ceil (X) – до целого в большую сторону; Floor (X) – до целого в меньшую сторону;
Для ряда функций нужно добавить пакет math в User начала программы. Доступны многие математические функции, в том числе: абсолютное значение abs (х), квадрат sqr (x) и корень квадратный из х: sqrt (x); для степенной функции преобразование: xn = exp (n*ln (x); корень n-й степени из x = exp (1/n*ln (x), хотя имеется также и функция возведения XY: Power (x,y):
var
Z: Real;
begin
Z:= Power (0.25, 0.5); {Z:= 0.5}
end;
Функция получения вероятного числа: Random (n), по умолчанию пустые скобки () – вероятное число от 0 до 1; при «n» целочисленном – целочисленное значение от 0 до «n-1».
Символы представлены типом Char: Type: Char = #0..#255; Char:= «3». Код символа можно узнать по функции Chr (n). Код ANSI: #0…255, UNICODE: первые 256 символов = ANSI. Chr (66) = B; Char 67) = C.
var
myChar: Char;
begin
myChar:= «G»; // Назначение из символьной константы
ShowMessage («Символ G = ' + myChar); // Видим: «Символ G = G»
myChar:= #65; // Назначение из целочисленной константы
ShowMessage («#65 = ' + myChar); // Получаем «#65 = А»
end;
Присваивание значения требует двоеточия перед равенством: n:= 10; обычное равенство (=) используется в булевых значениях сравнения (true/false): if n = 10 then… Неравенство: X <> Y.
Массивы: важная часть программ для накопления данных.
Могут быть:
– одномерные: Mas: array [1…100] of String; //все начинаются с 1.
– многомерныe: Ar: array [0..9] of array [0..9] of integer;
– динамический массив: D: array of real.
Перед использованием динамического массива устанавливается его длина (начинается с 0): setLeangth (D,20). Закрытие массива: D_M: =nil. элементы массива начинаются с 0, исключая строковой массив, начинающийся с 1.
Доступ к массиву по его индексу: n:= D [21]; соответственно присваивание значения элементу массива: D [21]:=n. Для заполнения массива обычно применяется конструкция цикла:
for n:= 1 to 100 dobeginD [n]:= n-1; //Нумерует компоненты массива D [100] с 0end;Можно найти максимальное и минимальное значение и среднее по массиву: MaxIntVal (D); MinVal (D): double); Mean (D):double), копировать массив в другой с компонента: D:= copy (D, 0, 20) и др.
Строки: ShortString: 255 символов и занимает в памяти
2 байта; String = AnsiString: 1031 символ. AnsiString или WideString содержат большое количество символов. В типе AnsiString символы кодируются в коде ANSI, а в типе WideString в коде Unicode. Общим типом является тип String. String [n] длин строки.
Со строками можно проводить множество операций:
– найти в строке субстроку, ее индекс: n:= Pos (subStr, str);
– копировать строку str c позиции index и числом знаков count: str1:= copy (str, index, count);
– удалить часть строки по индексу delete (str, index, count);
– вставить субстроку: insert (str1, str0, index);
– длину строки можно узнать как: length (str).
Для выравнивания строк полезна функция вставки пустых символов: StringOfChar (»», count); если использовать моноширинный шрифт, то получим идеально выровненные в столбик строчки.
SelStart и SelLength устанавливают позицию 1-го символа и длину записи, SelText – выделенный текст, весь текст выделяет SelectAll; ClearSelection очищает выделенный текст; Clear очищает текст, Undo возвращает предыдущее действие.
Для копирования текста используют CopyToClipBorad, для вставки Paste, для замены символов StringReplace (Строка, Старое значение, новое значение, Флаг [rfReplaceAll, rfIgnoreCase]). Перед копированием целесообразно выделить текст для копирования; Memo.CopyToClipBorad ничего не копирует, для копирования всего содержимого компонента Memo нужно предварительно выделить его содержимое:
Memo.SelectAll; Memo.CopyToClipBorad
Перевод каретки: string1 + #13#10 + string2 (перевод каретки и конец строки с переносом string2 на другую строку).
Изменение типов проводится очень часто, обычно для передачи строкового значения в числовое и наоборот, используют: StrToInt; InToStr; StrToFloat (str); для форматирования: FloatToStrF (str, ffGeneral или ffFixed, count знаков всего, count знаков после запятой. Для Single: x:=Round (x). Для преобразования строки/байты в UTF-8:
bytes:= TEncoding.UTF8.GetBytes (str);
str:= TEncoding.UTF8.GetString (bytes);
TEncoding.ANSI.GetString (Byte);//String из Byte
Строки Java. Для обращения к Java напрямую используют модуль Uses Androidapi. Helpers. Так можно преобразовывать строки:
function JStringToString (const JStr: TJString): String;
function StringToJString (const Str: String): JString;
То же для StrToJCharSequence и StrToJURI.
Дата и Время. Имеется значительное число возможностей работы с датой, но обычно достаточно узнать настоящую дату DateToStr (Now): и текущее время: TimeToStr (Now) и DateTimeToStr (Now).
Форматы представления даты:
dd/mm/yy hh: mm: ss = 09/02/49 01:02:03 mmm = Feb
mmmm = February ddd = Tue
dddd = Tuesday ddddd = 09/02/2049
dddddd = 09 February 2049 hhampm = 01AM
t = 01:02
tt = 01:02:03
dd/mm/yyyy = 09/02/2049
dd/mm/yy hh: mm: ss = 09-02-49 01_02_03 mmm = FEB
mmmm = FEBRUARY ddd = WED
dddd = WEDNESDAY
ddddd = 09-FEB-49
dddddd = WEDNESDAY 09 of FEBRUARY of 1949
hhampm = 01morning t = 01_02_03
tt = 01 _ 02 _ 03. 004
dd/mm/yyyy = 09-02-1949
Для отсчета времени в Delphi 10—12 имеется такой же компонент, как и ранее: Timer, запускающийся при присвоении функции Timer. Enable:= true и выключаемый …false; имеет единственное действие, повторяемое через задаваемый промежуток времени (в мСек). Однако, кроме малой точности (50 мСек) при достаточно нагруженной программе он действует крайне медленно, так что практически часто мало пригоден (хотя вне Android работает вполне точно и хорошо). Для получения времени между 2-мя событиями удобнее использовать функции даты-времени:
var // На Кнопку Start
str, h, m, s: String; t1:Integer;
begin
str:= DateTimeToStr (Now); // Начальное время
h:= Copy (str,, 2);// Отсекаем Дату и сразу берем Часы
m:= Copy (str, 15, 2);
s:= Copy (str, 18, 2);
t1:= StrToInt (h) *3600 + StrToInt (m) *60+ StrToInt (s);
Edit1.Text:= IntToStr (t1); //Текущее время в сек
end;
var // На Кнопку Stop
str, h, m, s: String; t, t1, t2:Integer; begin
str:= DateTimeToStr (Now); // Конечное время h:= Copy (str,12,2);
m:= Copy (str,15,2);
s:= Copy (str,18,2);
t2:= StrToInt (h) *3600 + StrToInt (m) *60+ StrToInt (s); t1:= StrToInt (Edit1.text);
t:= t2 – t1;
Edit3.Text:= IntToStr (t); // Итоговое прошедшее время
end;
Можно также использовать функцию разбора времени:
var
Hour, Min, Sec, Msec: Word;
begin
DecodeTime (Now, Hour, Min, Sec, Msec);
Edit1.Text:= IntToStr (Hour) +IntToStr (Min) +IntToStr (Sec) + IntToStr (Msec);
end;
в мСек:= Hour*60*60*1000 + Min*60*1000 + Sec*1000 + Msec;
TGUID
GUID (Globally Unique Identifier) в Delphi является8-битным идентификатором и используется для уникальной идентификации объектов или компонентов приложения. Обычно представляется в формате шестнадцатеричного числа из 32 цифр, разделенных дефисами. В Windows редактор библиотеки типов автоматически генерирует GUID для новых интерфейсов; также можно сгенерировать GUID, нажав CTRL + SHIFT + G. Пример с GUID:
var
MyGuid1: TGUID;
begin
// Создание нового GUID из строки текста
MyGuid1:= StringToGUID (» {00020400-0000-0000-C000—000000000046}»);
//Отображение в Memo заданного GUID
Memo1.Lines.Add («Заданный GUID: ' + GUIDToString (MyGuid0));
end;
Пример создания Массива (на 2 элемента):
const
MyGuid1 =» {99BDAB12-B1B6—41B0—9BF1—2C1DB3D8EC70}»;
MyGuid2 =» {8C7CD303—8D81—469B-99ED-E1F163E9036F}»;
const
MyArray: array [0..1] of TGUID = (MyGuid1, MyGuid2);
begin
***************
end;
Элемент массива можно создать и запитать им, например, элемент ALRealToAudio из AudioLab, который может получать данные из массива:
x:= StrToInt(Memo2.Lines [i]);
MyArray[0].Create (x);
ALRealToAudio1.InputPins.Pins[0].IsConnectedByIDs (MyArray);
Целый ряд компонентов имеет выход с GUID, что позволяет им взаимодействовать также и с заранее не определенными данными компонентов.
7. ВКЛАДКИ КОМПОНЕНТОВ
Базовые компоненты находятся на вкладке Standard, вклад ка Additional используется значительно меньше, так как ее эле менты практически дублируют вкладку Standart; из вкладки System используют компонент Timer, вкладка Win 32 исчезла.
Компонент Таблица представлен во вкладке Grids двумя таблицами – обычной строковой StringGrid и Grid в котором можно использовать самые разные типы данных и вставлять другие компоненты, также отдельный компонент Заглавие – Header.
Желание разнообразить возможности рисования обернулись их резким усложнением, однако, появилась вкладка Shapes, где представлены различне компоненты: прямоугольник, круг, овал, дуга, линия, подпись и другие типичные элементы рисунков, свойства которых можно задавать программно и рисовать или создавать графики. Компоненты графиков представлены PlotGrid с сеткой и осями координат, на котором фактически нужно рисовать график вручную, а также обычным Chart из TeeChartLite группы.
Вкладку Effects, задуманная для придания красивого вида элементов, использовать можно разве, чтобы сделать хоть как-то видимым компонент Edit. Различные эффекты мигания, скручивания, жалюзи и пр., как и ротация, доступная практически для всех элементов, предназначены для анимации (как и вкладка Animations, вкладка Styles и вкладки для 3D вида компонентов), к которой сам Delphi как раз не предназначен, и работать на смартфоне будет медленно, для прикладных программ это вооб ще дурной тон.
Видимо, вкладка LiveBinding, нововведение авторов языка Firemonkey, отслеживающая «жизнь» компонентов и их связь между собой, также вряд ли подойдет для привыкших к обычному программированию из-за множества специфических функций, которые легко заменить обычными методами Delphi.
Вкладка Color представлена множеством компонентов для работы с цветом, часто взаимодействующими между собой, и также скорее подходят для анимации, чем для прикладных программ. Определенный интерес представляет, возможно, простой ColorBox. Для создания цветового градиента с целью приданию графику вида «зеленая и красная области» подойдут два компонента Rectangle (прямоугольник) из вкладки Shapes, на которые накладываются другие прямоугольники уже как графики данных.
Как уже отмечалось, важными элементами приложения являются компоненты их вкладки Layouts, отвечающие за выравнивание компонентов, в них находящихся, хотя со времен первых вариантов Delphi эту функцию успешно играет компонент Панель – Panel.
Вкладка Common Control представлена рабочими элементами – TabControl и MultiView. Важнейшая вкладка Dialogs в Delphi 10, 11, отсутствует (вернее, не доступна для платформы Android).
Целый ряд вкладок предназначен для работы с Базами данных, в том числе SQL и специальная с широкими возможностями – Fire, вместе с вкладками для работы в Интернет.
Особое значение для Android имеют компоненты работы с элементами смартфона: камерой, сенсорами, аудиоплеером, интернетом, Bluetooth (вкладка Systems), что, впрочем, гораздо лучше делает сам смартфон; нужны специальные разрешения!
Для обычной работы каждого приложения понадобятся:
– из вкладки Standard: Label (метка), Edit (окошко), Memo (многостраничный текстовый компонент, аналог отсутствующего RichEdit), Button (кнопка), CheckBox или RadioButton для выбора различных условий, ListBox (списки), ImageControl вместе с ImageList и Panel для ввода иконок и картинок.
– из вкладки Addinional: PlotGrid для графиков, NumberBox для ввода числовых значений, ComboEdit для сложного ввода;