1 {
2   Lazarus Component Library
3 
4   This is a unit for holding all hardware APIs which do not involve the screen
5   nor input events. These are things like accelerometer, SMS, GPS, etc, which
6   are typical of mobile devices such as smartphones
7 
8   Author: Felipe Monteiro de Carvalho 2011
9 
10   License: The same modified LGPL as the rest of the LCL
11 }
12 unit LazDeviceApis;
13 
14 {$mode delphi}
15 
16 interface
17 
18 uses
19   SysUtils, Classes,
20   LCLIntf, LCLType;
21 
22 type
23 
24   // TLazAccelerometer
25 
26   { The accelerometer geometry is the following:
27 
28     Consider the device with the screen facing the user
29     Typically it will have some buttons in the bottom part (represented by []):
30 
31        ^ Y axis
32        |
33     ________
34     |      |
35     |      | --> X axis
36     |      |
37     |[][][]|
38 
39     The Z axis goes from the device screen in the direction of the user facing it.
40   }
41 
42   TLazAccelerometer = class
43   private
44     FOnSensorChanged: TNotifyEvent;
45     FReadingStarted: Boolean;
46   public
47     // These fields store the last data read
48     xaxis, yaxis, zaxis: Double; // in m/s^2
49     procedure StartReadingAccelerometerData();
50     procedure StopReadingAccelerometerData();
51     property OnSensorChanged: TNotifyEvent read FOnSensorChanged write FOnSensorChanged;
52   end;
53 
54   // TLazMessaging
55 
56   TLazDeviceMessageKind = (dmkSMS, dmkMMS, dmkEMail);
57 
58   TLazDeviceMessage = class
59   public
60     // The coments indicate in which message kind each
61     // field is available.             SMS   MMS  EMail
62     bccAddress: TStringList;         // N     N    Y
63     Body: string;                    // Y     Y	   Y
64     ccAddress: TstringList;          // N     N    Y
65     destinationAddress: TStringList; // Y     Y    Y
66     isRead: Boolean;                 // Y     Y    Y
67     messageId: string;               // Y     Y    Y
68     //messagePriority	Y	Y	Y
69     messageType: TLazDeviceMessageKind;//Y    Y    Y
70     ReplyToAddress: string;          // Y     Y    Y
71     sourceAddress: string;           // Y     Y    Y
72     Subject: string;                 // N     Y    Y
73     Time: TDateTime;                 // Y     Y    Y
74     validityPeriod:TTime;            // Y     N    N
75     constructor Create; virtual;
76     destructor Destroy; override;
77   end;
78 
79   TLazMessagingStatus = (
80     // Message sending status
81     mssSentSuccessfully, mssSendingGeneralError, mssRadioOff, mssNoService,
82     // Message receiving status (by the destination)
83     mssReceivedSuccessfully, mssReceivingGeneralError
84     );
85 
86   TOnMessagingStatus = procedure (AMessage: TLazDeviceMessage;
87     AStatus: TLazMessagingStatus) of object;
88 
89   TLazMessaging = class
90   private
91     FOnMessagingStatus: TOnMessagingStatus;
92     FMessages: TFPList; // of TLazDeviceMessage
93   public
94     constructor Create; virtual;
95     destructor Destroy; override;
96     // Attempt to send the specified message.
97     procedure SendMessage(AMsg: TLazDeviceMessage);
CreateMessagenull98     function CreateMessage: TLazDeviceMessage;
99     procedure FreeMessage(AMessage: TLazDeviceMessage);
100     // Called asynchronously when there is a message status
101     property OnMessagingStatus: TOnMessagingStatus
102       read FOnMessagingStatus write FOnMessagingStatus;
103   end;
104 
105   // TLazPositionInfo
106 
107   TLazPositionMethod = (pmGPS, pmNetwork);
108 
109   TLazPositionInfo = class
110   private
111     FOnPositionRetrieved: TNotifyEvent;
112   public
113     IsPositionDataAvailable: Boolean; // Indicates if position info was read in the life of this program
114     // These fields hold the last position information read
115     accuracy: Double; // The horizontal accuracy of the position in meters
116     altitude: Double; // Altitude in meters in relation to the sea level using the World Geodetic System 1984 (WGS84) datum.
117     altitudeAccuracy: Double; // The vertical accuracy of the position in meters, or zero if not available.
118     latitude: Double; // Latitude in degrees using the World Geodetic System 1984 (WGS84) datum.
119     longitude: Double; // Longitude in degrees using the World Geodetic System 1984 (WGS84) datum.
120     speed: Double; // In meters / second
121     timeStamp: TDateTime; // The time when the latest location was established.
122     procedure RequestPositionInfo(AMethod: TLazPositionMethod);
123     // Called asynchronously when the position is read
124     property OnPositionRetrieved: TNotifyEvent read FOnPositionRetrieved write FOnPositionRetrieved;
125   end;
126 
127   // TLazDevice
128 
129   TScreenRotation = (srRotation_0, srRotation_90, srRotation_180, srRotation_270);
130 
131   TLazDevice = class
132   private
GetDeviceManufacturernull133     function GetDeviceManufacturer: string;
GetDeviceModelnull134     function GetDeviceModel: string;
135   public
136     procedure Vibrate(ADurationMS: Cardinal);
GetScreenRotationnull137     function GetScreenRotation(AScreenIndex: Integer): TScreenRotation;
138     property Manufacturer: string read GetDeviceManufacturer;
139     property Model: string read GetDeviceModel;
140   end;
141 
142 var
143   Accelerometer: TLazAccelerometer;
144   Messaging: TLazMessaging;
145   PositionInfo: TLazPositionInfo;
146   Device: TLazDevice;
147 
148 implementation
149 
150 uses wslazdeviceapis, wslclclasses;
151 
152 { TLazDevice }
153 
GetDeviceManufacturernull154 function TLazDevice.GetDeviceManufacturer: string;
155 var
156   WidgetsetClass: TWSLazDeviceAPIsClass;
157 begin
158   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
159   Result := WidgetsetClass.GetDeviceManufacturer();
160 end;
161 
TLazDevice.GetDeviceModelnull162 function TLazDevice.GetDeviceModel: string;
163 var
164   WidgetsetClass: TWSLazDeviceAPIsClass;
165 begin
166   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
167   Result := WidgetsetClass.GetDeviceModel();
168 end;
169 
170 procedure TLazDevice.Vibrate(ADurationMS: Cardinal);
171 var
172   WidgetsetClass: TWSLazDeviceAPIsClass;
173 begin
174   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
175   WidgetsetClass.Vibrate(ADurationMS);
176 end;
177 
TLazDevice.GetScreenRotationnull178 function TLazDevice.GetScreenRotation(AScreenIndex: Integer): TScreenRotation;
179 var
180   WidgetsetClass: TWSLazDeviceAPIsClass;
181 begin
182   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
183   Result := WidgetsetClass.GetScreenRotation(AScreenIndex);
184 end;
185 
186 { TLazAccelerometer }
187 
188 procedure TLazAccelerometer.StartReadingAccelerometerData;
189 var
190   WidgetsetClass: TWSLazDeviceAPIsClass;
191 begin
192   if FReadingStarted then Exit;
193   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
194   WidgetsetClass.StartReadingAccelerometerData();
195   FReadingStarted := True;
196 end;
197 
198 procedure TLazAccelerometer.StopReadingAccelerometerData;
199 var
200   WidgetsetClass: TWSLazDeviceAPIsClass;
201 begin
202   if not FReadingStarted then Exit;
203   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
204   WidgetsetClass.StopReadingAccelerometerData();
205   FReadingStarted := False;
206 end;
207 
208 { TLazPositionInfo }
209 
210 procedure TLazPositionInfo.RequestPositionInfo(AMethod: TLazPositionMethod);
211 var
212   WidgetsetClass: TWSLazDeviceAPIsClass;
213 begin
214   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
215   WidgetsetClass.RequestPositionInfo(AMethod);
216 end;
217 
218 { TLazDeviceMessage }
219 
220 constructor TLazDeviceMessage.Create;
221 begin
222   inherited Create;
223   bccAddress := TStringList.Create;
224   ccAddress := TStringList.Create;
225   destinationAddress := TStringList.Create;
226 end;
227 
228 destructor TLazDeviceMessage.Destroy;
229 begin
230   bccAddress.Free;
231   ccAddress.Free;
232   destinationAddress.Free;
233   inherited Destroy;
234 end;
235 
236 { TLazMessaging }
237 
238 constructor TLazMessaging.Create;
239 begin
240   FMessages := TFPList.Create;
241 end;
242 
243 destructor TLazMessaging.Destroy;
244 var
245   i: Integer;
246 begin
247   // Free all messages
248   for i := 0 to FMessages.Count-1 do
249     TLazDeviceMessage(FMessages.Items[i]).Free;
250   FMessages.Free;
251   inherited Destroy;
252 end;
253 
254 procedure TLazMessaging.SendMessage(AMsg: TLazDeviceMessage);
255 var
256   WidgetsetClass: TWSLazDeviceAPIsClass;
257 begin
258   WidgetsetClass := TWSLazDeviceAPIsClass(GetWSLazDeviceAPIs());
259   WidgetsetClass.SendMessage(AMsg);
260 end;
261 
CreateMessagenull262 function TLazMessaging.CreateMessage: TLazDeviceMessage;
263 begin
264   Result := TLazDeviceMessage.Create;
265   FMessages.Add(Result);
266 end;
267 
268 procedure TLazMessaging.FreeMessage(AMessage: TLazDeviceMessage);
269 begin
270   FMessages.Remove(AMessage);
271   AMessage.Free;
272 end;
273 
274 initialization
275   RegisterLazDeviceAPIs();
276   Accelerometer := TLazAccelerometer.Create;
277   Messaging := TLazMessaging.Create;
278   PositionInfo := TLazPositionInfo.Create;
279   Device := TLazDevice.Create;
280 finalization
281   Accelerometer.Free;
282   Messaging.Free;
283   PositionInfo.Free;
284   Device.Free;
285 end.
286 
287