【发布时间】:2016-02-17 04:19:14
【问题描述】:
使用 Delphi 10 Seattle Update 1 创建 Android 应用程序。
基本目标是让应用每隔几 (4) 小时弹出一次通知,提醒用户起床和移动。
我已经创建了基本 UI 并创建了后台服务。在服务中,我可以使用 TNotificationCenter 来发布通知,但我需要定期发布通知。
根据在以下网站上找到的建议...
- http://blog.blong.com/2015/02/delphi-and-android-services-part-3.html
- http://blog.marcocantu.com/blog/2014_may_background_delphi_android_threads.html
- embarcadero delphi XE10 android service with a timer
- 还有产品附带的 AndroidNotificationServiceDemo...
我意识到我不能在 Android 服务中使用 TTimer。我还尝试从 AndroidServiceStartCommand 和 AndroidServiceCreate 事件创建 TTask、TThread.CreateAnonymousThread 和老式 TThread 后代。
在 sleep 命令完成后,它们都会抛出相同的错误。 《Project MoveProof.apk 引发异常类Segment fault(11)》
这是我现在使用的代码......
unit UnitServiceMain;
interface
uses
System.SysUtils
, System.Classes
, System.Android.Service
, System.Notification
, AndroidApi.JNI.GraphicsContentViewText
, Androidapi.JNI.Os
;
type
TServiceThread = class;
TNotes = Array of String;
TAndroidServiceDM = class(TAndroidService)
NotificationCenterNotes: TNotificationCenter;
function AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
procedure AndroidServiceCreate(Sender: TObject);
procedure AndroidServiceDestroy(Sender: TObject);
private
FNotes: TArray<string>;
FThread: TServiceThread;
public
var Running: Boolean;
Procedure LoadArray;
Property Notes:TArray<string> read FNotes;
end;
TServiceThread = class(TThread)
public
Procedure Execute; override;
Procedure DoNotification;
end;
var
AndroidServiceDM: TAndroidServiceDM;
implementation
{%CLASSGROUP 'FMX.Controls.TControl'}
{$R *.dfm}
Uses
System.Threading
, Androidapi.JNI.App
;
{ TServiceThread }
procedure TServiceThread.DoNotification;
Var
NoteId: Integer;
MyNotification: TNotification;
begin
while (AndroidServiceDM <> nil) and AndroidServiceDM.Running do
Begin
try
if (AndroidServiceDM <> nil) and AndroidServiceDM.Running then
Begin
AndroidServiceDM.NotificationCenterNotes.CancelAll;
NoteID := Random(High(AndroidServiceDM.Notes));
MyNotification := AndroidServiceDM.NotificationCenterNotes.CreateNotification;
try
MyNotification.Name := 'LoveNoteMessage'+InttoStr(NoteID);
MyNotification.EnableSound := False;
MyNotification.Number := NoteID;
MyNotification.Title := 'Michael Said...';
MyNotification.AlertBody := AndroidServiceDM.Notes[NoteID];
AndroidServiceDM.NotificationCenterNotes.PresentNotification(MyNotification);
finally
MyNotification.DisposeOf;
end;
End;
except
on Exception do
// Need to log this...
end;
end;
end;
procedure TServiceThread.Execute;
begin
inherited;
Sleep( 20000 );
Synchronize(DoNotification);
end;
procedure TAndroidServiceDM.LoadArray;
begin
if Length(FNotes) = 0 then
Begin
FNotes := TArray<string>.Create
(
'Get up and move.',
'Time to keep moving.',
'Lets take a walk.',
'Move.'
);
End;
end;
procedure TAndroidServiceDM.AndroidServiceCreate(Sender: TObject);
begin
Randomize;
LoadArray;
end;
procedure TAndroidServiceDM.AndroidServiceDestroy(Sender: TObject);
begin
FThread.Terminate;
FThread := Nil;
end;
function TAndroidServiceDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
JavaService.stopSelf;
Result := TJService.JavaClass.START_STICKY;
if not Running then
begin
Running := True;
FThread := TServiceThread.Create(False);
end;
end;
end.
我对线程没有那么丰富的经验,所以也许我在同步方面做错了。任何帮助将不胜感激。
【问题讨论】:
-
您不需要为此提供服务。只需使用AlarrmManager。就个人而言,为什么您会费心在 Delphi 中创建新应用程序? AndroidStudio 是免费的,完全受支持且易于查找帮助。对于跨平台开发,有更好的工具可用。 FWIW,我从第一版(1995 年)开始在 Delphi 中开发。这只是移动设备的错误工具。
-
Segfault(11) 相当于 Windows 上的访问冲突。您正在访问无效的内存。你为什么打电话给
JavaService.stopSelf()?为什么要在Synchronize()'ed 过程中运行while循环? -
@323go - AlarmManager 看起来是要走的路。我开发桌面 OSX/Win 应用程序,所以我已经有了 Delphi,而且我刚刚开始学习移动设备,所以我现在坚持靠近“家”。
-
@RemyLebeau - while 刚刚从较早的尝试中遗留下来。应该删除它。
-
@323go 我也更喜欢 Android Studio,但是在工作中我们有很多 delphi 库(需要在客户端运行的函数),XE 允许你在你的 android 应用程序中使用它们,所以它是是我们公司的自然选择。无需重新发明轮子。
标签: android multithreading delphi service firemonkey