FAQ FM
Приложение

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

[Android] Как в run-time получить информацию, указанную в окне "Project->Options->Version Info"?

{for Delphi XE6: Add to "uses" module "Androidapi.Helpers"}
uses
  {..., } Androidapi.JNI.JavaTypes, FMX.Helpers.Android,
  Androidapi.JNI.GraphicsContentViewText
  {$IF CompilerVersion >= 20}, Androidapi.Helpers{$ENDIF};
 
// В примере показано как получить versionName
procedure TForm1.Button1Click(Sender: TObject);
var
  PackageManager: JPackageManager;
  VersionPackage, PackageName: JString;
begin
   PackageManager := SharedActivity.getPackageManager;
   PackageName := SharedActivityContext.getPackageName;
   
   VersionPackage := PackageManager.getPackageInfo( PackageName, 0 ).versionName;
   Label1.Text := JStringToString( VersionPackage );
end;


[MacOS] Как изменить прозрачность формы (альфа-канал)?

uses
  Macapi.AppKit, FMX.Platform.Mac;

procedure TForm1.Button1Click(Sender: TObject);
var
  Wnd: NSWindow;
begin
   Wnd := WindowHandleToPlatform( Form1.Handle ).Wnd;
   Wnd.setAlphaValue( 0.5 ); // Диапазон: 0 .. 1.0
   // Узнать значение текущего альфа-канала можно так:
   Caption := FloatToStr( Wnd.alphaValue );
end;


[MacOS] Как ограничить размер растяжения/сжатия формы?

uses
  FMX.Platform.Mac, Macapi.CoreGraphics;

procedure SetFormMinSize( const AForm: TForm; const AMinSize: TSize );
var
  MacHandle: TMacWindowHandle;
begin
   MacHandle := WindowHandleToPlatform( AForm.Handle );
   MacHandle.Wnd.setMinSize( CGSizeMake( AMinSize.Width, AMinSize.Height ) );
end;

procedure SetFormMaxSize( const AForm: TForm; const AMaxSize: TSize );
var
  MacHandle: TMacWindowHandle;
begin
   MacHandle := WindowHandleToPlatform( AForm.Handle );
   MacHandle.Wnd.setMaxSize( CGSizeMake( AMaxSize.Width, AMaxSize.Height ) );
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
   SetFormMinSize( Self, TSize.Create( 500, 500 ) );
   SetFormMaxSize( Self, TSize.Create( 800, 800 ) );
end;


[Android] Как определить, установлено ли приложение или нет?

uses
  Androidapi.JNI.GraphicsContentViewText
  {$IF CompilerVersion >= 20}, Androidapi.Helpers{$ENDIF};

function IsAppInstalled( const AAppName: string ): Boolean;
var
  PackageManager: JPackageManager;
begin
   PackageManager := SharedActivity.getPackageManager;
   try
      PackageManager.getPackageInfo( StringToJString( AAppName ),
         TJPackageManager.JavaClass.GET_ACTIVITIES );
      Result := True;
   except
      on Ex: Exception do
         Result := False;
   end;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
   if IsAppInstalled( 'com.google.zxing.client.android' ) then
      ShowMessage( 'Приложение установлено' )
   else
      ShowMessage( 'Приложение не установлено' );
end;


[Windows, MacOS] Как отловить перемещение формы и изменение её размеров?

type
  TForm1 = class(TForm)
  public
    procedure SetBounds( ALeft, ATop, AWidth, AHeight: Integer ); override;
  end;

{...}

implementation

procedure TForm1.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
   inherited;
   Caption := Format( 'L: %d   T: %d   W: %d   H: %d', [ALeft, ATop, AWidth, AHeight] );
end;


[Windows, MacOS] Как перемещать форму за любой элемент?

procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
   // Свойство HitTest должен иметь значение True
   StartWindowDrag;
end;


[Android] Как установить ярлык на домашний экран Android?

uses
  Androidapi.JNI.GraphicsContentViewText, FMX.Helpers.Android, Androidapi.Helpers,
  Androidapi.JNI.JavaTypes, FMX.Platform.Android, AndroidApi.JniBridge,
  AndroidApi.JNI.App, AndroidAPI.Jni.OS;

procedure InstallShortcut( Action: string );
{$IFDEF ANDROID}
var
  ShortcutIntent: JIntent;
  addIntent: JIntent;
  wIconIdentifier: Integer;
  wIconResource: JIntent_ShortcutIconResource;
{$ENDIF}
begin
   {$IFDEF ANDROID}
   ShortcutIntent := TJIntent.JavaClass.init( SharedActivityContext, SharedActivityContext.getClass );
   ShortcutIntent.setAction( TJIntent.JavaClass.ACTION_MAIN );

   addIntent := TJIntent.Create;
   addIntent.putExtra( TJIntent.JavaClass.EXTRA_SHORTCUT_INTENT,
      TJParcelable.Wrap( ( shortcutIntent as ILocalObject ).GetObjectID ) );
   addIntent.putExtra( TJIntent.JavaClass.EXTRA_SHORTCUT_NAME, StringToJString( Application.Title ) );
   addIntent.setAction( StringToJString( Action ) );
   // Получаем идентификатор ресурса иконки
   wIconIdentifier := SharedActivity.getResources.getIdentifier( StringToJString( 'ic_launcher' ),
      StringToJString( 'drawable' ), StringToJString( 'com.embarcadero.Project1' ) ); // Имя должно быть указано правильно
   wIconResource := TJIntent_ShortcutIconResource.JavaClass.fromContext( SharedActivityContext, wIconIdentifier );
   // Устанавливаем значок для ярлыка
   addIntent.putExtra( TJIntent.JavaClass.EXTRA_SHORTCUT_ICON_RESOURCE,
      TJParcelable.Wrap( ( wIconResource as ILocalObject ).GetObjectID ) );

   SharedActivityContext.sendBroadcast( addIntent );
   {$ENDIF}
end;

// Создание ярлыка
// В манифесте должно быть прописано разрежение
// 
// На устройствах некоторых производителей (непример Sony) ярлыки можно создать
// до тех пор, пока на экране не закончится свободное место, а устройства от
// ASUS такого не допускают.
procedure TForm1.Button1Click(Sender: TObject);
begin
   {$IFDEF ANDROID}
   InstallShortcut( 'com.android.launcher.action.INSTALL_SHORTCUT' );
   {$ENDIF}
end;

// Удаление ярлыка
// В манифесте должно быть прописано разрежение
// 
// Если для приложения создано несколько ярлыков, они будут удалены все сразу.
procedure TForm1.Button2Click(Sender: TObject);
begin
   {$IFDEF ANDROID}
   InstallShortcut( 'com.android.launcher.action.UNINSTALL_SHORTCUT' );
   {$ENDIF}
end;


[Android] Как заставить устройство вибрировать?

// В манифесте должно быть прописано разрежение
// <uses-permission android:name="android.permission.VIBRATE" />
// Для этого в Uses Permissions» ставим галочку в пункте «Vibrate».

uses
  FMX.Helpers.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Os,
  Androidapi.Helpers, Androidapi.JNI.App, Androidapi.JNIBridge,
  Androidapi.JNI.GraphicsContentViewText;

// Проверяем, поддерживается ли вибрация
procedure TForm1.Button1Click(Sender: TObject);
var
  VibratorObj: JObject;
  Vibrator: JVibrator;
begin
   //VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
   VibratorObj := SharedActivity.getSystemService(TJContext.JavaClass.VIBRATOR_SERVICE);
   if Assigned(VibratorObj) then
   begin
      Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);
      if Assigned(Vibrator) then
         if Vibrator.hasVibrator() then
            ShowMessage('Вибрация поддерживается!')
         else
            ShowMessage('Вибрация НЕ поддерживается!')
      else
         ShowMessage('Вибрация НЕ поддерживается!');
   end;
end;

// Включение вибрации
procedure TForm1.Button2Click(Sender: TObject);
var
  VibratorObj: JObject;
  Vibrator: JVibrator;
begin
   //VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
   VibratorObj := SharedActivity.getSystemService(TJContext.JavaClass.VIBRATOR_SERVICE);
   if Assigned(VibratorObj) then
   begin
      Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);
      if Assigned(Vibrator) then
         Vibrator.vibrate(1000);
   end;
end;

// Вибрация по шаблону
procedure TForm1.Button3Click(Sender: TObject);

  function IntArrayToJArray(const Arr: array of Integer): TJavaArray<Int64>;
  var
    i: Integer;
  begin
     Result := TJavaArray<Int64>.Create(Length(Arr));
     for i := Low(Arr) to High(Arr) do
        Result.Items[i] := Arr[i];
  end;

var
  VibratorObj: JObject;
  Vibrator: JVibrator;
begin
   //VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
   VibratorObj := SharedActivity.getSystemService(TJContext.JavaClass.VIBRATOR_SERVICE);
   if Assigned(VibratorObj) then
   begin
      Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);
      if Assigned(Vibrator) then
         // Первый параметр – массив со значениями.
         // Первое значение в массиве означает длительность паузы, второе – длительность вибрации,
         //   третье – длительность паузы, четвёртое – длительность вибрации и т.д.
         // Второй параметр – это число повторов. «-1» значит, что повторять не надо.
         Vibrator.vibrate(IntArrayToJArray(
            // Тема из "Звездных войн" :)
            [0, 500, 110, 500, 110, 450, 110, 200, 110, 170, 40, 450, 110, 200, 110, 170, 40, 500]), -1);
   end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  VibratorObj: JObject;
  Vibrator: JVibrator;
begin
   //VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
   VibratorObj := SharedActivity.getSystemService(TJContext.JavaClass.VIBRATOR_SERVICE);
   if Assigned(VibratorObj) then
   begin
      Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);
      if Assigned(Vibrator) then
         Vibrator.cancel();
   end;
end;


[Android] Как определить текущий уровень громкости в приложении?

uses
  Androidapi.JNI.JavaTypes, Androidapi.JNI.Media, Androidapi.Helpers,
  Androidapi.JNI.App, Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
var
  AudioObj: JObject;
  Audio: JAudioManager;
begin
   if (Key = vkVolumeDown) or (Key = vkVolumeUp) then
   begin
      AudioObj := SharedActivity.getSystemService(TJContext.JavaClass.AUDIO_SERVICE);
      Audio := TJAudioManager.Wrap((AudioObj as ILocalObject).GetObjectID);
      lbCurrentVolume.Text := Audio.getStreamVolume(TJAudioManager.JavaClass.STREAM_RING).ToString;
      lbMaxVolume.Text := Audio.getStreamMaxVolume(TJAudioManager.JavaClass.STREAM_RING).ToString;
   end;
end;


Как изменить предпочитаемый графический процессор?

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage('Используемая канва: ' + Canvas.ClassName);
   // • TCanvasD2D - Direct 2D (Win)
   // • TCanvasGdiPlus - GDI + (Win)
   // • TCanvasGpu - GPU (Все платормы)
   // • TCanvasQuartz - Quartz (iOS, OSX)
end;

{$IFDEF MSWINDOWS}
initialization
   FMX.Types.GlobalUseDX := False;
//  FMX.Types.GlobalUseDXInDX9Mode := False;
//  FMX.Types.GlobalUseDXSoftware := False;
  FMX.Types.GlobalUseDirect2D := False;
//  FMX.Types.GlobalUseGPUCanvas := False;
{$ENDIF}

При использовании материала - ссылка на сайт обязательна