-
Постов
414 -
Зарегистрирован
-
Посещение
-
Победитель дней
12
Активность репутации
-
Pax Beach отреагировална Сергей Сергеев в Проблема в Android 6.0
Ура! Проблема решилась.. т.е. стало работать не рестартуя после свертывания и т.д.
все дело в "галочке"
Это я поставил эту отметку в новом телефоне, после включения режима разработчика.. очень мне не понравились слова про сохранения моих действий
и все "простые" приложения, не сохраняющие свое состояние , после рестарта оказывались в начальном положении.
Отключил.. и все стало работать, приложение живет, благо памяти хватает, на сеанс просмотра инфы - 10-15 мин явно хватит и при запуске вьеверов и мейла.. ну уж если вытеснит его из памяти, значит пользователь чем то таким уж занялся посторонним, что после этого и перелогиниться, думаю, его не удивит..
-
Pax Beach отреагировална Равиль Зарипов (ZuBy) в Стилизованный компонент на базе нативного
порядок отрисовки компонентов на форме, сейчас нативные лежат всегда сверху
-
Pax Beach отреагировална Камышев Александр в Быстродействие при использовании TCrititcalSection и TThread
Windows, FMX
Возможно не совсем в тему форума, вопрос по архитектуре серверных служб, хотелось бы услышать мнения.
Ситуация:
IdHTTTPServer на каждый запрос создает поток, в этом потоке не обойтись без обращения к пулу данных в памяти. Пул - несколько наборов актуальных данных. Наборы данных асинхронно получаются из БД, имеют связи многие ко многим, один ко многим и периодически кэшируются в память в основном потоке. Т.к. обращение к пулу из потока - соответственно пул должен быть потокозащищенным. После обработки запроса, данные также отправляются в основном потоке в очередь БД.
1. Если весь пул закрыть в TCriticalSection - то на время использования его одним потоком все остальные будут ожидать. Обращение к очереди БД из потока получается также должно быть потокозащищенным. Не изящно.
2. Можно задачу обработки положить в некую потокозащищенную очередь и остановить поток c помощью TSimpleEvent->WaitFor( INFINITE ). Далее в основном потоке работать с пулом данных и очередью БД без критических сессий и, после получения результата, запустить поток SetEvent(). Код будет проще и понятней, однако задачи будут выполняться синхронно, последовательно как и в первом случае.
3. Можно закрывать TCriticalSection отдельные наборы данных, это возможно несколько увеличит быстродействие (не факт!), усложнит код и увеличит вероятность deadlock, т.к. для обработки одного запроса используется несколько наборов данных. Deadlock не будет, если перед обращением к следующему набору ( critical_section->Enter() ) копировать что необходимо из предыдущего и отпускать его ( critical_section->Leave() ) - тут становится важна стоимость операторов копирования.При больших объемах, стоимость копирования может перекрыть весь профит от частного обращения к наборам.
TThread полезно использовать при длительных операциях ввода вывода и ресурсоемких операциях, т.е. когда нужно подождать, не останавливая основной поток. Выигрыша в производительности полагаю нет, к тому же переключения критических секций также имеют стоимость.
Вопросы:
1. Какой вариант предпочтительней? Есть стандартные схемы?
2. Как влияет количество ядер, процессоров, на быстродействие во втором и третьем случае?
-
Pax Beach отреагировална Brovin Yaroslav в Фильтр по типу "облака тегов"
Добрый день,
Можно взять компонент TFlowLayout с плавающей разметкой внутренних компонентов. Накидывать туда TLabel со специальным стилем и AutoSize. Там где нужен перенос вставлять TFlowLayoutBreak.
Всплывающий список со списком, я думаю не проблема. Можно взять TPopup с TListBox. Можно просто заюзать пикеры FMX.Pickers.pas. Взять пикер TCustomListPicker
-
Pax Beach отреагировална Rusland в Фильтр по типу "облака тегов"
Можно наверное воспользоваться TRoundRect, изменив Fill Color и Stroke Color на #FF4B90BE и положить на него пару TText... будет похоже.
Самое трудное придумать как их объединять в ряды.
-
Pax Beach отреагировална Просто Проги в Как listbox можно добавить стиль для items которые не выделены
Суть такова копаюсь в стилях, но не могу понять откуда идет наследования есть контейнер content в нем есть selection т,е выделенный элемент лист бокса , возможно ли создать стиль просто для итемов в листбоксе или это не делается через стиль?
-
Pax Beach получил реакцию от Rusland в Получить голос из микрофона потоками
... или обычный TJMediaRecorder?
Вот готовый пример записи микрофона в файл.
Так не подойдет?
А определение уровней звукозаписи для нормализации (normalization) — это обычно постпроцесс, выполняемый для всего файла записи.
-
Pax Beach получил реакцию от azm_ezm_ivan в Получить голос из микрофона потоками
... или обычный TJMediaRecorder?
Вот готовый пример записи микрофона в файл.
Так не подойдет?
А определение уровней звукозаписи для нормализации (normalization) — это обычно постпроцесс, выполняемый для всего файла записи.
-
Pax Beach отреагировална Rusland в как из сервиса узнать, что приложение основное сейчас закрыто
брал отсюда
Интересно что в стандартном Androidapi.JNI.App.pas вроде те же функции описаны, но с ним не получается работать.
-
Pax Beach получил реакцию от Kitty в После "сна" программа с сервисом не стартует
При таких параметрах SDK Manager у меня в Берлине не виснет:
SDK
NDK
JAVA
-
Pax Beach получил реакцию от Равиль Зарипов (ZuBy) в как из сервиса узнать, что приложение основное сейчас закрыто
А где ты их взял?
В SDK другие методы в этих классах: приложение и сервис.
С этими все получилось =)))
Спасибо!
-
Pax Beach получил реакцию от Rusland в После "сна" программа с сервисом не стартует
При таких параметрах SDK Manager у меня в Берлине не виснет:
SDK
NDK
JAVA
-
Pax Beach получил реакцию от Равиль Зарипов (ZuBy) в Получить голос из микрофона потоками
... или обычный TJMediaRecorder?
Вот готовый пример записи микрофона в файл.
Так не подойдет?
А определение уровней звукозаписи для нормализации (normalization) — это обычно постпроцесс, выполняемый для всего файла записи.
-
Pax Beach получил реакцию от Вольдемар в Запись и сохранение голоса в течение 10 секунд после запуска Android сервиса (Пример)
Я реализовал пример работы с микрофоном и таймером в Android сервисе, как указано в теме вопроса.
Каждый раз, когда вы отправляете в сервис StartCommand или сервис перезапускается, включается запись с микрофона, и сохраняется в каталог с музыков в файл "myrecord.3gp".
Надеюсь, мой пример поможет вам создать новые полезные решения. В этом случае пожалуйста делитесь ими с участниками нашего сообщества.
Для отладки своих программ на Android используйте запись в LOGI и чтение при помощи monitor.bat (PlatformSDKs\android-sdk-windows\tools).
uses ... AndroidApi.JNI.Media, // JMediaRecorder AndroidApi.Timer, // Timer ...; Const TimerInterval = 1000; TimerCounterSecLimit = 10; type TDM = class(TAndroidService) ... private FTimerHandle: Integer; FRecording: Boolean; procedure StartRecord; procedure StopRecord; procedure StartTimer; procedure StopTimer; public FAudioRec: JMediaRecorder; end; procedure Log(const Fmt: string; const Params: array of const); overload; var Msg: string; M: TMarshaller; begin Msg := Format(Fmt, Params); LOGI(M.AsUtf8(Msg).ToPointer); end; procedure Log(const Source: string); overload; var M: TMarshaller; begin LOGI(M.AsUtf8(Source).ToPointer); end; procedure TDM.AndroidServiceCreate(Sender: TObject); begin FTimerHandle := 0; FTimerCounter := 0; FRecording := false; end; procedure TDM.AndroidServiceDestroy(Sender: TObject); begin StopTimer; StopRecord; end; function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; begin if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then begin StopTimer; StopRecord; Result := TJService.JavaClass.START_NOT_STICKY; // don't reload service Log('- service stoped', []); end else begin if not FRecording then begin Log('... sound record to be started', []); StartRecord; StartTimer; end; Result := TJService.JavaClass.START_STICKY; // rerun service if it stops Log('+ Service started', []); end; end; procedure TDM.StartRecord; begin StopRecord; FAudioRec := TJMediaRecorder.Create; FAudioRec.setAudioSource(TJMediaRecorder_AudioSource.JavaClass.MIC); FAudioRec.setOutputFormat(TJMediaRecorder_OutputFormat.JavaClass.THREE_GPP); FAudioRec.setAudioEncoder(TJMediaRecorder_AudioEncoder.JavaClass.AMR_NB); FAudioRec.setOutputFile(StringToJString(TPath.Combine(TPath.GetSharedMusicPath, 'myrecord.3gp'))); try FAudioRec.Prepare(); FAudioRec.start; FRecording := True; Log('+ Start record to %s', [TPath.Combine(TPath.GetSharedMusicPath, 'myrecord.3gp')]); except on E: Exception do Log('- Error in mic recording: %s', [E.Message]); end; end; procedure TDM.StopRecord; begin if Assigned(FAudioRec) then begin if FRecording then begin FRecording := false; try FAudioRec.stop(); FAudioRec.release(); Log('- Mic recording is stoped'); except on E: Exception do Log('- Error in mic stop recording: %s', [E.Message]); end; end; end else begin FRecording := false; end; end; procedure TDM.WaitComplete(TimerId: Integer); begin if FTimerCounter < TimerCounterSecLimit then begin Log('+++ Timer is triggered %d time.', [FTimerCounter]); inc(FTimerCounter); end else StopTimer; end; procedure TDM.StartTimer; begin FTimerCounter := 0; if FTimerHandle = 0 then begin FTimerHandle := AndroidTimerCreate; AndroidTimerSetInterval(FTimerHandle, TimerInterval); end; AndroidTimerSetHandler(WaitComplete); Log('+ Timer started', []); end; procedure TDM.StopTimer; begin if FTimerHandle > 0 then begin Log('... MIC recording to be stopped'); StopRecord; AndroidTimerSetHandler(nil); Log('- Timer stoped', []); end; end; end.
-
Pax Beach отреагировална Равиль Зарипов (ZuBy) в как из сервиса узнать, что приложение основное сейчас закрыто
всего-то нужны было дописать
procedure TForm9.Button2Click(Sender: TObject); // Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.JavaTypes, // Androidapi.JNIBridge, Androidapi.JNI.App, Androidapi.Helpers, Androidapi.JNI.ActivityManager; var ActivityServiceManager: JObject; FActivityManager: JActivityManager; List: JList; Iterator: JIterator; ri: JActivityManager_RunningServiceInfo; begin ActivityServiceManager := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.ACTIVITY_SERVICE); FActivityManager := TJActivityManager.Wrap((ActivityServiceManager as ILocalObject).GetObjectID); List := FActivityManager.getRunningServices(MAXINT); Iterator := List.Iterator; while Iterator.hasNext do begin ri := TJActivityManager_RunningServiceInfo.Wrap((Iterator.next as ILocalObject).GetObjectID); with ListView1.Items.Add do begin Text := JStringToString(ri.service.getPackageName); Detail := JStringToString(ri.service.getClassName); end; end; end; ri.service.getPackageName - показывает родителя сервиса (т.е. приложение)
-
Pax Beach отреагировална Rusland в как из сервиса узнать, что приложение основное сейчас закрыто
Виноват
Это вот апи скачанные с интернета: AndroidApi.zip
В uses
Androidapi.JNI.GraphicsContentViewText, // TJIntent (Receive Intent) Androidapi.JNI.JavaTypes, // JList Androidapi.JNIBridge, // ILocalObject Androidapi.JNI.App, // TJService Androidapi.Helpers, // StringToJString AndroidApi.Log, // LOGI Androidapi.JNI.RunningServiceInfo, // поиск запущенных приложений - https://stackoverflow.com/questions/34262554/how-to-check-if-a-service-is-running-in-delphi-10-seattle Androidapi.JNI.ActivityManager, // поиск запущенных приложений - http://blog.csdn.net/flcop/article/details/17190009uses b:boolean;
-
Pax Beach отреагировална Равиль Зарипов (ZuBy) в Получить голос из микрофона потоками
а где инициализация?
recorder:Jmediarecorder; -
Pax Beach отреагировална Alex7wrt в Зависание приложения при разворачивании после поворота экрана, Android
Я так понимаю,у меня одного возникает такая проблема, и никто с таким не встречался?
Может быть стоит создавать баннер средствами JNI на основе стандартного баннера Android?
Тут еще такой вопрос: в Berlin есть модуль FMX.Advertising.Android. Есть ли у кого-нибудь опыт работы с этим модулем?
-
Pax Beach получил реакцию от zairkz в Диалоговое окно на Андроид.
Не бейте сильно, но только вот такое безобразие в голову пришло =)
procedure TFormMain.DialogEvent(Sender: TObject); var i: integer; s: string; begin s := ''; try for i := 0 to 1000 do s := s + (Sender as TMyInputQuery).Values[i] + #13#10; finally end; ShowMessage('TNotifyEvent '#13#10 + s); end; UPD:
Отупение прошло. Но класс мне, конечно, надо будет переписать.
procedure TFormMain.DialogEvent(Sender: TObject); var i: integer; s: string; begin s := ''; for i := 0 to (Sender as TMyInputQuery).Edits.count - 1 do s := s + (Sender as TMyInputQuery).Values[i] + #13#10; ShowMessage('TNotifyEvent '#13#10 + s); end;
-
Pax Beach получил реакцию от Andrey Efimov в Получить голос из микрофона потоками
Просьба код оформлять в специально предназначенном для этого
блоке код
1. Для чего здесь объявлены AudioMem и AudioStream, если они не используются?
2. для чего приведение типа в конструкциях
(AudioRecorder as JAudioRecord) Без этого не вызываются методы?
3. Когда перестает работать таймер и что выполняется по его событию, как часто?
4. Вообще логику работы примера нельзя ли описать в комментариях над строчками кода? Пока не очень понятно, как это должно работать?
-
Pax Beach отреагировална Равиль Зарипов (ZuBy) в Проблема в Android 6.0
в чем проблема?
1) при авторизации выдать клиенту токен
2) токен записать в базу и ограничить по времени
3) при каждом новом заходе в приложение, старый токен убивать, новый выдавать (вот вам сессия)
4) при "живой сессии" не запрашивать пин-код
5) Profit!
-
Pax Beach получил реакцию от Равиль Зарипов (ZuBy) в Проблема в Android 6.0
Вот с какой стати модуль будет доступен, если приложение и сервис — это разные проекты.
-
Pax Beach получил реакцию от rareMax в Проблема в Android 6.0
В смысле — нельзя — 152-ФЗ? Вы уже обрабатываете персональные данные, значит должны были получить на это разрешение разрешение.
В оперативной памяти хранятся данные, чем это от недр отличается? Можно передавать данные через LocalBroadcastReceiver, если объем не большой.
-
Pax Beach отреагировална Fedor K в Работа с намерениями в iOS
Один из вариантов открытия одного приложения из другого - это использование URL schemes (Ярослав давал выше ссылку).
Из приложение А:
//отправка uses Macapi.Helpers, FMX.Helpers.iOS; //делаем намерение открыть URL (по сути тоже самое Intent в Android) SharedApplication.openURL(StrToNSUrl(Url)); Приложение Б (подробнее, хотя немного устарело):
//подписываемся на события if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(aFMXApplicationEventService)) then aFMXApplicationEventService.SetApplicationEventHandler(HandleAppEvent); //обработчик function HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; var lURL : string; begin case AAppEvent of TApplicationEvent.OpenURL : begin lURL := (AContext as TiOSOpenApplicationContext).URL; //реализуем логику end; Как передать файлы я вижу несколько вариантов:
- использовать буфер обмена (класс UIPasteboard - думаю не сложно его использовать в FMX, я им пользовался только в Xamarin, на FMX возможно (нужно проверить) можно использовать FMX.Platform.IFMXClipboardService). Перед открытием URL в "А" - сохраняем картинку/файл в буфер обмена, в "Б" при открытии считываем.
- передавать в URL путь к файлу (это возможно только, если и "А" и "Б" являются приложением одной группы). пример с Object-C.
-
Pax Beach отреагировална Brovin Yaroslav в Работа с намерениями в iOS
По идеи можно. Просто используйте нативное апи. TfgApplicationEvent здесь не поможет. Нужно перехватить сообщение с урлом TApplicationEventMessage