Jump to content
ТУК НЕ СЕ ПРЕДЛАГАТ ХАКЕРСКИ УСЛУГИ ! ×

Recommended Posts

ВМЕСТО ПРЕДГОВОР

Здравейте,

Това е тема за мултиплатформено програмиране на Delphi.

Преди да простъпим към същността на въпроса (един код за Windows, Linux, iOS и Andeoid), бих желал да направя малки разяснения.

Delphi не е просто Object Pascal, както масово се твърди. Има сходство в синтаксиса и донякъде в логиката и с това всичко се изчерпва.

Delphi е изключително мощен инструмент, който няма аналог към настоящият момент. На Delph може да създавате както приложен, така и системен софтуер. Горещо ви препоръчвам да посетите официалният сайт на колегата Боян Митов URL:  https://www.mitov.com/ за да получите малка представа как и за какво може да ползвате този изключително мощен инструмент.

Друга голяма заблуда е, че на Delphi не могат да се пишат игри. Това не просто  не е вярно, но и е абсурдно. Все пак такива заглавия като Diablo, Civilization, Dune и много други (тук визирам само тези, които са реализирали най-голяма печалба) са написани на Delphi.

Но това за което ще говорим е много по-сериозно.

Малцина имат предства какво може да се направи на Delphi, когато говорим за мобилни приложения. 

Сами ще се убедите, че всичко, което масово се твърди за Android (да се чете Linux), за iOS (da se ète XENIX, което пък е разновидност на UNIX) и за браузърите е много далеч от истината.

Предполагам, че на мнозина истината няма да им хареса, но това е техен проблем.

За голямо съжаление индийските програмисти, пренесоха на Запад не само математическите си познания, но и кастовото си мислене (все пак всички индийски програмисти са от кастат на търговците в прекия смисъл на тази дума) с всички произтичащи от това последици.

След 2000 година започна процес на деградация в IT отрасъла, който продължава и до днес. Едва преди няколко месеца след като тази криза нанаесе поредното си поражение бе взето решение да се пристъши към противодействие на опитите на определени кръгове да унищожат софтуерната индустрия. Ние подкрепяме тази инициатива и ще направим каквото е по силите ни. тези уроци са част от програмата, която следваме.

Но нека започнем ...

За да тествате примерите е добре да изтеглите Delphi Community Edition от следния адрес:

 

https://www.embarcadero.com/products/delphi/starter

 

Препоръчвам ви да направите пълна инсталация, тъй като основно ще работим с FMX (подробно ще говорим за това съкращение).

 

Когато се научим да правим приложение ще ви науча как да ги продавате в GooglePlay, Apple Store и Microsoft Store.

Ако обаче сте заклети привърженици на оутсорсинга и твърдо вярвате, че всичко се свежда до писане на скриптове, ако се страхувате да създадете собствен буизнес и да печелите пари, то спрете до тук и не четете повече тази тема.

Изборът остава за вас

 

С уважение

Георги Тодоров Герасимов (Avatara)

CSA BS NGIT

  • Thanks 1
Link to post
Share on other sites

КАК МОЖЕ ДА ПОЛУЧИМ ПЪЛНИ АДМИНИСТРАТИВНИ ПРАВА НАД ТЕЛЕФОНА (И НЕ САМО)

Независимо кой какво твърди, ако ползвате Delphi, нямате никакъв проблем да напишете приложение, което ви дава пълен административен достъп над всичко. Искам да подчертая, че този достъп не е само и единствено върху операционната система, а и върху апаратната част.

Важно е да разберете, че в случая няма никакво значение дали става дума за телефон, персонален компютър или сървър. Ако използваната ОС е Linux, Android или iOS, вие вече сте си осигурили стратегическо предимство. Можете да правите каквото пожелаете и нито един системен администратор не може да ви попречи.

Но ... Тъй като ние сме етични, ще ви запозная как може да направите това на собствения си телефон.

Избрах умишлено Android, защото обективно погледнато това е Linux. Това, което мога да направя за Android ще работи без проблем и на всеки Linux сървър (визирам управлението на операционата система като такава и не само това).

Време е да пристъпим към нещо сериозно.

За разлика от други уроци в които ще ви обясняват за цикли, броячи, матрици, обекти, стекове и пр., тук няма да се занимаваме със суха и абсолютно безполезна теория. Много добри майстори на бойни изкуства са яли здрав пердах на улицата, защото просто там няма правила.

Това, което ще направим е да подходим следвайки тази логика. Първо забравяме за правилата и всичко, което сме учили (най-вече това което се пише в internet).

Практиката е най-добрият учител, а личното ми мнение е, че няма как да усвоите и да разберете теорията, aко нямате лични наблюдения върху реалните проблеми.

И така, да започнем ...

Като начало ще стартираме Delphi Community Edition 

От менюто File избирате New >  Multi-Device Application Delphi (така както е показано на изображението).

 

L_001.thumb.png.bd1d52937ab1dd0172af558329fb99e6.png

 

Следващата стъпка е да изберете вида на мобилното приложение.

За първото си приложение избираме Blank Application. 

Обещавам да отделим специално внимание на всяка една възможност, която имаме, защото наистина възможностите, които са ни предоставени са много големи.

 

L_002.thumb.png.09cf195fc955c036a2f4ed1a85b7de66.png

 

След като сме избрали вида на приложението трябва да укажем каква ще бъде използваната операционна система (на която ще правим тестове).

Държа да подчертая, че най-добре е ако правите игри или приложения, ползващи големи бази данни да си работите под Windows, но тъй като тук идеята е да демонстрираме как може да управляваме "желязото" в Android, ние ще изберем тази оперционна система.

 

L_003.thumb.png.6105fc41290d77724904e098e84ab831.png

 

За да бъдат тестовете коректни, аз включих към компютъра една старичка Motorola, но може да направите това с всякакво друго устройство. Просто ползвате USB кабел и следвате инструкцията. 

В този случай компилацията ще се извърши на мобилното устройство, а не на компютъра. Важно е да разберете това. А защо е важно ще говорим в следващите публикации. Сега искаме да получим административен достъп до ... всичко.

За да направим това е нужно да укажем какви права ще ни даде нашето приложение.

За целта oт менюто Project избираме Options или натискаме Shift+Ctrl+F11.

 

L_004.thumb.png.ae7f605da3a10cc90912f4cd51a46420.png

 

Тук имаме много и разнообразни настройки (в т.ч. и такива, който са свързани с последващи продажби), но ние ще се концентрираме върху User Permissions (права на достъп на потребителя). 

 

L_005.thumb.png.1e74e9cea59dad0740eb7fef36ec3791.png

 

Както сами може да се убедите, пред погледа ни се разкрива невиждана красота, която би накарала всеки един кодер да завие от безсилна ярост. 

Без да сме написали нито ред, ние можем д определин къде как и в какви гранници ще управляваме всеки един от елементите на операционната система. Но това не е всичко. Ние можем да получим достъп до системите за геопозициониране, камерата, микрофона, виртуалната клавиатура и пр. и пр. и пр, с една дума до ... всичко.

Тук има един доста забавен момен, който не мога да не спомена.

Вие можете да направите така, че привилегиите ви като потребители да се променят динамично в процеса на изпълненеи на приложението.

Може да направите нещо още по-забавно - да наложите рестрикции (забрана) на потребителите да използват един или друг елемент от системата. Тук възможностите са неограничени, но като начало ние ще се спрем на най-важната за нас

Как да получим пълна информация за устройството?

  • Thanks 1
Link to post
Share on other sites

След като вече сме набелязали основната цел е редно да пристъпим към изпълнението и.

И тук отново няма нищо сложно. Като начало е добре да се запознаем със служебната информация на Android. Повярвайте няма нищо по-добро от техническата документация. Знанието е ваше основно оръжие.

Преди обаче да пристъпим към сериозни действия е нужно да решим къде ще извеждаме информацията.

Най-лесният вариант е да използваме TMemo и да добавяме ред по ред, но ... ние създаваме мобилно приложение а то има своя логика.

Запомнете - логиката на мобилните приложения се различава диаметрално от тази на компютърните.

При мобилните приложения нямате модални прозорци и като цяло всичко е пълноекранно.

Това, както и много други неща са в състоянире да създат доста серизни проблеми на всеки програмист.

Нека се опитаме да извлечем максимална информация за използваното устройство.

Като начало от палитрата със стандартни компоненти (Standard, намира се в дясно, а отгоре има надпис Palete) избираме TListBox. Това е много интересен компонент, на който ще отделим специално място в нашите по-нататъшни разглеждания. Ако трябва да бъда искрен това е най-масово използвания компонент при разработка на мобилни устройства. Използва се за какво ли не и по какъв ли не начин. Най-често се среща при месенджърите, файловите мениджъри и други подобни приложения.

В нашият случай ще използваме TListBox за да изведем системната информация на дисплея на мобилното устройство.

 

L_006.thumb.png.b416037e1e4f231c285e3db74f95c041.png

 

В Properties указваме как ще бъде позициониран компонента на екрана.

В нашия случай избираме Client, което означава, че той ще заеме цялата свободна клиентска зона, така както се вижда на изображението.

 

Признавам, че това е доста забавна операционна система. Използва се доста Java, а и като цяло следва до болка познатата логика на UNIX. 

Както вече споменах, първо изчитаме внимателно служебната информация. От там ние научаваме, че при Android системните библиотеки са написани на Java (не бива да се бърка с Java Script, защото е много различно). 

За да реализираме достъп до системната информация ще използваме Android АПИ, който както вече споменахме е написан  на Java. За целта е нужно да добавим няколко системни библиотеки. Тези библиотеки ще ни позволят в максимална степен да използваме Java Native Interface (JNI).

Но нека първо поясним какво трябва да се разбира под JNI.

Най-просто казано това е  стандартен механизъм, който позволява виртуалната Java машина  (JVM) да изпълнява код,  написан на Delphi. 

На практика не е нужно използваме Java. Така  кодът на приложението ще бъде изцяло на Delphi. 

В конкретния случай ние използваме JNI за да получим достъп до пълната функционалност на Android API. 

 

L_007.thumb.png.65ad369a2c957360cec93cc3f30b72c4.png

 

Ето самият код:

  {$IFDEF ANDROID}
    Androidapi.JNI.JavaTypes,
    Androidapi.JNI.Os,
    Androidapi.Helpers,
  {$ENDIF}

 

Обърнете внимание на индтрукциите в зелено.

{$IFDEF ANDROID} - Това е инструкция на компилатора. Запомнете, че при Delphi кодът се компилира. За разлика от скриптовете, тук приложението е набор от машинни инструкции, които се изпълняват на много ниско ниво. В случая ние казваме на компилатова, че ако използваната операционна система е Android то той трябва да изпълни кода, който е заключен между {$IFDEF ANDROID} и {$ENDIF} 

Ако обаче операционната система е друга (да кажем Linux или iOS) този код няма да се изпълни.

Ако пищем за iOS просто заменяме ANDROID с iOS. Получава се нещо от вида:

{$IFDEF IOS}

  iOS библиотеки

{$ENDIF}

 

Следващите стъпки могат които ще предприемем е да задаваме определени запитвания към системата и да записваме получените отговори в TListBox.

Преди това обяче ще разпишем процедура, която ще ни позволи да извеждаме получената информация в TListBox.

Ето как изглежда тя:

 

// ADD DEVICE INFO TO SYSTEM INFO LIST BOX
procedure TSystemForm.AddInfoToListBox(ItemText: String);
var
  NewItem: TListBoxItem;

begin

    SystemInfo.Items.BeginUpdate;

    NewItem:= TListBoxItem.Create(Self);
    NewItem.Parent:= SystemInfo;
    NewItem.Text := ItemText;

    SystemInfo.Items.EndUpdate;

end;
 

В тази процедура няма нищо сложно. 

Първо дефинираме началото на процес на обновяване на информацията в TListBox.

Това не е задължително, но е добре да се прави. В случая не става дума за проява на стил, а за предпазна мярка. Ако паралено е стартиран друг активен процес, автоматично ще бъде предотвратена опасността от възникване на конфликт. 

Следващата стъпка е да създадем нов TListBoxItem.

Естествено, че това ще бъде TListBoxItem, който е елемент от нашият TListBox.

В нашето приложение ние сме го нарекли SystemInfo.

Тъй като TListBox, не е нищо повече от линеен списък, чиито елементи са обекти, едно от свойствата на които е Text (String, символен низ), ние просто трябва да просвоим информацията за отделния системен елемент на полето Text.

След като приключим с добавянето на елемент в TListBox, информираме системата, че процесът е приключен.

 

Следващата стъпка е да получим информация за системата.

Тук също няма нищо сложно. 

 

// GET DEVICE INFO
procedure TSystemForm.DeviceInfo;
var
  Version: TAndroidVersion;

  CodeName : String;
  SystemInfo: String;

begin

    CodeName:= 'Unknown';

    Version:= TAndroidVersion(TJBuild_VERSION.JavaClass.SDK_INT);

    SystemInfo:= Format('Device Type(model): %s', [JStringToString(TJBuild.JavaClass.MODEL)]);
    AddInfoToListBox(SystemInfo);

    . . . 

 

Обърнете внимание на TAndroidVeersion. Това е тип.

Android има различни версии и е добре да може информацията за тях периодично да се актуализира.

Ето какво имаме към момента:

type TAndroidVersion = (
  UNKNOWN,
  BASE,
  BASE_1_1,
  CUPCAKE,
  CUR_DEVELOPMENT,
  DONUT,
  ECLAIR,
  ECLAIR_0_1,
  ECLAIR_MR1,
  FROYO,
  GINGERBREAD,
  GINGERBREAD_MR1,
  HONEYCOMB,
  HONEYCOMB_MR1,
  HONEYCOMB_MR2,
  ICE_CREAM_SANDWICH,
  ICE_CREAM_SANDWICH_MR1,
  JELLY_BEAN,
  JELLY_BEAN_MR1,
  JELLY_BEAN_MR2
);
 

както вече бе споменато са различни версии на операционната система, но ако трябва да бъдем точни това са псевдоними или търговски наименования.

 Обърнете внимание как се изписват. Трябва да се познава в детайли операционната ситема, която е обследвана. 

 

Пример:

Android Froyo е версия на Android, която вече не се поддържа, но се ползва. Включва версии от 2.2 до 2.2.3. За първи път за Froyo се споменава на 20 май 2010 година по време на конференцията Google I/O 2010. 

Тази версия е първата при която в Android се използват USB модеми и Wi-Fi-hot-spot. за първи път при нея се появява Android Cloud to Device Messaging (C2DM) и още много други неща.

 

 

След като сме получили версията от TJBuild_VERSION.JavaClass.SDK_INT може да извлечем и останалата системна информация.

 

За да получим информация за модела използваме  JStringToString(TJBuild.JavaClass.MODEL).

Обърнете внимание, че ние ползваме функция JStringToString. Тази функция преобразува Java низ в нормален Unicode символен низ.

Важно е да знаете, че има разлика между Unicode, UTF-8, UTF-16, UTF-32, ASCII и пр..

Въпросът с кодировките е от изключителна важност и е обект на отделни разглеждания.

 

Последната стъпка е да определим, кога ще се активира процедурата за анализ на системните данни. 

В нашия случай това ще стане, когато приложението се визуализира.

 

// ON FORM SHOW
procedure TSystemForm.FormShow(Sender: TObject);
begin

    {$IFDEF ANDROID}
    DeviceInfo;
    {$ENDIF}

end;
 

Пълният код на приложението има следния вид:

 

unit SystemUnit;

interface

uses

  {$IFDEF ANDROID}
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.Os,
  Androidapi.Helpers,
  {$ENDIF}

  System.SysUtils,
  System.Types,
  System.UITypes,
  System.Classes,
  System.Variants,

  FMX.Types,
  FMX.Controls,
  FMX.Forms,
  FMX.Graphics,
  FMX.Dialogs,
  FMX.Layouts,
  FMX.ListBox;

type
  TSystemForm = class(TForm)
    SystemInfo: TListBox;
    procedure FormShow(Sender: TObject);


  private
    { Private declarations }

    procedure AddInfoToListBox(ItemText: String);

    {$IFDEF ANDROID}
    procedure DeviceInfo;
    {$ENDIF}


  public
    { Public declarations }

  end;

var
  SystemForm: TSystemForm;

implementation

{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}

{$IFDEF ANDROID}

type TAndroidVersion = (
  UNKNOWN,
  BASE,
  BASE_1_1,
  CUPCAKE,
  CUR_DEVELOPMENT,
  DONUT,
  ECLAIR,
  ECLAIR_0_1,
  ECLAIR_MR1,
  FROYO,
  GINGERBREAD,
  GINGERBREAD_MR1,
  HONEYCOMB,
  HONEYCOMB_MR1,
  HONEYCOMB_MR2,
  ICE_CREAM_SANDWICH,
  ICE_CREAM_SANDWICH_MR1,
  JELLY_BEAN,
  JELLY_BEAN_MR1,
  JELLY_BEAN_MR2
);

// ADD DEVICE INFO TO SYSTEM INFO LIST BOX
procedure TSystemForm.AddInfoToListBox(ItemText: String);
var
  NewItem: TListBoxItem;

begin

    SystemInfo.Items.BeginUpdate;

    NewItem       := TListBoxItem.Create(Self);
    NewItem.Parent:= SystemInfo;
    NewItem.Text  := ItemText;

    SystemInfo.Items.EndUpdate;

end;

// GET DEVICE INFO
procedure TSystemForm.DeviceInfo;
var
  Version: TAndroidVersion;

  CodeName  : String;
  SystemInfo: String;

begin

    CodeName:= 'Unknown';

    Version:= TAndroidVersion(TJBuild_VERSION.JavaClass.SDK_INT);

    SystemInfo:= Format('Device Type(model): %s', [JStringToString(TJBuild.JavaClass.MODEL)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('BOARD: %s', [JStringToString(TJBuild.JavaClass.BOARD)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('BOOTLOADER: %s', [JStringToString(TJBuild.JavaClass.BOOTLOADER)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('CPU_ABI: %s', [JStringToString(TJBuild.JavaClass.CPU_ABI)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('CPU_ABI2: %s', [JStringToString(TJBuild.JavaClass.CPU_ABI2)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('DEVICE: %s', [JStringToString(TJBuild.JavaClass.DEVICE)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('DISPLAY: %s', [JStringToString(TJBuild.JavaClass.DISPLAY)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('FINGERPRINT: %s', [JStringToString(TJBuild.JavaClass.FINGERPRINT)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('HARDWARE: %s', [JStringToString(TJBuild.JavaClass.HARDWARE)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('HOST: %s', [JStringToString(TJBuild.JavaClass.HOST)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('ID: %s', [JStringToString(TJBuild.JavaClass.ID)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('MANUFACTURER: %s', [JStringToString(TJBuild.JavaClass.MANUFACTURER)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('MODEL: %s', [JStringToString(TJBuild.JavaClass.MODEL)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('PRODUCT: %s', [JStringToString(TJBuild.JavaClass.PRODUCT)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('RADIO: %s', [JStringToString(TJBuild.JavaClass.RADIO)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('SERIAL: %s', [JStringToString(TJBuild.JavaClass.SERIAL)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('TAGS: %s', [JStringToString(TJBuild.JavaClass.TAGS)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('TIME: %s', [IntToStr(TJBuild.JavaClass.TIME)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('&TYPE: %s', [JStringToString(TJBuild.JavaClass.&TYPE)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('UNKNOWN: %s', [JStringToString(TJBuild.JavaClass.UNKNOWN)]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('USER: %s', [JStringToString(TJBuild.JavaClass.USER)]);
    AddInfoToListBox(SystemInfo);


    case Version of

      UNKNOWN: CodeName:= 'Unknown';

      BASE    : CodeName:= 'Base';
      BASE_1_1: CodeName:= 'Base';

      CUPCAKE: CodeName:= 'Cupcake';

      CUR_DEVELOPMENT: CodeName:= 'Curent Development';

      DONUT: CodeName:= 'Donut';

      ECLAIR    : CodeName:= 'Eclair';
      ECLAIR_0_1: CodeName:= 'Eclair';
      ECLAIR_MR1: CodeName:= 'Eclair';

      FROYO: codename:= 'Froyo';

      GINGERBREAD    : CodeName:= 'Gingerbread';
      GINGERBREAD_MR1: CodeName:= 'Gingerbread';

      HONEYCOMB    : CodeName:= 'Honeycomb';
      HONEYCOMB_MR1: CodeName:= 'Honeycomb';
      HONEYCOMB_MR2: CodeName:= 'Honeycomb';

      ICE_CREAM_SANDWICH    : CodeName:= 'Ice Cream Sandwich';
      ICE_CREAM_SANDWICH_MR1: CodeName:= 'Ice Cream Sandwich';

      JELLY_BEAN    : CodeName:= 'Jelly Bean';
      JELLY_BEAN_MR1: CodeName:= 'Jelly Bean';
      JELLY_BEAN_MR2: CodeName:= 'Jelly Bean';

    end;

    SystemInfo:= Format('OS Name: %s'   , [CodeName]);
    AddInfoToListBox(SystemInfo);

    SystemInfo:= Format('OS Version: %s', [JStringToString(TJBuild_VERSION.JavaClass.RELEASE)]);
    AddInfoToListBox(SystemInfo);

end;

{$ENDIF}


// ON FORM SHOW
procedure TSystemForm.FormShow(Sender: TObject);
begin

    {$IFDEF ANDROID}
    DeviceInfo;
    {$ENDIF}

end;


end.
 

Както сами може да се убедите няма нищо сложно.

След компилация, на дисплея на мобилното устройство получаваме информация за системните параметри.

 

Screenshot_2020-09-22-20-56-35.thumb.png.3a6994a3cb39e92dfcb47bbd3dcdad8c.png

 

 

Познанието е сила. 

  • Thanks 1
Link to post
Share on other sites
  • 2 weeks later...

ПРИХВАЩАНЕ НА АУДИО ИНФОРМАЦИЯ

Прихващането на аудио информация е обвързано с възможността да записваме аудио данни, постъпващи от микрофона.

ЗАДАЧА:

Да се състави приложение, което да записва аудио информацията от микрофона във файл, който да можем да прослушаме.

Обърнете внимание, че към момента ние не уточняваме вида на файла. Това е много важно поради спецификата на Android и iOS, които работят с файл по подразбиране. Първоначално ние ще се придържаме към тази логика, но после ще разгледаме вариант, при който ще може да записваме аудиоданни във файл с произволно избран формат. 

Още по-интересно е, ако постъпващата от микрофона поточна информация не се записва във файл, а се записва в специално разработена за целта база данни или директно се предава към сървъра по TCP/IP.

 

Pic_003.png.899ccdf90122e53a99d1852a115d5a72.png

 

Първото, което правим е да създадем формата, която ще ползваме.

На формата добавяме два бутона Record (начало на запис) и Stop (прекратяване на записа). Посредством тези два бутона ние ще управляваме ръчно процесите на аудио запис.

Бутонът Exit затваря приложението.

За да възпроизведем записаната аудио информация добавяме бутоните Play и Stop. Освен тях добавяме и бутон Clear, който ще извърши физическо унищожаване на аудио файла, в случай на необходимоист.

В конкретния пример процесите се стартират и прекратяват ръчно, но те биха могли да бъдат автоматизирани в случай на нужда.

Освен така посочените бутони (в случая ние сме ги създали от графични примитиви, а не посредством използване на стандартни компоненти), добавяме и следните визуални компоненти както следва:

  • TActionList  (AudioActionList) - Управление на процесите;
  • TMediaPlayer  (MediaPlayer) - Възпроизвеждане на аудио информацията;
  • TTimer (AudioTimer) - Системен таймер.

Следващата стъпка е да дефинираме какъв файл ще използваме в зависимост от операционната система.

В конкретният случай имаме следните възможности:

  • Temp.3gp - Когато мобилното устройсто ползва OS Android.
  • Temp.caf - Когато мобилното устройсто ползва iOS.
  • Temp.wav - Когато мобилното устройсто ползва OS Windows.

В събитието OnFormCreate (създаване на формата) записваме следния код:

 

// 1. ON FORM CREATE
procedure TAudioForm.FormCreate(Sender: TObject);
begin

    AudioForm.StyleBook:= MainMenuForm.StyleBook;

    {$IFDEF ANDROID}
      AudioFile:= TPath.GetTempPath + '/' + 'Temp.3gp';
    {$ELSE}
     {$IFDEF IOS}

        AudioFile:= TPath.GetHomePath + '/Documents/' + 'Temp.caf';
      {$ELSE}
        AudioFile:= TPath.GetTempPath + '\Temp.wav';
      {$ENDIF}
    {$ENDIF}

end;

 

Обърнете внимание къде записваме аудио файла. 

  • Temp.3gp - Записваме в директория TPath.GetTempPath + '/' .
  • Temp.caf - Записваме в TPath.GetHomePath + '/Documents/'.
  • Temp.wav - Записваме в TPath.GetTempPath.

При трите операционни системи файлът се записва в различни директории. Причината за това е спецификата, тъй като както Android така и iOS са наследили всички недостатъци на UNIX.

В конкретния пример, който има образователен характер, това не е проблем, но ако разработваме професионално решение е нужно да добавим няколко реда кода, който биха възпрепятствали възможността от несанкциониран достъп до аудио файла.

В декларативната част на програмата записваме:

  public
    { Public declarations }

    Microphone: TAudioCaptureDevice;

    AudioFile: String;
 

Следващата стъпка е да реализираме запис на аудио информация (да прихванем микрофона).

 


// 1. START AUDIO RECORDING
procedure TAudioForm.RecordingStartActionExecute(Sender: TObject);
begin

    //Get the default microphone
    Microphone:= TCaptureDeviceManager.Current.DefaultAudioCaptureDevice;

    if Microphone <> nil then
      begin

        Microphone.FileName:= AudioFile;
        Microphone.StartCapture;

      end
    else
      begin

        ShowMessage('Audio capturing device not available');
      end;

end;


// 2. STOP AUDIO RECORDING
procedure TAudioForm.RecordingStopActionExecute(Sender: TObject);
begin

    Microphone.StopCapture;

end;

 

В този код няма нищо сложно.

Microphone:= TCaptureDeviceManager.Current.DefaultAudioCaptureDevice опредяля от къде ще записваме аудиопотока.

В конкретния случай това е микрофона на устройството. 

Microphone.FileName:= AudioFile показва къде ще записваме аудиоинформацията.

 

 

 

Link to post
Share on other sites
  • 3 weeks later...

ИЗПОЛЗВАНЕ КАМЕЕРАТА НА МОБИЛНОТО УСТРОЙСТВО

Съвременните мобилни устройства разполагат с една илиповече камери, които бихме могли да използваме както за запис на поточно видео, така и като цифрови фотоапарати. 

ЗАДАЧА:

Да се създаде приложение, което ни позволява да използваме видеокамерата, като цифров фотоапарат.

Макар за мнозина това да прозвучи нелогично, това е много по-трудно от това да записваме поточно видео.

Както при аудио файловете, така и  при  цифровите изображения записът се извършва в определен файлов формат и в определена директория. При използване на подходящите софтуерни решения тези ограничения могат лесно да бъдат избегнати.

Като начало на формата (никога не забравяйте, че "форма" и "фрейм" са две много различни неща) разполагаме компонент за визуализация на цифрови изпображения TImage, на който за пригледност задаваме име PhotoImage, четири бутона:

  • Shooting - Заснимане;
  • Clear - Изчистване на PhotoImage (изчиства снимката, която сме направили);
  • Save - Записва снимката в папка, която ние посочим или в зададената по подразбиране;
  • Exit - Изход от приложението.

Освен това добавяме TCameraComponent, TTimer и TActionList, така както е показано на изображението.

 

L_001.png.fdaf2c5263f84aaeea7e80c929885bfa.png

 

НАЙ-ВАЖНИЯТ ЗА НАС КОМПОНЕНТ Е СИСТЕМНИЯТ ТАЙМЕР.

 

В събитието OnFormCreate задаваме директориите по подразбиране в зависимост от операционната система на мобилното устройство.

 

// 1. ON FORM CREATE
procedure TPhotoForm.FormCreate(Sender: TObject);
begin

    {$IFDEF ANDROID}
      TempDirectory:= TPath.GetHomePath + '/Files/';
    {$ELSE}
      {$IFDEF IOS}
        MainMenuForm.StyleBook:= iOSStyleBook;
        TempDirectory:= TPath.GetHomePath + '/Documents/Files/';
      {$ELSE}
        TempDirectory:= 'C:\Temp';
      {$ENDIF}
    {$ENDIF}

    if not TDirectory.Exists(TempDirectory) then TDirectory.CreateDirectory(TempDirectory);


end;
 

Следва най-интересното: Как прихващаме видеоизображението?

Няма да повярвате, колко лесно това се постига на Delphi.

В събитието OnTimer на системния таймер, записваме следния код: 

 

procedure TPhotoForm.PhotoTimerTimer(Sender: TObject);
begin
    Camera.SampleBufferToBitmap(PhotoImage.Bitmap, True);
end;

 

Какво на практика ни дава това?

Информацията (кадрите), които постъпват от видеокамерата ще се изобразяват в работната област (Canvas) на TImagе.

За да може да правим снимки и да стартираме камерата е достатъчно в TActionList да добавим събитието PhotoShootingAction.

 

// PHOTO SHOOTING
procedure TPhotoForm.PhotoShootingActionExecute(Sender: TObject);
begin

    if not Camera.Active then
      begin
        Camera.Active := TRUE;
        PhotoTimer.Enabled:= TRUE;
      end
    else
      begin

        Camera.Active := FALSE;
        PhotoTimer.Enabled:= FALSE;
      end;

end;

С това се изчерпва почти всичко. 

За да изчистим получената цифрова фотография е достатъчно да напишем следния код:

 

// CLEAR PHOTO
procedure TPhotoForm.PhotoClearActionExecute(Sender: TObject);
begin
    PhotoImage.Bitmap:= nil;
end;

 

Много по-важният въпрос е: А за какво може да ползваме това на практика?

Като начало за специализирани месенджъри, които поддържат пълнофункционален strong encryption.

 

L_003.png.47fba5a43ab2dd4ea7b7f82c58d9ad47.png

 

На изображението виждате един от възможните варианти. В този случай получените цифрови изображения, освен че могат да се записват, също така могат да се криптират преди да бъдат изпратени или да се съхраняват в защитен вид (в случай, че някой прояви любопитство към снимките на телефона ви).

Интересното е, че на практика записа на цифрови изображебния е много по-лесен за реализация, отколкото аудио записите. 

Истински интересен е въпросът как да синхронизираме аудио и видеоинформацията, но това е тема на други разглеждания.

Целта на настоящите публикации е да ви запознае с много малка част от възможностите на Rad Studio Delphi и FMX.

А ето още едино възможно приложение. Система за излъчване на супермаратони за мобилни устройства. Проектът е от 2017 година. Вие може да си направите изводите. На практивка това е итерактивна телевизия, но .. не забравяйте, за коя година говорим.

 

L_004.png.d76cce0ec2549846d1f410e41aad7d44.png

 

Ако трябва да направя сравнение между софтуера като такъв и софтуера за мобилни устройства бих използвал едно много нагледно сравнение.

Софтуерът за мобилни устройства е като пластичната хирургия. Лицата занимаващи се с пластична хирургия дори не са хирурзи, а това е козметична медицина (софтуерът за мобилни устройства - също).

Истинският софтуер е като неврохирургията. Там нещата са доста различни и изискват различен подход и друг вид познания.

Но ...

Живеем в модерни времена ... :$

Link to post
Share on other sites
  • 1 month later...

Здравейте,

За всички, които сега правят първите си стъпки и срещат затруднения с подходяща литература за начинаещи, горещо препоръчвам "Object Pascal Handbook 10.4 Sydney Edition" на Марку Канту.

Това определено е едно от най детайлните ръководства по програмиране, което съм виждал. Изключително много практически примери и разяснения.

Може да научите страшно много и на практика да формирате база, която ще ви позволи безпроблемно да програмирате на всеки един език.

Object Pascal Handbook by Marco Cantu

  • Thanks 1
Link to post
Share on other sites
  • 4 weeks later...
  • 1 month later...

ПРОГРАМИРАНЕ ЗА LINUX И iOS

Едно от най-големите предимства на Delphi е възможността за създаване на VCL или FMX мултиплатформени приложения.

Ето как се създава типично VCL приложениe за Linux, като ползвате Delphi.

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.