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

Firemonkey и обои рабочего стола


PowerOwl

Вопрос

Здравствуйте, у меня есть вопрос: можно-ли с помощью Firemonkey каким-либо образом сменить обои на рабочем столе Android? Я уже облазил весь интернет, нигде не смог найти ответа на свой вопрос. Использую Rad Studio 10.4.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
5 часов назад, Andrey Efimov сказал:

Посмотрите в сторону Android API: WallpaperManager, вероятно, с помощью этого апи можно менять обои.

 

Подскажите, пожалуйста, как это чудо подключить к проекту. С помощью Java2OP создал bridge-файл, но не знаю, как его подключить. В справке Embarcadero сказано, что можно подключить через Project manager, но там нужен .jar файл, который я не знаю, откуда взять. Заранее спасибо, я ещё новичок в Firemonkey.

Ссылка на комментарий
  • 0
  • Модераторы

Для стандартного АПИ, в большинстве случаев, достаточно иметь только обёртку (.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

Ссылка на комментарий
  • 0
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
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
  • Модераторы

Ну смотрите:

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. Автоматический генератор обёрток иногда сбоит, рекомендую всегда проверять генерируемые обёртки. Результаты этих сбоев встречались как в личном опыте, так и у других разработчиков на форуме.

Ссылка на комментарий
  • 0

Спасибо за замечания, буду пытаться исправляться.

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.

 

Ссылка на комментарий
  • 0
  • Модераторы

Если кода много, то можете прикреплять в виде файла или даже демки с кодом(в архиве), воспроизводящим проблему или попыткой решения задачи.

Про контекст, получить можно , например так:

uses 
	... Androidapi.Helpers, ....

var
	Context: JContext;
begin
	Context := TAndroidHelper.Context;
	или
	Context := SharedActivityContext;

 

Ссылка на комментарий
  • 0

Спасибо, понял. К сожалению, это опять-таки не исправило ошибку. В отладке я посмотрел, какие значения у объектов, и обнаружил, что у объекта 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;

356519003_29-06-202118-28-52.thumb.png.cd72f9251da604744ff9dc6e8137dd1d.png

Ссылка на комментарий
  • 0
  • Модераторы
5 минут назад, PowerOwl сказал:

В edit вбиваю название, а картинку скинул в директорию программы на телефоне

В эту директорию "/data/data/<application ID>/files"? (т.е. вы используете устройство с root правами?)

Ссылка на комментарий
  • 0
1 час назад, Andrey Efimov сказал:

В эту директорию "/data/data/<application ID>/files"? (т.е. вы используете устройство с root правами?)

Да, root на телефоне есть, но доступ к этой директории можно получить подключив телефон к компьютеру.

Ссылка на комментарий
  • 0
  • Модераторы
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

Извиняюсь за потраченное время, я сам затупил... У меня клавиатура автоматически переключается в верхний регистр перед началом набора текста, и поэтому программа не могла найти файл. Забыл, что в C-подобных языках регистр имеет значение. В общем, программа работает.

А что по поводу изучения основ, то я был бы рад их изучить, но не могу найти нигде нормальную(современную) литературу, где доходчиво объясняется использование библиотеки Firemonkey.

P.S. Я ещё заметил, что у объектов класса JContext есть методы для работы с обоями, но в официальной документации Android сказано, что их вырезали в API Level 15, так что для программирования до Android 4.0 можно обойтись и без WallpaperManager

Ссылка на комментарий
  • 0

Оставлю тут код демо-проекта и обёртку для 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

Изменено пользователем PowerOwl
Небольшое исправление
Ссылка на комментарий
  • 0
  • Модераторы

Отлично.

Вот ещё один момент, на эмуляторе с рут-правами и обычным перекидыванием файлов в директорию может появляться эта же ошибка. Видимо, это связано с правами на директорию, поэтому, чтобы ошибки не было, необходимо добавить необходимые файлы в проект через деплой (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

Изменено пользователем Andrey Efimov
добавил ссылку на learndelphi
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...