Delphi AndroidAPi运动检测 [英] Delphi AndroidAPi motion detection

查看:104
本文介绍了Delphi AndroidAPi运动检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想直接使用AndroidApi对运动检测器(加速度计)进行编码。我目前已经测试了使用TMotionSensor和TSensorManager的实现(每个Embarcadero示例),但是两者似乎都存在功耗问题(即电话变热)。

I want to code a motion detector (Accelerometer) using the AndroidApi directly. I currently have tested implementations (per Embarcadero examples) using TMotionSensor as well as TSensorManager, but both seem to have power drain issues (ie. the phone gets hot).

我的TSensorManager实现如下:

My TSensorManager implementation looks like this:

procedure TfrmTabbed.InitSensorMan;
var
  FSensors: TSensorArray;
  Sensor: TCustomSensor;
begin
  TSensorManager.Current.Activate;
  FSensors := TSensorManager.Current.GetSensorsByCategory(TSensorCategory.Motion);
  FSensor := nil;
  for Sensor in FSensors do
  begin
    if TCustomMotionSensor(Sensor).SensorType = TMotionSensorType.Accelerometer3D then
    begin
      FSensor := TCustomMotionSensor(Sensor);
      Break;
    end;
  end;
  MotionTimer.Interval := 250; 
  MotionTimer.Active := True;
end;

现在,使用如何检测android设备的运动?作为参考,我开始编写如下代码:

So now, using How to detect movement of an android device? as a reference, I start writing code like this:

uses
  Androidapi.Sensor,
  Androidapi.JNI.JavaTypes;

{$R *.fmx}

procedure TForm2.FormCreate(Sender: TObject);
var
  Obj: JObject;
  SensorManager: JSensorManager;
begin

  Obj := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.SENSOR_SERVICE);
  if Obj <> nil then
  begin
     SensorManager := TJsensorManager.Wrap(Obj);

  end;

我想任何一个熟悉这一领域的人都会意识到,没有 JSensorManager C:\Program Files(x86)\Embarcadero\Studio\18.0\source 中的任何位置声明。有 Androidapi.JNI.Telephony.pas ,但没有 Androidapi.JNI.Sensor.pas

I guess anyone who is familiar with this area, will realize that there's no JSensorManager declared anywhere in C:\Program Files (x86)\Embarcadero\Studio\18.0\source. There's a Androidapi.JNI.Telephony.pas, but no Androidapi.JNI.Sensor(s).pas!

我的问题是,是否可以通过这种方式从Delphi访问SENSOR_SERVICE,如果可以,该如何实现?

My question is, is it possible to access the SENSOR_SERVICE from Delphi in this way, and if so, how can I implement it?

附录

我尝试了Java2op。似乎要求JDK的特定版本(1.7.25?)不会产生期望的类或接口错误。因此,我尝试使用 Java2Pas 。免费版本仅解析Android.jar,但这似乎足以满足我的需求。

I tried Java2op. It seems to require a very specific version (1.7.25?) of the JDK to not produce a "class or interface expected" error. So I tried Java2Pas instead. The free version only parses Android.jar, but that seems to be sufficient for my purposes.

推荐答案

这是我的(即将完成) )回答尝试在Delphi Android 10.x中执行相同(或相似)操作(尤其是使用侦听器)的人。

Here is my (almost completed) answer for those of you who are trying to do the same (or similar) things, especially with Listeners, in Delphi Android 10.x.

注意:


  1. SensorListener在Android中已被弃用。

  1. SensorListener has been deprecated in Android. Use SensorEventListener instead.

Java2pas在 android.hardware.SensorEventListener.pas 中错误地将JSensorEventListener编码。它是 JSensorEventListener = interface(JObject)。必须将其更正为 JSensorEventListener = interface(IJavaInstance)

Java2pas coded the JSensorEventListener in android.hardware.SensorEventListener.pas incorrectly. It was JSensorEventListener = interface(JObject). It must be corrected to JSensorEventListener = interface(IJavaInstance).

android.hardware.SensorEvent 中, JSensorEvent 声明缺少$ c>属性和 _Getvalues 函数。只需从 JSensorEventClass 复制它们。

In android.hardware.SensorEvent, the values property and the _Getvalues function, was missing from the JSensorEvent declaration. Just copy them from the JSensorEventClass.

这里是代码:

unit Unit2;

interface

uses    
 System.SysUtils, System.Types, System.UITypes, System.Classes,
 System.Variants,
 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
 FMX.Controls.Presentation, FMX.StdCtrls
 , Androidapi.JNIBridge
 , Androidapi.JNI.Embarcadero
 , Androidapi.JNI.GraphicsContentViewText
 , androidapi.JNI.JavaTypes
 , AndroidApi.JNI.Location
 , Androidapi.JNI.Os
 // java2pas gen'd units (modified as noted above)
 , android.hardware.SensorManager
 , android.hardware.Sensor
 , android.hardware.SensorEventListener
 , android.hardware.SensorEvent
 , FMX.ScrollBox, FMX.Memo
 ;

type

  TSensorEventListener = class;

  TForm2 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FSensorManager: JSensorManager;
    FDefaultSensor: JSensor;
    SensorEventListener: TSensorEventListener;
    FStarted: Boolean;
    procedure StartApi;
    procedure StopApi;
  public
    { Public declarations }
  end;

  TSensorEventListener = class(TJavaLocal, JSensorEventListener)
  private
    [weak]
    FParent: TForm2;
  public
    constructor Create(AParent: TForm2);
    procedure onAccuracyChanged(JSensorparam0 : JSensor; Integerparam1 : Integer) ; cdecl;
    procedure onSensorChanged(JSensorEventparam0 : JSensorEvent) ; cdecl;
  end;

var
  Form2: TForm2;

implementation

uses
  Androidapi.Helpers
  , Androidapi.JNI.Net
  , FMX.Helpers.Android
  ;

procedure TForm2.Button1Click(Sender: TObject);
begin
  if Fstarted then
    StopApi
  else
    StartApi;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  FStarted := False;
end;

procedure TForm2.StartApi;
var
  SensorManagerService: JObject;
begin
  if not Assigned(FSensorManager) then
  begin
    SensorManagerService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.SENSOR_SERVICE);
    FSensorManager := TJSensorManager.Wrap((SensorManagerService as ILocalObject).GetObjectID);
    if not Assigned(SensorEventListener) then
      SensorEventListener := TSensorEventListener.Create(Self);
    FDefaultSensor := FSensorManager.getDefaultSensor(TJSensorManager.JavaClass.SENSOR_ACCELEROMETER);
  end;
  FSensorManager.registerListener(SensorEventListener, FDefaultSensor, TJSensorManager.JavaClass.SENSOR_DELAY_NORMAL);
  Memo1.Lines.Add(DateTimeToStr(Now) + ' started');
  FStarted := True;
end;

procedure TForm2.StopApi;
begin
  if Assigned(SensorEventListener) then
    FSensorManager.unregisterListener(SensorEventListener);
  Memo1.Lines.Add(DateTimeToStr(Now) + ' stopped');
  FStarted := False;
end;

{ TSensorEventListener }

constructor TSensorEventListener.Create(AParent: TForm2);
begin
  inherited Create;
  FParent := AParent;
end;

procedure TSensorEventListener.onAccuracyChanged(JSensorparam0: JSensor;
  Integerparam1: Integer);
begin
   // do stuff
end;

procedure TSensorEventListener.onSensorChanged(
  JSensorEventparam0: JSensorEvent);
begin
   // do stuff, especially with the JSensorEventparam0.values
end;

这篇关于Delphi AndroidAPi运动检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆