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

PowerOwl

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

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

  • Посещение

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

    7

Весь контент PowerOwl

  1. Если я правильно понял, то .. 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;
  2. Здравствуйте! Хочу поделиться своим опытом в использовании класса 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
  3. Оставлю тут код демо-проекта и обёртку для 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
  4. Извиняюсь за потраченное время, я сам затупил... У меня клавиатура автоматически переключается в верхний регистр перед началом набора текста, и поэтому программа не могла найти файл. Забыл, что в C-подобных языках регистр имеет значение. В общем, программа работает. А что по поводу изучения основ, то я был бы рад их изучить, но не могу найти нигде нормальную(современную) литературу, где доходчиво объясняется использование библиотеки Firemonkey. P.S. Я ещё заметил, что у объектов класса JContext есть методы для работы с обоями, но в официальной документации Android сказано, что их вырезали в API Level 15, так что для программирования до Android 4.0 можно обойтись и без WallpaperManager
  5. Да, root на телефоне есть, но доступ к этой директории можно получить подключив телефон к компьютеру.
  6. В edit вбиваю название, а картинку скинул в директорию программы на телефоне
  7. Спасибо, понял. К сожалению, это опять-таки не исправило ошибку. В отладке я посмотрел, какие значения у объектов, и обнаружил, что у объекта 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;
  8. Спасибо за замечания, буду пытаться исправляться. 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.
  9. Попробовал использовать. Ошибка пропала, но появилась новая. Когда программа доходит до установки обоев, то появляется ошибка в файле 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;
  10. Спасибо, написал небольшой пример. Всё компилируется, устанавливается, но при нажатии на кнопку показывается ошибка "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;
  11. Подскажите, пожалуйста, как это чудо подключить к проекту. С помощью Java2OP создал bridge-файл, но не знаю, как его подключить. В справке Embarcadero сказано, что можно подключить через Project manager, но там нужен .jar файл, который я не знаю, откуда взять. Заранее спасибо, я ещё новичок в Firemonkey.
  12. Здравствуйте, у меня есть вопрос: можно-ли с помощью Firemonkey каким-либо образом сменить обои на рабочем столе Android? Я уже облазил весь интернет, нигде не смог найти ответа на свой вопрос. Использую Rad Studio 10.4.
×
×
  • Создать...