From b360c1f433cc10d0162b64b926661fd5fd84fb8a Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Wed, 28 Dec 2011 23:06:17 +0000 Subject: [PATCH] Implements basic accelerometer support in Android and adds it to the Example git-svn-id: trunk@34479 - --- .../src/com/pascal/lcltest/LCLActivity.java | 35 ++++++++++++++++- examples/androidlcl/androidlcltest.lpi | 6 +-- examples/androidlcl/androidlcltest.lpr | 3 +- examples/androidlcl/mainform.lfm | 4 +- examples/androidlcl/secondform.lfm | 31 +++++++++++---- examples/androidlcl/secondform.pas | 19 +++++++++- lcl/interfaces/customdrawn/customdrawnint.pas | 5 ++- .../customdrawnlclintf_android.inc | 16 ++++++++ .../customdrawn/customdrawnlclintf_cocoa.inc | 15 ++++++++ .../customdrawn/customdrawnlclintf_win.inc | 15 ++++++++ .../customdrawn/customdrawnlclintf_x11.inc | 15 ++++++++ .../customdrawn/customdrawnlclintfh.inc | 4 ++ .../customdrawn/customdrawnobject_android.inc | 38 ++++++++++++++++++- lcl/lazdeviceapis.pas | 9 +++++ 14 files changed, 197 insertions(+), 18 deletions(-) diff --git a/examples/androidlcl/android/src/com/pascal/lcltest/LCLActivity.java b/examples/androidlcl/android/src/com/pascal/lcltest/LCLActivity.java index ada6c0394d..22fd67fb97 100755 --- a/examples/androidlcl/android/src/com/pascal/lcltest/LCLActivity.java +++ b/examples/androidlcl/android/src/com/pascal/lcltest/LCLActivity.java @@ -9,9 +9,15 @@ import android.graphics.*; import android.view.*; import android.view.inputmethod.InputMethodManager; import android.content.res.Configuration; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; -public class LCLActivity extends Activity +public class LCLActivity extends Activity implements SensorEventListener { + private SensorManager localSensorManager; + // ------------------------------------------- // Our drawing surface // ------------------------------------------- @@ -147,6 +153,7 @@ public class LCLActivity extends Activity public native int LCLOnKey(int kind, int keyCode, KeyEvent event, char AChar); public native int LCLOnTimer(Runnable timerid); public native int LCLOnConfigurationChanged(int ANewDPI, int ANewWidth); + public native int LCLOnSensorChanged(int ASensorKind, float[] AValues); // ------------------------------------------- // Functions exported to the Pascal side @@ -309,6 +316,32 @@ public class LCLActivity extends Activity localInputManager.showSoftInput(lclsurface, 0); }; + @Override + public void onSensorChanged(SensorEvent event) + { + int eventKind = event.sensor.getType(); + int eventResult = LCLOnSensorChanged(eventKind, event.values); + if (((eventResult | 1) != 0) && (lclsurface != null)) lclsurface.postInvalidate(); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) + { + } + + public void LCLDoStartReadingAccelerometer() + { + localSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); + localSensorManager.registerListener(this, + localSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), + SensorManager.SENSOR_DELAY_NORMAL); + }; + + public void LCLDoStopReadingAccelerometer() + { + localSensorManager.unregisterListener(this); + }; + // ------------------------------------------- // Fields exported to the Pascal side for easier data communication // ------------------------------------------- diff --git a/examples/androidlcl/androidlcltest.lpi b/examples/androidlcl/androidlcltest.lpi index d44ddf30d2..1b61d915fa 100644 --- a/examples/androidlcl/androidlcltest.lpi +++ b/examples/androidlcl/androidlcltest.lpi @@ -35,7 +35,7 @@ - + @@ -72,7 +72,7 @@ - + @@ -150,7 +150,7 @@ - + diff --git a/examples/androidlcl/androidlcltest.lpr b/examples/androidlcl/androidlcltest.lpr index 5c8afdb9ea..ce8e93ddb9 100644 --- a/examples/androidlcl/androidlcltest.lpr +++ b/examples/androidlcl/androidlcltest.lpr @@ -15,7 +15,8 @@ exports Java_com_pascal_lclproject_LCLActivity_LCLOnMessageBoxFinished name 'Java_com_pascal_lcltest_LCLActivity_LCLOnMessageBoxFinished', Java_com_pascal_lclproject_LCLActivity_LCLOnKey name 'Java_com_pascal_lcltest_LCLActivity_LCLOnKey', Java_com_pascal_lclproject_LCLActivity_LCLOnTimer name 'Java_com_pascal_lcltest_LCLActivity_LCLOnTimer', - Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged name 'Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged', + Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged name 'Java_com_pascal_lcltest_LCLActivity_LCLOnConfigurationChanged', + Java_com_pascal_lclproject_LCLActivity_LCLOnSensorChanged name 'Java_com_pascal_lcltest_LCLActivity_LCLOnSensorChanged', JNI_OnLoad name 'JNI_OnLoad', JNI_OnUnload name 'JNI_OnUnload'; diff --git a/examples/androidlcl/mainform.lfm b/examples/androidlcl/mainform.lfm index 21f3786627..c4f0113d04 100644 --- a/examples/androidlcl/mainform.lfm +++ b/examples/androidlcl/mainform.lfm @@ -1,7 +1,7 @@ object Form1: TForm1 - Left = 932 + Left = 161 Height = 251 - Top = 220 + Top = 137 Width = 220 Caption = 'Form1' ClientHeight = 251 diff --git a/examples/androidlcl/secondform.lfm b/examples/androidlcl/secondform.lfm index f2fd3247f2..8098ffce86 100644 --- a/examples/androidlcl/secondform.lfm +++ b/examples/androidlcl/secondform.lfm @@ -1,7 +1,7 @@ object Form2: TForm2 - Left = 1158 + Left = 154 Height = 259 - Top = 220 + Top = 137 Width = 320 Caption = 'Form2' ClientHeight = 259 @@ -10,7 +10,7 @@ object Form2: TForm2 object Button1: TButton Left = 8 Height = 25 - Top = 16 + Top = 0 Width = 304 Caption = 'Hide' OnClick = Button1Click @@ -19,7 +19,7 @@ object Form2: TForm2 object Edit1: TEdit Left = 12 Height = 25 - Top = 50 + Top = 32 Width = 80 OnExit = Edit1Exit OnKeyDown = Edit1KeyDown @@ -29,10 +29,10 @@ object Form2: TForm2 Text = 'Edit1' end object Image1: TImage - Left = 32 + Left = 96 Height = 138 - Top = 96 - Width = 274 + Top = 32 + Width = 210 Picture.Data = { 07545069786D617044DA00002F2A2058504D202A2F0A73746174696320636861 72202A206C617A617275735F61626F75745F6C6F676F5F78706D5B5D203D207B @@ -1783,4 +1783,21 @@ object Form2: TForm2 2E202E202E202E202E202E20227D3B0A } end + object Button2: TButton + Left = 8 + Height = 25 + Top = 194 + Width = 304 + Caption = 'Read Accelerometer' + OnClick = Button2Click + TabOrder = 2 + end + object labelSensorData: TLabel + Left = 8 + Height = 18 + Top = 168 + Width = 81 + Caption = 'Sensor Data' + ParentColor = False + end end diff --git a/examples/androidlcl/secondform.pas b/examples/androidlcl/secondform.pas index add3431aeb..a20f5920f1 100644 --- a/examples/androidlcl/secondform.pas +++ b/examples/androidlcl/secondform.pas @@ -6,7 +6,7 @@ interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, - ComCtrls, ExtCtrls, LCLType, LCLProc; + ComCtrls, ExtCtrls, LCLType, LCLProc, lazdeviceapis; type @@ -14,9 +14,12 @@ type TForm2 = class(TForm) Button1: TButton; + Button2: TButton; Edit1: TEdit; Image1: TImage; + labelSensorData: TLabel; procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); procedure Edit1Exit(Sender: TObject); procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); @@ -25,6 +28,7 @@ type { private declarations } public { public declarations } + procedure HandleAccelerometerChanged(Sender: TObject); end; var @@ -41,6 +45,12 @@ begin Hide; end; +procedure TForm2.Button2Click(Sender: TObject); +begin + Accelerometer.OnSensorChanged := @HandleAccelerometerChanged; + Accelerometer.StartReadingAccelerometerData(); +end; + procedure TForm2.Edit1Exit(Sender: TObject); begin DebugLn('[Edit1Exit]'); @@ -62,5 +72,12 @@ begin DebugLn('[Edit1UTF8KeyPress] Char=' + UTF8Key); end; +procedure TForm2.HandleAccelerometerChanged(Sender: TObject); +begin + labelSensorData.Caption := Format('X=%f Y=%f Z=%f', [Accelerometer.xaxis, + Accelerometer.yaxis, Accelerometer.zaxis]); + DebugLn(labelSensorData.Caption); +end; + end. diff --git a/lcl/interfaces/customdrawn/customdrawnint.pas b/lcl/interfaces/customdrawn/customdrawnint.pas index 71067a8ad1..2a56ef6d3e 100644 --- a/lcl/interfaces/customdrawn/customdrawnint.pas +++ b/lcl/interfaces/customdrawn/customdrawnint.pas @@ -41,7 +41,7 @@ uses customdrawnproc, // LCL customdrawn_common, customdrawncontrols, customdrawndrawers, - lazcanvas, lazregions, + lazcanvas, lazregions, lazdeviceapis, InterfaceBase, Controls, Forms, lclproc, IntfGraphics, GraphType, LCLType, LMessages, Graphics, LCLStrConsts; @@ -252,6 +252,8 @@ function Java_com_pascal_lclproject_LCLActivity_LCLOnTimer( env:PJNIEnv; this:jobject; ATimer: jobject): jint; cdecl; function Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged( env:PJNIEnv; this:jobject; ANewDPI, ANewWidth: jint): jint; cdecl; +function Java_com_pascal_lclproject_LCLActivity_LCLOnSensorChanged( + env:PJNIEnv; this:jobject; ASensorKind: jint; AValues: JFloatArray): jint; cdecl; function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl; procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer); cdecl; @@ -305,6 +307,7 @@ var javaMethod_LCLDoDestroyTimer: jmethodid = nil; javaMethod_LCLDoHideVirtualKeyboard: jmethodid = nil; javaMethod_LCLDoShowVirtualKeyboard: jmethodid = nil; + javaMethod_LCLDoStartReadingAccelerometer: jmethodid = nil; // This is utilized to store the information such as invalidate requests in events eventResult: jint; diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc index ccecc9c592..e65fe38a37 100644 --- a/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc +++ b/lcl/interfaces/customdrawn/customdrawnlclintf_android.inc @@ -163,6 +163,22 @@ begin javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoHideVirtualKeyboard); end; +procedure TCDWidgetSet.LazDeviceAPIs_RequestPositionInfo(AMethod: TLazPositionMethod); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_SendMessage(AMsg: TLazDeviceMessage); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_StartReadingAccelerometerData(); +begin + // Call the method + javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoStartReadingAccelerometer); +end; + function TCDWidgetSet.PromptUser(const DialogCaption : string; const DialogMessage : string; DialogType : LongInt; diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc index 97e5a3566b..0e256a4c8d 100644 --- a/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc +++ b/lcl/interfaces/customdrawn/customdrawnlclintf_cocoa.inc @@ -113,6 +113,21 @@ begin end; +procedure TCDWidgetSet.LazDeviceAPIs_RequestPositionInfo(AMethod: TLazPositionMethod); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_SendMessage(AMsg: TLazDeviceMessage); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_StartReadingAccelerometerData(); +begin + +end; + {------------------------------------------------------------------------------ Function: PromptUser Params: diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc index 51cf56761c..ddab0a56ba 100644 --- a/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc +++ b/lcl/interfaces/customdrawn/customdrawnlclintf_win.inc @@ -114,6 +114,21 @@ begin end; +procedure TCDWidgetSet.LazDeviceAPIs_RequestPositionInfo(AMethod: TLazPositionMethod); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_SendMessage(AMsg: TLazDeviceMessage); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_StartReadingAccelerometerData(); +begin + +end; + {------------------------------------------------------------------------------ Function: PromptUser Params: diff --git a/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc b/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc index c0f8863f57..2a5ab2d9cc 100644 --- a/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc +++ b/lcl/interfaces/customdrawn/customdrawnlclintf_x11.inc @@ -114,6 +114,21 @@ begin end; +procedure TCDWidgetSet.LazDeviceAPIs_RequestPositionInfo(AMethod: TLazPositionMethod); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_SendMessage(AMsg: TLazDeviceMessage); +begin + +end; + +procedure TCDWidgetSet.LazDeviceAPIs_StartReadingAccelerometerData(); +begin + +end; + {------------------------------------------------------------------------------ Function: PromptUser Params: diff --git a/lcl/interfaces/customdrawn/customdrawnlclintfh.inc b/lcl/interfaces/customdrawn/customdrawnlclintfh.inc index 5fefdb1fb1..c2823d105a 100644 --- a/lcl/interfaces/customdrawn/customdrawnlclintfh.inc +++ b/lcl/interfaces/customdrawn/customdrawnlclintfh.inc @@ -56,6 +56,10 @@ procedure HideVirtualKeyboard(); (*function IntfSendsUTF8KeyPress: boolean; override; function IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean; override;*) +procedure LazDeviceAPIs_RequestPositionInfo(AMethod: TLazPositionMethod); override; +procedure LazDeviceAPIs_SendMessage(AMsg: TLazDeviceMessage); override; +procedure LazDeviceAPIs_StartReadingAccelerometerData(); override; + function PromptUser(const DialogCaption : string; const DialogMessage : string; DialogType : LongInt; diff --git a/lcl/interfaces/customdrawn/customdrawnobject_android.inc b/lcl/interfaces/customdrawn/customdrawnobject_android.inc index 08cc8bc7b0..99b9a72b5e 100644 --- a/lcl/interfaces/customdrawn/customdrawnobject_android.inc +++ b/lcl/interfaces/customdrawn/customdrawnobject_android.inc @@ -250,7 +250,37 @@ begin CDWidgetset.DefaultFontAndroidSize := Round(16 * (ANewDPI / 125)); end; -const NativeMethods: array[0..6] of JNINativeMethod= +function Java_com_pascal_lclproject_LCLActivity_LCLOnSensorChanged( + env:PJNIEnv; this:jobject; ASensorKind: jint; AValues: JFloatArray): jint; cdecl; +var + arraydata: PSingle; + arraylen: jsize; + lIsCopy: jboolean; +begin + Result := 0; + + if (javaEnvRef = nil) then Exit; + + // Get the elements and length + lIsCopy := 0; + arraylen := javaEnvRef^^.GetArrayLength(javaEnvRef, AValues); + arraydata := javaEnvRef^^.GetFloatArrayElements(javaEnvRef, AValues, lIsCopy); + + // Send the data to the LCL + if ASensorKind = 1 then + begin + Accelerometer.xaxis := arraydata[0]; + Accelerometer.yaxis := arraydata[1]; + Accelerometer.zaxis := arraydata[2]; + if Assigned(Accelerometer.OnSensorChanged) then + Accelerometer.OnSensorChanged(nil); + end; + + // Don't forget to release it + javaEnvRef^^.ReleaseFloatArrayElements(javaEnvRef, AValues, arraydata, 0); +end; + +const NativeMethods: array[0..7] of JNINativeMethod= ((name:'LCLDrawToBitmap'; signature:'(IILandroid/graphics/Bitmap;)I'; fnPtr:@Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmap;), @@ -271,7 +301,10 @@ const NativeMethods: array[0..6] of JNINativeMethod= fnPtr:@Java_com_pascal_lclproject_LCLActivity_LCLOnTimer;), (name:'LCLOnConfigurationChanged'; signature:'(II)I'; - fnPtr:@Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged;) + fnPtr:@Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged;), + (name:'LCLOnSensorChanged'; + signature:'(I[F)I'; + fnPtr:@Java_com_pascal_lclproject_LCLActivity_LCLOnSensorChanged;) ); function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl; @@ -358,6 +391,7 @@ begin javaMethod_LCLDoDestroyTimer := javaEnvRef^^.GetMethodID(javaEnvRef, javaActivityClass, 'LCLDoDestroyTimer', '()V'); javaMethod_LCLDoHideVirtualKeyboard := javaEnvRef^^.GetMethodID(javaEnvRef, javaActivityClass, 'LCLDoHideVirtualKeyboard', '()V'); javaMethod_LCLDoShowVirtualKeyboard := javaEnvRef^^.GetMethodID(javaEnvRef, javaActivityClass, 'LCLDoShowVirtualKeyboard', '()V'); + javaMethod_LCLDoStartReadingAccelerometer := javaEnvRef^^.GetMethodID(javaEnvRef, javaActivityClass, 'LCLDoStartReadingAccelerometer', '()V'); __android_log_write(ANDROID_LOG_INFO, 'lclapp', 'JNI_OnLoad finished'); result:=JNI_VERSION_1_4;// 1_6 is another option diff --git a/lcl/lazdeviceapis.pas b/lcl/lazdeviceapis.pas index b977982e85..a1b10c0540 100644 --- a/lcl/lazdeviceapis.pas +++ b/lcl/lazdeviceapis.pas @@ -38,10 +38,14 @@ type } TLazAccelerometer = class + private + FOnSensorChanged: TNotifyEvent; public // These fields store the last data read, to get fresh data use UpdateAccelerometerData; xaxis, yaxis, zaxis: Double; // in m/s^2 procedure StartReadingAccelerometerData(); + procedure StopReadingAccelerometerData(); + property OnSensorChanged: TNotifyEvent read FOnSensorChanged write FOnSensorChanged; end; // TLazMessaging @@ -100,6 +104,11 @@ begin LCLIntf.LazDeviceAPIs_StartReadingAccelerometerData(); end; +procedure TLazAccelerometer.StopReadingAccelerometerData; +begin + +end; + { TLazPositionInfo } procedure TLazPositionInfo.RequestPositionInfo(AMethod: TLazPositionMethod);