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

Belov.V.

Пользователи
  • Постов

    69
  • Зарегистрирован

  • Посещение

  • Победитель дней

    6

Активность репутации

  1. Like
    Belov.V. отреагировална Олег Игоревич в MapView рушит приложение в Tokyo 10.2.3   
    Отлично пуши исправили и карты заработали.
    30831_rad_studio_10.2.3_android_push_notification_patch.ZIP
  2. Like
    Belov.V. отреагировална krapotkin в Цикл по unicode строке   
    гораздо проще 
    '1234567890'.Contains(ch)
  3. Like
    Belov.V. получил реакцию от Евгений Корепов в Сборка приложений под Linux   
    Предлагаю поделиться практикой сборки приложений под Linux, набором ошибок и глюков.
    Решил сделать пару экспериментов в связке RAD-Linux.
    1) Есть рабочий Debian7. На нем не пошел PAServer. Требует glib версии 2.14 или 2.17 (на 7-ке 2.12). Добавил в репозиторий ссылку на пакеты от debian 8. Обновил. PAServer стартует, но тут же валится по ошибке сокета (не записал как звучит). Пока все пакеты подряд.
    2) Поднял Debian8. Чистый.
    PAServer стартует, SDK в RAD студию загружается. При попытке сборки ошибка "[DCC Error] E2597 C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\ld-linux.exe: error: cannot find -lgcc_s" При обновлении кеша файлов SDK ругается: Directory does not exist: /usr/include/c++/ Directory does not exist: /usr/include/x86_64-linux-gnu/ (исчезла после gcc-6) Directory does not exist: /usr/include/x86_64-linux-gnu/c++/ Directory does not exist: /usr/include/c++/ Directory does not exist: /usr/lib/gcc/x86_64-redhat-linux/ Directory does not exist: /usr/lib/gcc/x86_64-redhat-linux/ Directory does not exist: /usr/lib64/ Доставил пакеты gcc-6 и linux-compiler-gcc-6-x86, обновил файлы кеша SDK (исчезла вторая строчка в предупреждении при обновлении). Ура!  Простейший пример собирается и стартует. Под отладчиком работает. Но остались шесть предупреждений при обновлении linux SDK.
    Где это может вылезти?
  4. Like
    Belov.V. отреагировална Brovin Yaroslav в Delphi for Linux Boot Camp Replay   
    Just in case you missed the fantastic Delphi for Linux Boot Camp by Craig Chapman this week here, or you want to watch it again, here is the replay that includes Marco Cantu's Q&A at the end.
    This Boot camp covers the setup of a Linux development environment for building Linux applications with Delphi. We’ll look at hello world, debugging linux applications, deploying apache2 modules using WebBroker, and accessing a MySQL database using FireDAC. The penguins are coming, be prepared!
    Просмотр полной статьи
  5. Like
    Belov.V. отреагировална Alex7wrt в 9-Patch PNG FMX Generator   
    Сделал небольшую программу-генератор 9-patch заставок. 
    Достаточно выбрать цвет фона, логотип и его видимый размер, и программа сгенерирует 9-patch для всех необходимых  в FMX размеров.

    Примеры
    Рисунок:

    Полученные 9-Patch png:

    Рисунок:

    Полученные 9-Patch png:

     
    Исходники: 9Patch Generator.zip
     
  6. Like
    Belov.V. получил реакцию от Pax Beach в Отправка файлов через намерение   
    Вот пример. Соорудил, проверил, вроде работает.
     
    Размер файла нормальный. Скриншеты на двух почтовых клиентах:

     

     
    Upd: в RX небольшие изменения. См. второй пример. (для первого идут предупреждения, хотя тоже работает)
    Sample-SendAttach.zip
    Sample-SendAttach_RX.zip
  7. Like
    Belov.V. получил реакцию от Pax Beach в Отправка файлов через намерение   
    Goggle Drive в качестве имени ставит то, что указано в Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment));
    Т.е. прописывайте в это поле имя файла без пути,
     
    Mail.ru не пробовал.
  8. Like
    Belov.V. получил реакцию от Rusland в После активации TSearchBox не возвращается индекс нового добавленого элемента   
    Готового решения на просторах интернета не нашел. То, что напридумывал сам, оформил в виде хелпера к TListBox. Может кому пригодится.
    Реализовал только необходимые мне методы. И только для режима MultiSelectStyle=None
    Самое главное, что так индекс возвращается корректно.
    unit ListBoxHelper; interface uses FMX.Controls, FMX.Types, System.SysUtils, FMX.ListBox, FMX.SearchBox; // Создаем Helper для класса TListBox type TListBoxHelper = class helper for TListBox function ResetFilter : string; // возвращает старый фильтр function GetSearchBox : TSearchBox; // возвращает SearchBox function AddAndClearSelect(const S : string) : integer; // добавить, ничего не выбирать, фильтр очистить function AddAndSelect(const S : string) : integer; // добавить, выбрать, фильтр очистить function AddAndSaveOldSelect(const S : string) : integer; // добавить, сохранить выбор, фильтр очистить function AddAndSaveOldView(const S : string) : integer; // добавить, сохранить выбор и фильтр, вернуть номер добавленного в отфильтрованном списке, или -1 если не попадает в фильтр procedure DeleteItem(const i : integer = -1); // удалить по индексу. если индекс не указан то удалить выбранный end; implementation function TListBoxHelper.GetSearchBox : TSearchBox; var Child : TControl; FxmChild : TFmxObject; begin Result := nil; for Child in self.Controls do for FxmChild in Child.Controls do if FxmChild is TSearchBox then Exit( TSearchBox( FxmChild ) ); end; function TListBoxHelper.ResetFilter : string; var s : TListBoxItem; sb : TSearchBox; begin Result := EmptyStr; s := Selected; sb := GetSearchBox; if Assigned( sb ) then begin Result := sb.Text; sb.Text := EmptyStr; end; if Assigned( FilterPredicate ) then FilterPredicate := nil; if Assigned( s ) then ItemIndex := s.Index; end; function TListBoxHelper.AddAndClearSelect(const S : string) : integer; begin ClearSelection; ResetFilter; Result := Items.Add( s ); end; function TListBoxHelper.AddAndSelect(const S : string) : integer; begin Result := AddAndClearSelect( s ); if Result <> -1 then ItemIndex := Result; end; function TListBoxHelper.AddAndSaveOldSelect(const S : string) : integer; var sel : TListBoxItem; begin sel := Selected; Result := AddAndClearSelect( s ); if Assigned( sel ) then ItemIndex := sel.Index end; function TListBoxHelper.AddAndSaveOldView(const S : string) : integer; var sb : TSearchBox; iSel, iNew : TListBoxItem; flt : string; begin iSel := Selected; iNew := nil; ClearSelection; sb := GetSearchBox; flt := ResetFilter; // Result := Items.Add( s ); if Result <> -1 then iNew := ItemByIndex( Result ); // if flt <> EmptyStr then begin sb.Text := flt; if Assigned( iNew ) then Result := iNew.Index; end; if Assigned( iSel ) then ItemIndex := iSel.Index; end; procedure TListBoxHelper.DeleteItem(const i : integer = -1); var sb : TSearchBox; flt : string; iSel, iDel : TListBoxItem; begin if i > Count-1 then Exit; sb := GetSearchBox; if i > -1 then begin iSel := Selected; iDel := ItemByIndex( i ); end else begin iSel := nil; iDel := Selected; end; flt := ResetFilter; if Assigned( iDel ) then Items.Delete( iDel.Index ); // if flt <> EmptyStr then sb.Text := flt; if Assigned( iSel ) then ItemIndex := iSel.Index; end; end. Еще на XE7 есть глюк в режиме Sorted := True, при добавить одинаковые значения (или несколько одинаковых) и сразу выделении одного через IntemIndex.
    Но пока на выявление закономерностей и борьбу нет времени.
    ListBoxHelper.zip
  9. Like
    Belov.V. получил реакцию от Марк в [TGrid] Как получить значение ячейки при использовании LiveBinding?   
    С того момента, как "стал рассматривать" TGrid непосредственно как компонент отображения существующих данных, работать с ним стало проще и приятнее. В похожих ситуация работаю непосредственно с данными (выборкой). То, что FDQuery и Grid связаны через LiveBinding, значения не имеет:
    FDQuery1.RecNo := Grid1.Selected+1; ... := FDQuery1.FieldByName['id'].AsInteger; //или по порядковому номеру: ... := FDQuery1.Fields.Fields[0].AsInteger; //или тип Variant: ... := FDQuery1['id'] //и т.д. В зависимости от необходимого способа реакции код можно подвесить на onClick, onMouseMove и т.д. по желанию.
  10. Like
    Belov.V. отреагировална AngryOwl в [TListBox] Как отобразить итемы в виде панелей?   
    Не в первый раз вижу эту тему...
    TGridPanelLayout - далеко не предпочтительный вариант. Совсем.
    У ListBox с его Item'ами намного больше возможностей.
    С [xenon54] соглашусь, но не полностью. ListView действительно хорош (для мобильной платформы), однако он намного сложнее.
     
    Примеры применения стилей для ListBoxItem (не сочтите за рекламу, так проще было... нащелкал скринов для примера):
     

     
    Везде - ListBox.
    На последнем скрине - всплывающие сообщения на экране. Реализовано так же - прозрачная форма, ListBox и Item'ы со своим стилем В ВИДЕ ПАНЕЛЕК )
     

  11. Like
    Belov.V. отреагировална Vitaldj в VirtualBox   
    Да нет, ничего она не напрягает)). Я же говорю, когда в ней студия не загружена, особо процессорное время и не тратиться. 
    Теперь насчет parallels. Ставил я ее и еще fusion. В общем пробовал разные вирт машины. Но, может вы будите удивлены, но разницы я не нашел! Даже тесты проводил! Примерно одинаково! Дело в том, что мне не нужны все эти плюшки параллелс. Я не использую виндовые программы, давно нашел всему замену в мак оси. И запуск сразу виндовых программ (как может parallels) мне ни к чему. Проблема еще в другом. В меня 2 мака (ноут + мак мини). И еще очень удобно ставить в виртуальную машину с виндой delphi. Там ее настраивать и потом этот один файл запускать на разных машинах! Поэтому у меня еще стоит 2-е вирт машины в виндосувских машинах (вот такой каламбур) дома и на работе. То есть винда в винде! Выпустила дельфи апдейт или сервис пак, я ее ставлю в одну машину и этот файл виртуальной машины потом использую на всех четерых! Очень это удобно. И еще, храню я его дополнительно на внешнем диске. И с влучае глюка восстанавливаю за 10 мин! Таким образом, мне надо покупать 4-е копии! Зачем мне это? Поэтому меня virtBox полностью устраивает, потому что она не такая уж и плохая, да еще и бесплатная! Поэтому программирую я дома и на работе и у родителей и при этом как бы за одним и тем же компьютером! Потому что все исходники лежат в dropbox и тут же синхронизируются. Так что что уж там крутого в parallels?
  12. Like
    Belov.V. отреагировална Andrey Efimov в [Статья][Android] Автоматическая смена названия приложения в зависимости от языка системы   
    Ссылка: http://delphifmandroid.blogspot.ru/2016/04/blog-post.html
    Автор: Андрей Ефимов
    Описание: Автоматическая смена названия приложения в зависимости от языка системы
  13. Like
    Belov.V. отреагировална krapotkin в Сортировка TListBoxItem по алфавиту   
    что ж так сложно то O_O
    выделить из строки подстроку - на 100 строк процедура?
     
    а еще как обычно замечу, что данные нужно хранить в модели данных а не на экране
    тогда доступ к ним гораздо проще
    и сортировка тоже
  14. Like
    Belov.V. получил реакцию от rareMax в Отправка файлов через намерение   
    Goggle Drive в качестве имени ставит то, что указано в Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment));
    Т.е. прописывайте в это поле имя файла без пути,
     
    Mail.ru не пробовал.
  15. Like
    Belov.V. отреагировална Rusland в "Общение" сервиса и приложения через intent   
    Для ищущих ответа:
    Есть стандартное demo Object Pascal\Mobile Snippets\AndroidIntents\AndroidIntentsGroup.groupproj, в котором показано как из одного приложения передавать данные другому. С помощью этого примера удалось передавать данные из сервиса в основное приложение.
    В юните основного приложения пишем:
    uses FMX.Platform, FMX.Platform.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.Helpers, System.Messaging, Androidapi.JNI.GraphicsContentViewText; private { Private declarations } function HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; procedure HandleActivityMessage(const Sender: TObject; const M: TMessage); function HandleIntentAction(const Data: JIntent): Boolean; procedure TForm1.FormCreate(Sender: TObject); var AppEventService: IFMXApplicationEventService; begin ... if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then AppEventService.SetApplicationEventHandler(HandleAppEvent); // Register the type of intent action that we want to be able to receive. // Note: A corresponding <action> tag must also exist in the <intent-filter> section of AndroidManifest.template.xml. MainActivity.registerIntentAction(TJIntent.JavaClass.ACTION_VIEW); TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage); end; procedure TForm1.HandleActivityMessage(const Sender: TObject; const M: TMessage); begin if M is TMessageReceivedNotification then HandleIntentAction(TMessageReceivedNotification(M).Value); end; function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; var StartupIntent: JIntent; begin Result := False; if AAppEvent = TApplicationEvent.BecameActive then begin StartupIntent := MainActivity.getIntent; if StartupIntent <> nil then HandleIntentAction(StartupIntent); end; end; function TForm1.HandleIntentAction(const Data: JIntent): Boolean; var Extras: JBundle; begin Result := False; if Data <> nil then begin Memo1.ClearContent; // записываем в Memo пришедшее сообщение Extras := Data.getExtras; if Extras <> nil then Memo1.Text := JStringToString(Extras.getString(TJIntent.JavaClass.EXTRA_TEXT)); Invalidate; end; end; в AndroidManifest.template.xml добавляем 
    <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:mimeType="text/pas" /> Отправка сообщения из сервиса делается так:
    SendTextViaIntent('Hello from service'); procedure TAndroidServiceDM.SendTextViaIntent(const AText: string); var   Intent: JIntent; begin   Intent := TJIntent.Create;   Intent.setType(StringToJString('text/pas'));   Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);   Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK); // добавил такой флаг, без  него сервис затыкался   Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(AText));   if  TJContextWrapper.Wrap(System.JavaContext).getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then      TJContextWrapper.Wrap(System.JavaContext).startActivity(Intent); // заменил MainActivity на TJContextWrapper.Wrap(System.JavaContext), т.к. это сервис end; Работает исправно, хоть 100%-ую правильность кода не гарантирую  Но как передать сообщение из основной программы обратно в сервис я пока не знаю. Также делать хендл внутри сервиса? 
    Попытался просто добавить FMX.Platform, в результате получаю ошибку в FMX.Platform.Android вываливается ошибка об использовании Activity внутри сервиса.
  16. Like
    Belov.V. отреагировална Равиль Зарипов (ZuBy) в SuperObject vs JSON   
    Привет Всем!
     
    Решил поделится впечатлениями по работе с SuperObject'ом и родным JSON'ом
     
    тест был файла с 2000+ объектами в JSON файле
    структура файла была такая
    { "status":"OK", "last_id":"711", "objects":[ { "obj_id":"1", "obj_acc_id":"1", "obj_cat_id":"24", "obj_title":"13 магистраль", "obj_descr":"ЖК представляет собой комфортный дом, состоящий из 14 блок-секций (подъездов). Расположен в перспективном развивающемся районе по 13 Магистрали с удобным выездом как на левый берег, так и в старую часть города. Вблизи Жилого комплекса распологается новая школа, парк отдыха и культуры.", "obj_address":"ул. Мамышулы - 104, д. 16\/1", "obj_address2":null, "obj_url":"3fa07dd73be072b049529c80c7d74732", "obj_planet":"1", "obj_country":"1", "obj_region":"1", "obj_city":"292", "obj_lat":"51.141", "obj_lon":"71.4835", "obj_insert_dt":null, "obj_update_dt":null, "obj_editted":"0", "obj_updated":"0", "obj_deleted":"0", "obj_showed":"1", "obj_rating":"0", "obj_pro_top":"0", "obj_pro_selected":"0", "obj_pro_unix_dt":"0", "obj_partner":"0", "obj_parent_id":"0", "obj_has_child":"0", "obj_currency":"0" }, // тут далее 2000+ объектов ] } SuperObject  Время выполнения:  ~01:393
    JSON родной Время выполнения: ~01:690
     
    разница не особо ощутима, тем более если будет меньше объектов
     
    JSON родной
    function JSONParse(const aJSONData: string; const aMemo: TMemo): boolean; var aJSValue: TJSONValue; aJSObject, aJSObjArr: TJSONObject; aJSArray: TJSONArray; I: integer; begin Result := false; aJSValue := TJSONObject.ParseJSONValue(aJSONData) as TJSONValue; if Assigned(aJSValue) then begin aJSObject := aJSValue as TJSONObject; aMemo.Lines.Add('status: ' + aJSObject.GetValue('status').Value); if aJSObject.GetValue('status').Value = 'OK' then begin Result := true; if Assigned(aJSObject) then begin aJSArray := aJSObject.GetValue('objects') as TJSONArray; if Assigned(aJSArray) then begin Result := true; aMemo.Lines.Add('last_id: ' + aJSObject.GetValue('last_id').Value); aMemo.Lines.Add('count: ' + aJSArray.Count.ToString); for I := 0 to aJSArray.Count - 1 do begin aJSObjArr := aJSArray.Items[I] as TJSONObject; if Assigned(aJSObjArr) then begin aMemo.Lines.Add(aJSObjArr.GetValue('obj_id').Value + ',' + aJSObjArr.GetValue('obj_acc_id').Value + ',' + aJSObjArr.GetValue('obj_cat_id').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_title').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_descr').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_address').Value); aMemo.Lines.Add(aJSObjArr.GetValue('obj_url').Value); end; end; end; end; end; aJSValue.Free; end; end; SuperObject
    function JSONSOParse(const aJSONData: string; const aMemo: TMemo): boolean; var xObject: ISuperObject; xCount, I: integer; sfmt: string; begin Result := false; xObject := SO(aJSONData); aMemo.Lines.Add('status: ' + xObject['status'].AsString); if xObject['status'].AsString = 'OK' then begin Result := true; xCount := xObject['objects'].AsArray.Length; aMemo.Lines.Add('count: ' + xCount.ToString); aMemo.Lines.Add('last_id: ' + xObject['last_id'].AsInteger.ToString); for I := 0 to xCount - 1 do begin aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_acc_id"'].AsInteger.ToString + ',' + xObject['objects[' + I.ToString + ']."obj_cat_id"'].AsInteger.ToString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_title"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_descr"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_address"'].AsString); aMemo.Lines.Add(xObject['objects[' + I.ToString + ']."obj_url"'].AsString); end; end; end; Разница ощутима когда пишешь код, SO намного легче читать
     
    Подробней почитать и скачать SO
  17. Like
    Belov.V. отреагировална #WAMACO в Кому нужны программисты Fire Monkey?   
    Вас вообще понять не могу!
    Все время критикуете RAD Studio и зачем тогда тут все время?
    я вот отошел от C#, перекрестился и больше не хочу туда!
  18. Like
    Belov.V. отреагировална rustam_d в Цена собственной программы   
    Факторов не мало:
    - Есть свой человек толкатель в компании? Если да то долю(откат) ему 20-30%, это мотивирует увеличить цену иначе придется работать как лох не выше пару-штук баков...на месяцы )
    - Претендует на тиражирование? Если да, то можно снизить цену за "обкатку", иногда на 50% если веришь в себя и в проект ), а это поверь надо!
    - Исходники хотят? обычно Цена проекта умноженная на 3-4 (переживать не стоит, ведь требуются доработки постоянные).
    - Дизайн иконок и заставки ВАЖНО с себя снять, иначе достанут по мелочам...т.е. получаешь все с заказчика.
    - Если дроид и ИОС, то сертификаты с них и дальнейшее слежение за магазами
    - Очень важно в договоре обговорить сроки!!! особенно сопровождения...иначе висяк, зависимость и т.п., ну вообщем снова лох..)
    - Сопровождение делается так, заказчик копит замечания, затем согласовывает с тобой, ты оцениваешь цену и сроки, и вперед доп.соглашение..
     
    Примерно так.. )
    Удачи стать независимым от ЗП, это и есть настоящая свобода ).
  19. Like
    Belov.V. получил реакцию от Евгений Корепов в Отправка файлов через намерение   
    Goggle Drive в качестве имени ставит то, что указано в Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment));
    Т.е. прописывайте в это поле имя файла без пути,
     
    Mail.ru не пробовал.
  20. Like
    Belov.V. получил реакцию от Евгений Корепов в [Android] Обработка приложением неявного намерения (Intent)   
    Регистрируем намерение через файл манифеста (ниже для файлов с типом xml). Для Android 3.2 адекватнее работал второй фильтр:
    <activity … <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="file" /> <data android:mimeType="text/xml" /> <data android:mimeType="application/xhtml+xml" /> </intent-filter> <!-- Для 3.2 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="file" /> <data android:mimeType="*/*" /> <data android:host="*" /> <data android:pathPattern=".*\\.xml" /> <data android:pathPattern=".*\\..*\\.xml" /> <data android:pathPattern=".*\\..*\\..*\\.xml" /> <data android:pathPattern=".*\\..*\\..*\\..*\\.xml" /> <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.xml" /> </intent-filter> Регистрируем свой обработчик события для на событие смены состояния приложения:
    procedure TForm1.FormCreate(Sender: TObject); var ApplicationService: IFMXApplicationEventService; begin if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, ApplicationService) then ApplicationService.SetApplicationEventHandler(ApplicationEventChanged); end; Оформляем обработчик.
    Получение файла можно перенести в Form1.onCreate, но я для экспериментов с activity делал тут:
    function TForm1.ApplicationEventChanged(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; var intent : JIntent; fileFullPath : String; begin intent := SharedActivity.getIntent; // BecameActive if AAppEvent = TApplicationEvent.BecameActive then begin if Assigned(intent) and TJIntent.JavaClass.ACTION_VIEW.equals(intent.getAction) then begin fileFullPath := JStringToString(intent.getData.getPath); if FileExists(fileFullPath) then begin // обработка файла fileFullPath // ... end; end; end // завершаем Activity при переводе приложения в "Background" else if AAppEvent = TApplicationEvent.EnteredBackground then SharedActivity.finish; // Result := True; end; Хочу обратить внимание, что привел только сам принцип. Очень важно корректно завершить активность (при сворачивании приложения, отключении экрана и т.д. ), т.к. при повторном вызове активности будет вызываться последний из стека. И если его не закрывать будем получить предыдущий, не закрытый activity. А если за приложением зарегистрировано несколько Activity (приложение можно вызвать из ланчера или как в примере, для обработки файла по типу).... в общем тут есть с чем поиграться.   Для желающих посмотреть поведение и последовательность выкладываю пример, который формирует лог обработки. Нужно закоментировать:    else if AAppEvent = TApplicationEvent.EnteredBackground then SharedActivity.finish; И посмотреть что и когда приложение получает в SharedActivity и AAppEvent.   Ссылка в тему: http://developer.android.com/guide/topics/manifest/activity-element.html#     Что не получилось: 1) Некоторые программы отдают файл в схеме «content» (к примеру Gmail v5.1 отдает). Как в этом случае получить содержание файла не разобрался. Поэтому в фильтре ограничил вид контента "file" 2) Не смог добраться до стека Activity. Если приложение в памяти и повторно вызывается с новой activity - возможно вот тут это могло пригодиться. (activity ... android:launchMode="singleTop" в этом случае не помог).   ADD: было обсуждение, кто как закрывает приложения на андроид, чтобы не оставалось в памяти. Если добавлять SharedActivity.finish приложение 100% убирается из памяти.    
    Intent_Get-File.zip
  21. Like
    Belov.V. отреагировална Vitaldj в Создание и коррекция кастомных стилей в XE8   
    Уважаемые форумчане, программирую давно, но как то не приходилось связываться со стилями, до этого писал ( http://fire-monkey.ru/topic/1536-kak-pomeniat-fon-edit/#entry7561 ) что нужно поменять фон в edit. Получил ответ, что лучше работать со стилями, занялся этой проблемой, посмотрел вебинар по этому поводу, перелопатил эту ветку форума про стили, но понял, что все вопросы и ответы были получены в 2014 году и что в XE8 поменялось много. Не смог, вернее смог, но криво и не правильно(( разобраться как поменять стиль у edit. Смог разобраться до момента подкладки TRectangle и все. Даже поставил hittest в false, но потерялась возможность вводе текста, его не видно(. Подскажите, где поновее мануал? Или просьба Ярославу, стиль - очень важная штука, не хотел бы он тут поподробнее об этом рассказать и многие вопросы отпали у очень многих людей.
    ​Ну или хотяб помогите с этим простым примером.
  22. Like
    Belov.V. получил реакцию от estra в Отправка файлов через намерение   
    Проверьте вот это место в коде:
    // прикрепляем файл
    j_file := SharedActivity.getExternalFilesDir(StringToJString(f_name));
     
    Обратите внимание, что там указано имя прикрепляемого файла без пути к нему. По описанию ситуации очень похоже на ошибку в этом месте.
  23. Like
    Belov.V. получил реакцию от estra в Отправка файлов через намерение   
    Вот пример. Соорудил, проверил, вроде работает.
     
    Размер файла нормальный. Скриншеты на двух почтовых клиентах:

     

     
    Upd: в RX небольшие изменения. См. второй пример. (для первого идут предупреждения, хотя тоже работает)
    Sample-SendAttach.zip
    Sample-SendAttach_RX.zip
  24. Like
    Belov.V. получил реакцию от estra в Отправка файлов через намерение   
    Заполнение поля "Кому:"
    var ... JRecipient: TJavaObjectArray<JString>; ... begin // JRecipient := TJavaObjectArray<JString>.Create(1); JRecipient.Items[0] := StringToJString('test@test.ru'); ... Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, JRecipient); ...
  25. Like
    Belov.V. отреагировална krapotkin в [Отклонение] [Android] Не меняется KeyboardType при переходе на следующий TEdit   
    этот ответ можно вынести на главную страничку и закрыть все темы форума разом )))
×
×
  • Создать...