【问题标题】:Android service doesn't work when I close app当我关闭应用程序时,Android 服务不起作用
【发布时间】:2016-11-19 11:51:00
【问题描述】:

我不知道我的代码有什么问题!

它可以工作,但是当我关闭应用程序时服务不起作用!!!再次启动应用程序时计数器会重新启动!!!任何帮助 我的代码:

主要:

unit Unit1;

interface

uses
 System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.IOUtils,
 System.Android.Service, FMX.ScrollBox, FMX.Memo, FMX.Controls.Presentation,
FMX.StdCtrls
;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
FService : TLocalServiceConnection;
public
{ Public declarations }
end;

 var
  Form1: TForm1;

 implementation

  {$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin

FService := TLocalServiceConnection.Create;

  end;

 procedure TForm1.Button2Click(Sender: TObject);
 begin
  FService.StartService('AndroidServer');


  end;

    end.

服务:

  unit Unit2;

   interface

       uses
     System.SysUtils,  System.Threading,
    System.Classes, System.IOUtils,
     System.Android.Service,
      AndroidApi.JNI.GraphicsContentViewText,
    Androidapi.JNI.Os, System.Notification;

     type

        TAndroidServiceDM = class(TAndroidService)
        NotificationCenter1: TNotificationCenter;
         function AndroidServiceStartCommand(const Sender: TObject;
         const Intent: JIntent; Flags, StartId: Integer): Integer;
         procedure AndroidServiceCreate(Sender: TObject);
         Procedure DoNotification;
          procedure AndroidServiceTaskRemoved(const Sender: TObject;
              const ARootIntent: JIntent);
          procedure AndroidServiceDestroy(Sender: TObject);
       private
       { Private declarations }

        public
       { Public declarations }

        end;

       var
       AndroidServiceDM: TAndroidServiceDM;

        io:Integer;
        implementation

       {%CLASSGROUP 'FMX.Controls.TControl'}

            {$R *.dfm}
            uses
           Androidapi.JNI.App;

           procedure TAndroidServiceDM.DoNotification;
            Var

      MyNotification: TNotification;



     begin


    TTask.Run(procedure
      begin

     myNotification := NotificationCenter1.CreateNotification;
      try
   MyNotification.Name := 'ServiceNotification';
   MyNotification.Title := 'Android Service Notification';
    MyNotification.AlertBody := io.ToString;
    MyNotification.FireDate := Now;
    NotificationCenter1.PresentNotification(MyNotification);
   finally
    myNotification.DisposeOf;
     end;

    tthread.Synchronize(nil,
     procedure
    begin
  end);
  end
   )  ;

   end;

    procedure TAndroidServiceDM.AndroidServiceCreate(Sender: TObject);
      var
      atask : Itask;

      begin
      io:=1;
      atask := Ttask.create(procedure()

       begin

      while true do
       begin

       begin
        sleep(5000);
        DoNotification;
        io:=io+1;
      end;

      end;

 end);

 atask.Start;




  end;

  procedure TAndroidServiceDM.AndroidServiceDestroy(Sender: TObject);
  begin

  end;

   function TAndroidServiceDM.AndroidServiceStartCommand(const Sender:           TObject;
     const Intent: JIntent; Flags, StartId: Integer): Integer;
    begin
    Result := TJService.JavaClass.START_STICKY;

      end;



     end.

它可以工作,但是当我关闭应用程序时服务不起作用!!! 再次启动应用程序时计数器会重新启动!!! 任何帮助

谢谢

【问题讨论】:

  • 没有XE10这样的Delphi版本。有 Delphi 10 Seattle 和 Delphi 10.1 Berlin,两者都不是 XE10。
  • 德尔福 10 西雅图和德尔福 10.1 柏林

标签: android delphi service


【解决方案1】:

本地服务与启动它的应用程序在同一进程中运行。因此,当应用终止时,服务也会终止。

如果您需要一个运行时间比其宿主应用程序寿命更长的服务,请在宿主应用程序的工作线程而不是主线程中启动该服务,并在服务的 onStartCommand 事件中调用 Service.startForeground() 方法。

或者,您可能需要在其清单中将服务标记为远程而不是本地,以便服务在其自己的进程中运行。然后,您的主应用可以根据需要与服务进行通信,例如使用 Intent。

【讨论】:

  • @IsamBuk 互联网上有很多例子。还有大量关于这个广泛项目所需的每个特定任务的教程。不要指望我们这里的任何人为您编写您的项目。
  • 谢谢 你能给我示例链接吗?曾在 Delphi 10.1 Berlin 工作
  • startForeground 接受JNotification,但我不知道如何从TNotification 获得JNotification
  • 在花费数小时试图为单击它时重新打开应用程序的服务获取一个简单的工作 JNotification 之后,我放弃了。这绝对需要来自 embarcadero 的工作示例。简单的“粘性”服务示例并不能解决问题。您仍然必须从基本上下文启动服务,您仍然需要做各种技巧来获得前台服务(我无法预测)
  • @nurettin TNotification 是一个纯Delphi RTL 类,它与Android 没有任何关系,因此您无法从中获得JNotification 接口。您需要改用 Delphi 的 Android JNI Bridge 框架中的 TJNotification 类。一个简单的网络搜索需要 2 秒才能在此博客文章的评论中找到 startForeground() 的 Delphi 示例:Delphi and Android services (part 2)
【解决方案2】:
  1. 将服务创建为Remote
  2. AlarmManager启动服务

这是启动服务并立即自行关闭的应用程序的代码。

program PlayerPowerMgr;

uses
  AndroidApi.JNI.GraphicsContentViewText,
  Androidapi.Helpers,
  Androidapi.JNI.App,

  Androidapi.NativeActivity,
  Androidapi.AppGlue,
  Androidapi.JNI.Embarcadero,
  ServiceUnit in '..\PowerMgrService\ServiceUnit.pas' {DM: TAndroidService};

{$R *.res}

procedure StartService;
var
     Intent: JIntent;
     PendingIntent: JPendingIntent;
const
  ServicePackageName = 'com.embarcadero.services.PlayerPwrMgrServ';
  ApplicationPackageName = 'com.embarcadero.PlayerPowerMgr';
begin
    Intent := TJIntent.Create;
    Intent.setClassName(
      StringToJString(ApplicationPackageName),
      StringToJString(ServicePackageName)
    );
     PendingIntent := TJPendingIntent.JavaClass.getService(TAndroidHelper.Context, 1, Intent, 0);
     TAndroidHelper.AlarmManager.&set(TJAlarmManager.JavaClass.RTC_WAKEUP, 1,  PendingIntent);
end;


begin
  StartService;
  TJFMXNativeActivity.Wrap(PAndroid_app(PANativeActivity(System.DelphiActivity)^.instance)^.activity.clazz).finish;
end.

当然,在项目经理的帮助下,您必须将服务添加到您的应用程序中。会出现这一行

ServiceUnit in '..\PowerMgrService\ServiceUnit.pas' {DM: TAndroidService};

用于近距离应用:

TJFMXNativeActivity.Wrap(PAndroid_app(PANativeActivity(System.DelphiActivity)^.instance)^.activity.clazz).finish;

等价

 MainActivity.Finish

,但是应用apk的大小会少10M左右。

创建这样的应用程序

1) 创建一个应用程序作为多设备应用程序/空白应用程序

2) 在项目管理器中从应用程序中删除 Unit1。

3) 在项目管理器中选择应用程序并点击“View Source”,然后插入此代码

4) 将您的服务添加到应用程序

【讨论】:

    猜你喜欢
    • 2017-11-03
    • 2021-01-31
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 2023-01-16
    相关资源
    最近更新 更多