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

Ingalime

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

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

  • Посещение

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

    5

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

  1. Thanks
    Ingalime отреагировална PowerOwl в Android 10 и муз.плеер   
    На шестёрке все ещё падает.
  2. Thanks
    Ingalime отреагировална PowerOwl в Android 10 и муз.плеер   
    Ну так эмуляторы ведь есть.
  3. Thanks
    Ingalime отреагировална Олег Киреев в Android 10 и муз.плеер   
    На всякий случай. У меня устройство Самсунг Галакси J6 с Андроид 10. После клика на иконку идёт запрос на разрешение. Я разрешаю а потом приложение само закрывается и OS сообщает что приложение загрузилось не корректно и предлагает его закрыть.
    С Уважением. Олег.
  4. Thanks
    Ingalime отреагировална Andrey Efimov в Android 10 и муз.плеер   
    У меня на устройстве с Андроид 11 и эмуляторе с Андроид 7.1.2 приложение не падает.

    По теме, делайте дебаг версию и ищите устройство на котором падает, запускайте monitor.bat и приложение, снимайте логи и выкидывайте их сюда. Это нужно сделать как минимум для того чтобы убедиться в ваших догадках (что происходит падение из-за сервиса). Так же попробуйте вынести в кнопку код запуска сервиса.
    Документация по Foreground service: https://developer.android.com/guide/components/foreground-services
     
     
  5. Thanks
    Ingalime отреагировална PowerOwl в Android 10 и муз.плеер   
    Протестировал на устройстве с Android 10(Nokia 3.1), всё прекрасно работает. Музыка работает, при сворачивании не падает, с выключенным экраном тоже.
     

  6. Thanks
    Ingalime отреагировална PowerOwl в Android 10 и муз.плеер   
    Я попробовал запустить на Android 6.0.1, при старте падает после показа картинки. Однако я не знаю, какой минимальный sdk level у приложения, может оно и не должно запускаться на шестёрке. В любом случае, просто отписался.
    Хотя в манифесте написано, что minSdkVersion='23', что соответствует Андроид 6
  7. Thanks
    Ingalime отреагировална Олег Киреев в Android 10 и муз.плеер   
    Здравствуйте.
    Ваше приложение на моём устройстве с OS Android 10 "падает".
    С Уважением. Олег.
  8. Thanks
    Ingalime отреагировална Tumaso в Android 10 и муз.плеер   
    @Ingalime на Android 11 у меня работает

  9. Thanks
    Ingalime отреагировална Andrey Efimov в Android 10 и муз.плеер   
    Есть два варианта:
    1) Добавить в промежуточном манифесте (находится тут: Project\Android\Debug\AndroidManifest.xml)
    Находим:
    <service android:exported="false" android:name="com.embarcadero.services.serPublic" /> Заменяем на:
    <service android:exported="false" android:foregroundServiceType="mediaPlayback" android:name="com.embarcadero.services.serPublic" /> Делаем деплой проекта.
     
    2) Прописать сервис в шаблоне (находится тут: Project\AndroidManifest.template.xml)
    Примерно вот так.
    Находим:
    <%services%> Заменяем на:
    <service android:exported="false" android:foregroundServiceType="mediaPlayback" android:name="com.embarcadero.services.serPublic" /> <service android:exported="false" android:name="com.embarcadero.firebase.messaging.ProxyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:exported="true" android:name="com.google.firebase.messaging.FirebaseMessagingService"> <intent-filter android:priority="-500"> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:exported="false" android:name="com.google.firebase.components.ComponentDiscoveryService"> <meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar" android:value="com.google.firebase.components.ComponentRegistrar" /> </service> Делаем сборку и деплой.
     
    p.s. Возможно есть ещё способы, я давненько не касался темы сервисов..
  10. Thanks
    Ingalime отреагировална Tumaso в Android 10 и муз.плеер   
    Мне кажется, что </service> (после <service android:foregroundServiceType="mediaPlayback" />) лишнее и его нужно удалить, т.к. предыдущий тег уже закрыт
  11. Like
    Ingalime отреагировална PowerOwl в Использование Android DownloadManager   
    Здравствуйте! Хочу поделиться своим опытом в использовании класса android.app.DownloadManager из Android API.
    Понятно из названия, что этот класс предоставляет пользователю возможность скачивать и сохранять файлы из интернета. Конечно, можно использовать HTTPClient, но по моему мнению использование DownloadManager гораздо легче.
    Возможности, предоставляемые классом:
    1.Скачивание любого файла из интернета с последующим сохранением
    2.Вывод уведомления о процессе загрузки с настраиваемым названием и описанием
    3.Разрешение загрузки только через конкретный вид сети, через роуминг, когда девайс заряжается и т.д.
    Вот ссылки на официальную документацию по классу DownloadManager и его подклассу DownloadManager.Request: https://developer.android.com/reference/android/app/DownloadManager
    https://developer.android.com/reference/android/app/DownloadManager.Request
    Демо-проект и обёртку для класса и прикрепил внизу.
    В примере по нажатию на кнопку происходит загрузка картинки в директорию /storage/emulated/0/Pictures
    -----------------------------------------------------------------------------
    Для начала, необходимо подключить библиотеки, необходимые приложению для работы:
    uses androidapi.JNI.JavaTypes, androidapi.Helpers, androidapi.JNI.GraphicsContentViewText, android.app.DownloadManager, androidapi.JNI.Net, System.Permissions, Androidapi.JNI.Os; Теперь нужно запросить у пользователя разрешение на запись в хранилище:
    procedure TForm1.FormCreate(Sender: TObject); var WRITE_EXTERNAL_STORAGE:String; begin WRITE_EXTERNAL_STORAGE:=JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE); PermissionsService.DefaultService.RequestPermissions([WRITE_EXTERNAL_STORAGE], procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>) begin if (Length(AGrantResults)=1) and (AGrantResults[0]=TPermissionStatus.Granted) then ShowMessage('Permission granted!') else begin Showmessage('Permission Denied! Manually go to "Settings-Applications-Project1-Permissions" and set Storage permission!'); Application.Terminate; end; end ) end; Если разрешение получено, то появится сообщение "Permission granted!", если нет, то программа попросит пользователя перейти в настройки и установить разрешение вручную.
    Отлично, разрешение получено, теперь можно написать и саму процедуру загрузки файла.
    procedure Download(code: string); //процедура будет получать уникальный код картинки на сайте pixabay.com var DownloadManager: JDownloadManager; //Объект класса DownloadManager для загрузки файла DownloadRequest: JDownloadManager_Request; //Объект класса DownloadManager_Request для установки настроек загрузки link: JString; //Переменная для хранения ссылки URI, URIPath: JNet_URI; //В URI будем получать ссылку на картинку, в URIPath - путь к загруженной картинке в файловой системе DownloadPermission: JObject; //Объект для получения доступа к сервису загрузки begin link := StringToJString('https://pixabay.com/get/' + code + '_1280.jpg'); //получаем ссылку на картинку URI := TJNet_URI.JavaClass.parse(link); //заносим ссылку в URI URIPath := TJNet_URI.JavaClass.parse(StringToJString('file:///storage/emulated/0/Pictures/img.jpg')); //заносим путь в URIPath DownloadRequest := TJDownloadManager_Request.JavaClass.init(URI); //инициализируем DownloadRequest с ссылкой на файл DownloadRequest.setDestinationUri(URIPath); //Устанавливаем конечный путь в DownloadRequest DownloadPermission := SharedActivityContext.getSystemService //Получаем доступ к сервису загрузки (TJContext.JavaClass.DOWNLOAD_SERVICE); DownloadManager := TJDownloadManager.Wrap(DownloadPermission); //Даём доступ к сервису загрузки DownloadManager'у DownloadManager.enqueue(DownloadRequest); //Запускаем загрузку end; Вот и всё, осталось только процедура нажатия на кнопку
    procedure TForm1.Button1Click(Sender: TObject); begin Download('g1e06713e4c5d9a9c5356f9e481ca8c37a7800ff986743fe4364aef699782e22b6a41f794dfd54ed32783eb0a577dc21b4dd2ba8fd83b6722740285291263d718'); end; Теперь можно компилировать программу и проверить, работает-ли она. Если всё сработало, то в директории Pictures должен появиться файл "img.jpg", содержащий в себе изображение тюльпанов.
    Надеюсь, это Вам поможет, если у Вас будут проблемы с загрузкой файлов. Удачи в проектах!
    File Downloading.7z
  12. Like
    Ingalime отреагировална PowerOwl в [TWebBrowser] Можно ли получить доступ к элементам разметки страницы HTML?   
    Если я правильно понял, то
    .. uses System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent; .. procedure Button1.Click(Sender:TObject); begin Memo1.lines.LoadFromStream(NetHTTPClient1.Get('http://yoursite.com/').ContentStream); end;  
  13. Thanks
    Ingalime отреагировална Andrey Efimov в Android 10 и муз.плеер   
    <manifest> ... <service ... android:foregroundServiceType="mediaPlayback" /> </manifest> Более подробно можно почитать тут Foreground services - Declare foreground service types
  14. Thanks
    Ingalime отреагировална Andrey Efimov в Android 10 и муз.плеер   
    Возможно, для Андроид 10-11, необходимо указывать тип службы. (в манифесте: foregroundServiceType и в startForeground)
  15. Like
    Ingalime отреагировална gonzales в Прощай, APK. Google переходит на новый формат Android-приложений   
    Ну вот и приехали((
    https://4pda.to/2021/06/30/387350/proschaj_apk_google_perekhodit_na_novyj_format_android_prilozhenij/
     
    Генерация Android App Bundle появилась только в 10.4.2, но работает криво. У меня не подтянулись доп. библиотеки, криво работает TListboxItem, возможно еще есть какие-то косяки. 
    Но тем не менее советую уже сейчас посматривать в сторону перехода на новую версию
     
     
  16. Like
    Ingalime отреагировална Andrey Efimov в Firemonkey и обои рабочего стола   
    Отлично.
    Вот ещё один момент, на эмуляторе с рут-правами и обычным перекидыванием файлов в директорию может появляться эта же ошибка. Видимо, это связано с правами на директорию, поэтому, чтобы ошибки не было, необходимо добавить необходимые файлы в проект через деплой (Deployment Manager).
     
    По поводу книг, загляните сюда https://delphifmandroid.blogspot.com/p/blog-page_15.html, ещё полезное можно найти тут https://blogs.embarcadero.com/. Тут - https://www.youtube.com/watch?v=Q6vXbXFthLU&list=PLvs4_U1JSz61q3b-S1KcX4F5rbWPAEWsH , Ярослав выложил курс по стилям. И вот сюда - https://learndelphi.org/
     
    P.s. Студия не поддерживает разработку под версии Андроида ниже 5.1. http://docwiki.embarcadero.com/RADStudio/Sydney/en/Android_Devices_Supported_for_Application_Development
  17. Like
    Ingalime отреагировална PowerOwl в Firemonkey и обои рабочего стола   
    Оставлю тут код демо-проекта и обёртку для WallpaperManager, кому-нибудь в будущем пригодятся.
    // Подключить System.IOUtils, Androidapi.JNI.GraphicsContentViewText, // Androidapi.JNI.JavaTypes, // Androidapi.helpers, android.app.WallpaperManager; (android.app.WallpaperManager распаковать и закинуть к исходникам проекта) //перейти в Project->Options->Application->Uses permissions и поставить галочку напротив пункта "Set wallpaper" procedure TForm1.Button1Click(Sender: TObject); var path: string; str: JString; Wallpaper: JWallpaperManager; Image: JBitmap; Context: JContext; begin if Edit1.Text <> '' then begin path := Tpath.Combine(Tpath.GetDocumentsPath, Edit1.Text); //Вместо TPath.GetDocumentsPath можно написать путь к любой директории на //устройстве, вместо Edit1.text - название картинки(с расширением, важно соблюдать регистр!!!) str := StringToJString(path); Context := SharedActivityContext; try if FileExists(path) then begin ShowMessage('Файл найден'); Image := TJBitmapFactory.JavaClass.decodeFile(str) end else ShowMessage('Файл не найден'); except ShowMessage('Не удалось декодировать'); end; try Wallpaper := TJWallpaperManager.JavaClass.getInstance(Context); Wallpaper.setBitmap(Image); except ShowMessage('Не удалось установить обои'); end; end; end;  
    android.app.WallpaperManager.pas.7z
  18. Like
    Ingalime отреагировална A_l_ex в Андроид 9 и Интернет   
    Если кто-то когда-то столкнется с подобной проблемой, обязательно добавляйте в манифест эту строчку, она спасет Вам дни или Недели тупого бездумного кодинга, в надежде понять почему TWebBrowser не в силах отобразить фрейм(iframe в котором как оказалось потом есть обращение к HTTP). А вы сидите на Андройде 8.1 или ниже а заказчик например на 9 и выше. 
  19. Like
    Ingalime отреагировална Евгений Корепов в Андроид 9 и Интернет   
    На будущее - при создании темы указывайте все исходные данные (как минимум вашу версию среды), что бы люди не давали вам советы, а потом уже узнали советы для какой версии среды они вам нужны.
    Я поставил Берлин и попробовал - ничего не получилось, результат такой же как у вас. Разбираться времени нет.
    Вот вам варианты:
    1. Постарайтесь избавится от http и перейти на https. В наше время почти не возможно найти сайт http, даже самые отсталые  госслужбы перешли на https на своих порталах. Если это ваш сервер, то я могу проконсультировать по способам перевода его на https.
    2. Перейдите на Delphi 10.3.2.
    3. Сделайте на каком нибудь другом сервере прокладку между запросами приложения по https и запросами к вашему серверу по http.
     
  20. Like
    Ingalime отреагировална Andrey Efimov в Firemonkey и обои рабочего стола   
    Ну смотрите:
    1) Как я уже говорил, вам необходимо ознакомиться с основами транслирования и использования АПИ.
    Например тут: Как создавать обёртки для JAVA-кода и тут: Как подключить и использовать свой JAVA-класс (статьи "малость" старые, но суть сохранилась.)
    Единственное, что могу добавить (про обёртки):
    Всё, что находится в interface(JObjectClass) вызывается так: TJНазваниекласса.JavaClass.НазваниеМетода/Поля
    Всё, что находится в interface(JObject) вызывается только через предварительно созданный/полученный объект.
     
    2) На форуме, для кода используйте тег "Код", без подсветки кода (или как вам угодно). Это помогает повысить читабельность поста, отделить код от текста. Если вы используете обёртку не из стандартной поставки, то прикладывайте её к посту. Не редкость, что ошибки бывают в самих обёртках.
    3) Из-за первого пункта вы начали копировать другие решения (не обдумывая). Я буду исходить из вашего изначального кода.
    Вам должно быть достаточно подключения AndroidAPI.JNI.GraphicsContentViewText, там всё уже реализовано (это я про обёртку для использования JBitmap и JBitmapFactory).
    Далее моё "гадание на кофейной гуще" (т.к. обёртку для WallpaperManager в вашем сообщении я не вижу).
    Исхожу из того, что она сгенерирована правильно. Значит в вашем коде, перед использованием метода setBitmap(Image); необходимо получить доступ к объекту WallpaperManager. Заходим по ссылке Android API: WallpaperManager, смотрим на описание и методы, видим метод Android API: WallpaperManager#getInstance, делаем вывод, что с помощью этого метода сможем получить доступ к объекту WallpaperManager, а далее попытаться использовать метод setBitmap. На этом, моё предсказание завершено (само собой не факт, что оно верное, но если бы передо мной стояла такая задача, то в самом начале, я поступил бы именно так), остаётся только попробовать.
     
     
    p.s. Автоматический генератор обёрток иногда сбоит, рекомендую всегда проверять генерируемые обёртки. Результаты этих сбоев встречались как в личном опыте, так и у других разработчиков на форуме.
  21. Like
    Ingalime отреагировална gonzales в IOS и Push. На иконке в IOS всегда стоит ЕДИНИЧКА - как убрать ?   
    У меня исчезает при запуске приложения.
    А вообще, если Вы пользовались примером Равиля для отправки пуша, то в нем функция, в ней параметр badge отвечает за цифру
    function pushSend($title, $text, $tokens, $server_key) { $url = 'https://fcm.googleapis.com/fcm/send'; $headers = array('Authorization: key=' . $server_key, 'Content-Type: application/json'); if (is_array($tokens)) $fields['registration_ids'] = $tokens; else $fields['registration_ids'] = array($tokens); $fields['priority'] = 'high'; $badge = 1; $fields['notification'] = array('body' => $text, 'title' => $title, 'sound' => 'default', 'badge' => $badge); $fields['data'] = array('message' => $text, 'title' => $title); $jsonfields = json_encode($fields); print_r($jsonfields); $ch = curl_init(); curl_setopt_array($ch, array( CURLOPT_URL => $url, CURLOPT_POST => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_POSTFIELDS => json_encode($fields) )); $result = curl_exec($ch); curl_close($ch); if ($result === false) return false; $json = json_decode($result, true); if ($json['success'] == 0) return false; else return true; }  
  22. Like
    Ingalime отреагировална Andrey Efimov в Firemonkey и обои рабочего стола   
    Используйте вот такое обращение к этому методу
    Image := TJBitmapFactory.JavaClass.decodeFile(str);  
  23. Like
    Ingalime отреагировална Andrey Efimov в Firemonkey и обои рабочего стола   
    Для стандартного АПИ, в большинстве случаев, достаточно иметь только обёртку (.pas файл).
    Какая то часть обёрток для АПИ всегда идёт со студией в комплекте (найти можно тут: C:\Program Files (x86)\Embarcadero\Studio\версиястудии\source\).
    Если нужной вам обёртки нет в комплекте со студией, то либо генерите её самостоятельно, либо скачиваете с GitHub'а. На форуме есть упоминание об этом: Полностью транслированное Android API 7-23 уровня
    Для сторонних jar - библиотек, необходимо иметь саму библиотеку в виде jar файла и обёртку к ней.
     
    В вашем случае, должно хватить (если не брать во внимание callback OnColorsChangedListener) простого указания .pas файла в секции uses вашего приложения.
     
    p.s. Все начальные вопросы уже много раз обсуждались на форуме и в различных блогах, ищите, читайте, пробуйте
    p.s.2. Можете "покопаться", например, тут (https://delphifmandroid.blogspot.com/p/blog-page_27.html), тут (https://github.com/AndrewEfimov) и тут (http://yaroslavbrovin.ru/). Ну и конечно же, если вы хотите использовать специфичные функции Андроида, то необходимо ознакомиться https://developer.android.com
  24. Like
    Ingalime отреагировална A_l_ex в Нативные контролы   
    Вопрос снят. Решение нашлось: 
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      CallInUIThreadAndWaitFinishing(
      procedure
      function BitmapToJBitmap(const ABitmap: TBitmap): JBitmap;
      var LSurface: TBitmapSurface;
      begin
        Result := TJBitmap.JavaClass.createBitmap(ABitmap.Width, ABitmap.Height, TJBitmap_Config.JavaClass.ARGB_8888);
        LSurface := TBitmapSurface.Create;
        try
          LSurface.Assign(ABitmap);
          SurfaceToJBitmap(LSurface, Result);
        finally
          LSurface.Free;
        end;
      end;
      var AStream: TMemoryStream;
          ABitmap: TBitmap;
          FImage: JImageView;
          Container: JRelativeLayout;
          LP: JRelativeLayout_LayoutParams;
      begin
        AStream := TMemoryStream.Create;
        ABitmap := TBitmap.Create;
        try
          with THTTPClient.Create do begin
            Get('URL до картинки', AStream);
            AStream.Position := 0;
            ABitmap.LoadFromStream(AStream);
            Free;
          end;
          FImage := TJImageView.JavaClass.init(TAndroidHelper.Activity);
          FImage.setLayoutParams(LP);
          FImage.setImageBitmap(BitmapToJBitmap(ABitmap));
          Container := TJRelativeLayout.JavaClass.init(TAndroidHelper.Context);
          LP := TJRelativeLayout_LayoutParams.JavaClass.init(Round(Width * 1), Round(Height * 1));
          LP.addRule(TJRelativeLayout.JavaClass.ALIGN_PARENT_TOP, TJRelativeLayout.JavaClass.TRUE);
          LP.addRule(TJRelativeLayout.JavaClass.ALIGN_PARENT_BOTTOM, TJRelativeLayout.JavaClass.TRUE);
          LP.addRule(TJRelativeLayout.JavaClass.ALIGN_PARENT_LEFT, TJRelativeLayout.JavaClass.TRUE);
          LP.addRule(TJRelativeLayout.JavaClass.ALIGN_PARENT_RIGHT, TJRelativeLayout.JavaClass.TRUE);
          Container.addView(FImage, LP);
          MainActivity.setContentView(Container);
        finally
          AStream.Free;
          ABitmap.Free;
        end;
      end);
    end;
  25. Like
    Ingalime отреагировална A_l_ex в Номер версии андроид   
    Возможно кому-то будет нужно: 
    C:\Users\Public\Documents\Embarcadero\Studio\(версия студии)\Samples\Object Pascal\Mobile Snippets\DeviceInfo
    Хорошее решение плясать не от SDK а от OSVersion.
×
×
  • Создать...