PowerOwl Опубликовано 25 июня, 2021 Поделиться Опубликовано 25 июня, 2021 Здравствуйте, у меня есть вопрос: можно-ли с помощью Firemonkey каким-либо образом сменить обои на рабочем столе Android? Я уже облазил весь интернет, нигде не смог найти ответа на свой вопрос. Использую Rad Studio 10.4. Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 26 июня, 2021 Модераторы Поделиться Опубликовано 26 июня, 2021 Посмотрите в сторону Android API: WallpaperManager, вероятно, с помощью этого апи можно менять обои. Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 26 июня, 2021 Автор Поделиться Опубликовано 26 июня, 2021 3 часа назад, Andrey Efimov сказал: Посмотрите в сторону Android API: WallpaperManager, вероятно, с помощью этого апи можно менять обои. Спасибо, попробую Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 26 июня, 2021 Автор Поделиться Опубликовано 26 июня, 2021 5 часов назад, Andrey Efimov сказал: Посмотрите в сторону Android API: WallpaperManager, вероятно, с помощью этого апи можно менять обои. Подскажите, пожалуйста, как это чудо подключить к проекту. С помощью Java2OP создал bridge-файл, но не знаю, как его подключить. В справке Embarcadero сказано, что можно подключить через Project manager, но там нужен .jar файл, который я не знаю, откуда взять. Заранее спасибо, я ещё новичок в Firemonkey. Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 26 июня, 2021 Модераторы Поделиться Опубликовано 26 июня, 2021 Для стандартного АПИ, в большинстве случаев, достаточно иметь только обёртку (.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 Ingalime 1 Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 27 июня, 2021 Автор Поделиться Опубликовано 27 июня, 2021 23 часа назад, Andrey Efimov сказал: Для стандартного АПИ, в большинстве случаев, достаточно иметь только обёртку (.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 Спасибо, написал небольшой пример. Всё компилируется, устанавливается, но при нажатии на кнопку показывается ошибка "Access violation at address 98CCCD32, accessing address 00000000", в RAD Studio показывается ошибка "Segmentation fault(11)" и указывается на строку с открытием картинки. Дал разрешение Set Wallpaper. Устройство Samsung Galaxy Note 4 SM-N910C, Android 6.0.1. Код: //Подключить System.IOUtils, Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.JNI.Util, Androidapi.helpers, Android.app.WallpaperManager; procedure TForm1.Button1Click(Sender: TObject); var path: string; str:JString; Wallpaper: JWallpaperManagerClass; Image:JBitmap; BitmapFact:JBitmapFactoryClass; begin if Edit1.Text <> ' ' then begin path := Tpath.Combine(Tpath.GetDocumentsPath, Edit1.Text); str:=StringToJString(path); Image := BitmapFact.decodeFile(str); //Тут ошибка try Wallpaper.setBitmap(Image); except ShowMessage('Не удалось установить обои'); end; end; end; Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 27 июня, 2021 Модераторы Поделиться Опубликовано 27 июня, 2021 Используйте вот такое обращение к этому методу Image := TJBitmapFactory.JavaClass.decodeFile(str); Ingalime 1 Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 28 июня, 2021 Автор Поделиться Опубликовано 28 июня, 2021 19 часов назад, Andrey Efimov сказал: Используйте вот такое обращение к этому методу Image := TJBitmapFactory.JavaClass.decodeFile(str); Попробовал использовать. Ошибка пропала, но появилась новая. Когда программа доходит до установки обоев, то появляется ошибка в файле Androidapi.JNIMarshall "Invoke error: Method not found", и обои сбрасываются на стандартные. Ещё нашёл статью, где рассказывается о использовании WallpaperManager: https://www.fmxexpress.com/code-snippet-to-set-the-device-wallpaper-in-delphi-xe7-firemonkey-on-android/ Попробовал использовать пример оттуда, пришлось его немного отредактировать, т.к. в нём были ошибки. Там используется полностью транслированное API, о котором Вы писали выше(в своём примере я использую файл, сгенерированный в Java2OP, и он использует только встроенные библиотеки). Также мне пришлось немного переписать android.graphics.BitmapFactory , потому что в качестве результатов некоторых функций там выступают JBitmap, и они путаются с классом JBitmap из встроенной библиотеки Androidapi.JNI.GraphicsContentViewText. Я изменил их на android.graphics.Bitmap.JBitmap. В общем, результат получился такой же: та же ошибка "Invoke error: Method not found". Код новой программы прикреплю. Код: procedure TForm1.Button1Click(Sender: TObject); var path: string; str:JString; Image:JBitmap; begin if Edit1.Text <> '' then begin path := Tpath.Combine(Tpath.GetDocumentsPath, Edit1.Text); str:=StringToJString(path); try Image:= TJBitmapFactory.JavaClass.decodeFile(str); except ShowMessage('Не удалось декодировать'); end; try TJWallpaperManager.JavaClass.setBitmap(Image); except ShowMessage('Не удалось установить обои'); end; end; end; --------------------------------------------------- Код новой программы: // подключить System.IOUtils, AndroidAPI.JNIBridge, AndroidAPI.JNI.JavaTypes, AndroidAPI.JNI.GraphicsContentViewText, AndroidAPI.JNI.os, AndroidAPI.helpers, android.app.WallpaperManager, android.graphics.Bitmap, android.graphics.BitmapFactory; procedure TForm1.Button1Click(Sender: TObject); Var FWallpaperManager: jwallpapermanager; Thebitmaptoshow:android.graphics.Bitmap.JBitmap; BitmapFact:android.graphics.BitmapFactory.TJBitmapFactory; Factoryoptions: JBitmapFactory_Options; FFiletoopen: String; begin { Create a filename to save the image to } FFiletoopen := System.IOUtils.TPath.Combine (System.IOUtils.TPath.getdocumentspath, Edit1.text); { Create JBitmap options } Factoryoptions := TJBitmapFactory_Options.Create; { Read up on these in the android API } Factoryoptions.inJustDecodeBounds := true; Factoryoptions.inPreferQualityOverSpeed := true; Factoryoptions.inJustDecodeBounds := false; { Get the wallpaper manager instance } FWallpaperManager := tjwallpapermanager.Wrap ((SharedActivityContext.getSystemService (TJContext.JavaClass.WALLPAPER_SERVICE) as ILocalObject).GetObjectID); { Load the image we saved } TheBitmaptoShow := BitmapFact.JavaClass.decodeFile (StringToJString(FFiletoopen), Factoryoptions); { Set the Wallpaper } FWallpaperManager.setBitmap(TheBitmaptoShow); end; Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 28 июня, 2021 Модераторы Поделиться Опубликовано 28 июня, 2021 Ну смотрите: 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. Автоматический генератор обёрток иногда сбоит, рекомендую всегда проверять генерируемые обёртки. Результаты этих сбоев встречались как в личном опыте, так и у других разработчиков на форуме. Ingalime 1 Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 Спасибо за замечания, буду пытаться исправляться. 1) Спасибо, перечитал, разобрался 2) Приложу обёртку снизу 3) Я не могу понять, где взять Context для этого метода. В Java-примерах для его получения используют функцию getContext(), но в Firemonkey такой нет. unit android.app.WallpaperManager; interface uses Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.JNI.Util; type // ===== Forward declarations ===== JWallpaperInfo = interface;//android.app.WallpaperInfo JWallpaperManager = interface;//android.app.WallpaperManager // ===== Interface declarations ===== JWallpaperInfoClass = interface(JObjectClass) ['{D1CC9CBB-D53F-4F29-ADA9-DD0BF04B0C86}'] {class} function _GetCREATOR: JParcelable_Creator; cdecl; {class} function init(context: JContext; service: JResolveInfo): JWallpaperInfo; cdecl; {class} function describeContents: Integer; cdecl; {class} procedure dump(pw: JPrinter; prefix: JString); cdecl; {class} function getComponent: JComponentName; cdecl; {class} function getSettingsActivity: JString; cdecl; {class} function loadAuthor(pm: JPackageManager): JCharSequence; cdecl; {class} function loadDescription(pm: JPackageManager): JCharSequence; cdecl; {class} function toString: JString; cdecl; {class} procedure writeToParcel(dest: JParcel; flags: Integer); cdecl; {class} property CREATOR: JParcelable_Creator read _GetCREATOR; end; [JavaSignature('android/app/WallpaperInfo')] JWallpaperInfo = interface(JObject) ['{A357E89F-3891-4795-8207-B1416424D512}'] function getPackageName: JString; cdecl; function getServiceInfo: JServiceInfo; cdecl; function getServiceName: JString; cdecl; function loadIcon(pm: JPackageManager): JDrawable; cdecl; function loadLabel(pm: JPackageManager): JCharSequence; cdecl; function loadThumbnail(pm: JPackageManager): JDrawable; cdecl; end; TJWallpaperInfo = class(TJavaGenericImport<JWallpaperInfoClass, JWallpaperInfo>) end; JWallpaperManagerClass = interface(JObjectClass) ['{F16EBFA1-4C27-4869-BEAA-3112EC3303A9}'] {class} function _GetACTION_CHANGE_LIVE_WALLPAPER: JString; cdecl; {class} function _GetACTION_CROP_AND_SET_WALLPAPER: JString; cdecl; {class} function _GetACTION_LIVE_WALLPAPER_CHOOSER: JString; cdecl; {class} function _GetCOMMAND_DROP: JString; cdecl; {class} function _GetCOMMAND_SECONDARY_TAP: JString; cdecl; {class} function _GetCOMMAND_TAP: JString; cdecl; {class} function _GetEXTRA_LIVE_WALLPAPER_COMPONENT: JString; cdecl; {class} function _GetWALLPAPER_PREVIEW_META_DATA: JString; cdecl; {class} procedure clear; cdecl;//Deprecated {class} function getBuiltInDrawable(outWidth: Integer; outHeight: Integer; scaleToFit: Boolean; horizontalAlignment: Single; verticalAlignment: Single): JDrawable; cdecl; overload; {class} function getCropAndSetWallpaperIntent(imageUri: Jnet_Uri): JIntent; cdecl; {class} function getDesiredMinimumHeight: Integer; cdecl; {class} function getInstance(context: JContext): JWallpaperManager; cdecl; {class} function getWallpaperInfo: JWallpaperInfo; cdecl; {class} function hasResourceWallpaper(resid: Integer): Boolean; cdecl; {class} procedure sendWallpaperCommand(windowToken: JIBinder; action: JString; x: Integer; y: Integer; z: Integer; extras: JBundle); cdecl; {class} procedure setBitmap(bitmap: JBitmap); cdecl; {class} procedure setResource(resid: Integer); cdecl; {class} procedure setWallpaperOffsets(windowToken: JIBinder; xOffset: Single; yOffset: Single); cdecl; {class} procedure suggestDesiredDimensions(minimumWidth: Integer; minimumHeight: Integer); cdecl; {class} property ACTION_CHANGE_LIVE_WALLPAPER: JString read _GetACTION_CHANGE_LIVE_WALLPAPER; {class} property ACTION_CROP_AND_SET_WALLPAPER: JString read _GetACTION_CROP_AND_SET_WALLPAPER; {class} property ACTION_LIVE_WALLPAPER_CHOOSER: JString read _GetACTION_LIVE_WALLPAPER_CHOOSER; {class} property COMMAND_DROP: JString read _GetCOMMAND_DROP; {class} property COMMAND_SECONDARY_TAP: JString read _GetCOMMAND_SECONDARY_TAP; {class} property COMMAND_TAP: JString read _GetCOMMAND_TAP; {class} property EXTRA_LIVE_WALLPAPER_COMPONENT: JString read _GetEXTRA_LIVE_WALLPAPER_COMPONENT; {class} property WALLPAPER_PREVIEW_META_DATA: JString read _GetWALLPAPER_PREVIEW_META_DATA; end; [JavaSignature('android/app/WallpaperManager')] JWallpaperManager = interface(JObject) ['{A1B98FC3-5736-43BC-A41C-5588DC0D8838}'] procedure clearWallpaperOffsets(windowToken: JIBinder); cdecl; procedure forgetLoadedWallpaper; cdecl; function getBuiltInDrawable: JDrawable; cdecl; overload; function getDesiredMinimumWidth: Integer; cdecl; function getDrawable: JDrawable; cdecl; function getFastDrawable: JDrawable; cdecl; function isWallpaperSupported: Boolean; cdecl; function peekDrawable: JDrawable; cdecl; function peekFastDrawable: JDrawable; cdecl; procedure setStream(data: JInputStream); cdecl; procedure setBitmap(bitmap: JBitmap); cdecl; procedure setWallpaperOffsetSteps(xStep: Single; yStep: Single); cdecl; end; TJWallpaperManager = class(TJavaGenericImport<JWallpaperManagerClass, JWallpaperManager>) end; implementation procedure RegisterTypes; begin TRegTypes.RegisterType('android.app.WallpaperManager.JWallpaperInfo', TypeInfo(android.app.WallpaperManager.JWallpaperInfo)); TRegTypes.RegisterType('android.app.WallpaperManager.JWallpaperManager', TypeInfo(android.app.WallpaperManager.JWallpaperManager)); end; initialization RegisterTypes; end. Andrey Efimov 1 Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 29 июня, 2021 Модераторы Поделиться Опубликовано 29 июня, 2021 Если кода много, то можете прикреплять в виде файла или даже демки с кодом(в архиве), воспроизводящим проблему или попыткой решения задачи. Про контекст, получить можно , например так: uses ... Androidapi.Helpers, .... var Context: JContext; begin Context := TAndroidHelper.Context; или Context := SharedActivityContext; Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 Спасибо, понял. К сожалению, это опять-таки не исправило ошибку. В отладке я посмотрел, какие значения у объектов, и обнаружил, что у объекта Image значение nil. Тогда я посмотрел в Androidapi.JNI.GraphicsContentViewText.pas класс BitmapFactory, и там почему-то в разделе декларации методов объекта JBitmapFactory ничего нет. Возможно я ошибаюсь, но мне кажется, что так быть не должно. 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); str := StringToJString(path); Context:=SharedActivityContext; try Image := TJBitmapFactory.JavaClass.decodeFile(str); except ShowMessage('Не удалось декодировать'); end; try Wallpaper:=TJWallpaperManager.JavaClass.getInstance(Context); Wallpaper.setBitmap(Image); except ShowMessage('Не удалось установить обои'); end; end; end; Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 29 июня, 2021 Модераторы Поделиться Опубликовано 29 июня, 2021 18 минут назад, PowerOwl сказал: Спасибо, понял. К сожалению, это опять-таки не исправило ошибку. Прикрепите пожалуйста демо проект. Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 Хорошо, вот: project.7z Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 29 июня, 2021 Модераторы Поделиться Опубликовано 29 июня, 2021 а как вы указываете имя картинки, если её нет в проекте? Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 В edit вбиваю название, а картинку скинул в директорию программы на телефоне Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 29 июня, 2021 Модераторы Поделиться Опубликовано 29 июня, 2021 5 минут назад, PowerOwl сказал: В edit вбиваю название, а картинку скинул в директорию программы на телефоне В эту директорию "/data/data/<application ID>/files"? (т.е. вы используете устройство с root правами?) Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 Да, в неё Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 1 час назад, Andrey Efimov сказал: В эту директорию "/data/data/<application ID>/files"? (т.е. вы используете устройство с root правами?) Да, root на телефоне есть, но доступ к этой директории можно получить подключив телефон к компьютеру. Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 29 июня, 2021 Модераторы Поделиться Опубликовано 29 июня, 2021 Вот такая ошибка у вас вываливалась? Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 Да, именно такая Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 29 июня, 2021 Модераторы Поделиться Опубликовано 29 июня, 2021 17 часов назад, PowerOwl сказал: Да, именно такая Так, а чего сразу то не сообщили, какая именно ошибка?! (вот так всегда, в 95% случаев, приходится вытягивать всю информацию из людей...). Теперь по теме: 1) Касательно "Тогда я посмотрел в Androidapi.JNI.GraphicsContentViewText.pas класс BitmapFactory, и там почему-то в разделе декларации методов объекта JBitmapFactory ничего нет. Возможно я ошибаюсь, но мне кажется, что так быть не должно. " Ещё раз повторяю, изучите основы. Всё реализовано правильно. 2) В коде, с помощью TFile.Exists проверьте, существование файла. 3) Если проверка пишет, что файл есть, то скорее всего нужно поиграться с настройками BitmapFactory.Options, например с этими: var BitmapFactory_Options: JBitmapFactory_Options; begin BitmapFactory_Options.inJustDecodeBounds (эту пробуйте в первую очередь) BitmapFactory_Options.inPreferQualityOverSpeed BitmapFactory_Options.inSampleSize Image := TJBitmapFactory.JavaClass.decodeFile(StringToJString(FilePath), BitmapFactory_Options); Описание есть в документации к АПИ. p.s. У меня демо приложение работает(как на эмуляторе, так и на девайсе с 11 Андроидом), если файл существует в нужном месте. Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 Извиняюсь за потраченное время, я сам затупил... У меня клавиатура автоматически переключается в верхний регистр перед началом набора текста, и поэтому программа не могла найти файл. Забыл, что в C-подобных языках регистр имеет значение. В общем, программа работает. А что по поводу изучения основ, то я был бы рад их изучить, но не могу найти нигде нормальную(современную) литературу, где доходчиво объясняется использование библиотеки Firemonkey. P.S. Я ещё заметил, что у объектов класса JContext есть методы для работы с обоями, но в официальной документации Android сказано, что их вырезали в API Level 15, так что для программирования до Android 4.0 можно обойтись и без WallpaperManager Andrey Efimov 1 Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 (изменено) Оставлю тут код демо-проекта и обёртку для 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 Изменено 30 июня, 2021 пользователем PowerOwl Небольшое исправление Andrey Efimov и Ingalime 2 Цитата Ссылка на комментарий
0 Модераторы Andrey Efimov Опубликовано 29 июня, 2021 Модераторы Поделиться Опубликовано 29 июня, 2021 (изменено) Отлично. Вот ещё один момент, на эмуляторе с рут-правами и обычным перекидыванием файлов в директорию может появляться эта же ошибка. Видимо, это связано с правами на директорию, поэтому, чтобы ошибки не было, необходимо добавить необходимые файлы в проект через деплой (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 Изменено 29 июня, 2021 пользователем Andrey Efimov добавил ссылку на learndelphi Ingalime 1 Цитата Ссылка на комментарий
0 PowerOwl Опубликовано 29 июня, 2021 Автор Поделиться Опубликовано 29 июня, 2021 Спасибо за информацию. Цитата Ссылка на комментарий
Вопрос
PowerOwl
Здравствуйте, у меня есть вопрос: можно-ли с помощью Firemonkey каким-либо образом сменить обои на рабочем столе Android? Я уже облазил весь интернет, нигде не смог найти ответа на свой вопрос. Использую Rad Studio 10.4.
Ссылка на комментарий
25 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.