воскресенье, 12 января 2014 г.

Используем вибрацию на Android устройствах

Для работы с вибрацией на устройстве, воспользуемся Delphi XE5 и JNI(Android API: http://developer.android.com/reference/android/os/Vibrator.html).
Если вы перешли по ссылке, то видите, что для использования нам доступно 4 метода, это:
  • cancel() – Выключение вибрации.
  • hasVibrator() – Проверка, поддерживается ли вибрация
  • vibrate(long[] pattern, int repeat) – Вибрация по шаблону
  • vibrate(long milliseconds) – Вибрация в течении указанного времени (в миллисекундах)
Этого вполне достаточно для работы.
Я написал небольшое приложение демонстрирующее работу всех этих методов.

Upd (21.04.14). Проверено на Delphi XE6


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

Чтобы использовать вибрацию в своих приложениях, вам необходимо:
1) Дать разрешение в «Uses Permissions», пункт так и называется «Vibrate», ставим галочку
2) В uses подключаем модули:
uses
  FMX.Helpers.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Os,
  Androidapi.JNI.App, Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText;

3) Написать код, работающий с вибрацией :)

Теперь привожу код проекта, а после, некоторые объяснения:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Edit;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    ClearingEdit1: TClearingEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

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

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

procedure TForm1.Button1Click(Sender: TObject);
var
  VibratorObj: JObject;
  Vibrator: JVibrator;
begin
  VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
  Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);
  Vibrator.vibrate(StrToInt(ClearingEdit1.Text));
end;

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

procedure TForm1.Button3Click(Sender: TObject);
var
  VibratorObj: JObject;
  Vibrator: JVibrator;
begin
  VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
  Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);
  Vibrator.vibrate(IntArrayToJArray([1000, 5000, 3000, 1000]), -1);
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  VibratorObj: JObject;
  Vibrator: JVibrator;
begin
  VibratorObj := SharedActivity.getSystemService(TJActivity.JavaClass.VIBRATOR_SERVICE);
  Vibrator := TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);

  if Vibrator.hasVibrator() then
    showmessage('Вибрация поддерживается!')
  else
    showmessage('Вибрация НЕ поддерживается!');
end;

end.

Скорее всего, вы заметили в коде функцию «IntArrayToJArray». Эту функцию я написал и использовал в процедуре «TForm1.Button3Click», т.к. третий метод из нашего списка работает только с массивом типа «TJavaArray<Int64>». Поэтому в функции «IntArrayToJArray» я создаю такой массив.

Теперь рассмотрим процедуру «TForm1.Button3Click». В ней я использовал вибрацию по шаблону.
Третий метод «vibrate(long[] pattern, int repeat)» из списка имеет два параметра.
Первый параметр – это массив со значениями, например «[1000, 5000, 3000, 1000]», первое значение в массиве означает длительность паузы, второе – длительность вибрации, третье – длительность паузы, четвёртое – длительность вибрации и т.д.
Второй параметр – это число повторов. «-1» значит, что повторять не надо.

Вот вроде и всё. Как обычно внизу есть ссылка на проект, который появился вследствие этой заметки.



Спасибо за внимание и удачной вам разработки.

Исходный код проекта: Скачать с Google Drive

4 комментария:

  1. В Delphi XE7 заработало только с поправкой
    uses
    Androidapi.Helpers;

    ОтветитьУдалить
  2. На Samsung S4 вышеупомянутый способ вылетал, хотя на планшетах работает.
    Вот рабочий вариант в Delphi XE8:
    ==========================================================
    VibratorObj:= SharedActivityContext.getSystemService(TJContext.JavaClass.VIBRATOR_SERVICE);
    Vibrator:= TJVibrator.Wrap((VibratorObj as ILocalObject).GetObjectID);

    ОтветитьУдалить
  3. Использовал следующие units:

    uses
    Androidapi.Helpers, // SharedActivityContext
    Androidapi.JNI.GraphicsContentViewText, // TJContext
    Androidapi.JNIBridge, // ILocalObject
    Androidapi.JNI.App, // TJActivity
    Androidapi.JNI.Os, // JVibrator
    Androidapi.JNI.JavaTypes, // JObject
    FMX.Helpers.Android; // SharedActivity

    ОтветитьУдалить
  4. Кстати, можно без "FMX.Helpers.Android;".

    ОтветитьУдалить