如何在Delphi中使用后台服务自动运行应用程序?

时间:2015-12-10 19:45:48

标签: android delphi service autorun delphi-10-seattle

是否有可能在Delphi 10 Seattle中创建一个Android应用程序(带有后台服务),它将在启动android设备后自动启动?

我找到了一个解决方案(Auto start Delphi XE5 Android App after boot),但它适用于Delphi XE5版本,并且没有自动启动后台服务的选项。

你们有没有试过解决这个问题?如果这样与我们分享您的解决方案?

更新:

我不知道出了什么问题。

  1. 添加BroadcastReceiver以使用

  2. 注册BroadcastReceiver

    procedure TForm1.CreateBroadcastReceiver;
    begin
      if not Assigned(BroadcastReceiver) then
        begin
          BroadcastReceiver:= TCSBroadcastReceiver.Create(nil);
          BroadcastReceiver.OnReceive:= BroadcastReceiverOnReceive;
          BroadcastReceiver.RegisterReceive;
          BroadcastReceiver.Add('android.intent.action.BOOT_COMPLETED');
        end;
    end;
    
  3. 设置BroadcastReceiver OnReceive

    procedure TForm1.BroadcastReceiverOnReceive(csContext: JContext; csIntent: JIntent);
    var
      Inx: JIntent;
    begin
      if JStringToString(csIntent.getAction).Contains('android.intent.action.BOOT_COMPLETED') then
        begin
          Inx := TJIntent.Create;
          Inx.setClassName(csContext, StringToJString('com.embarcadero.firemonkey.FMXNativeActivity'));
          Inx.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
          TAndroidHelper.Context.startActivity(Inx);
        end;
    end;
    
  4. 更新AndroidManifest.xml

  5. <receiver android:name="com.embarcadero.rtl.notifications.NotificationAlarm" />
    <receiver android:name="com.embarcadero.ProjectBCTA"
      android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    
    1. 启用RECEIVE_BOOT_COMPLETED权限

    2. 推出该应用程序。

    3. 停止申请。

    4. 重新启动机器。

    5. 重新启动系统后会显示错误消息应用程序已停止

    6. 我做错了什么。什么是错误?

3 个答案:

答案 0 :(得分:1)

在活动/组件明确请求它开始运行之前,Android服务不会开始运行。您仍然需要创建并注册BroadcastReceiver以接收BOOT_COMPLETED事件(如the XE5 article you linked to描述)并让您的事件处理程序根据需要启动您的服务:

Creating Android Services | Starting a Service

答案 1 :(得分:0)

您可以更改DanyWind的BroadcastReceiver以启动服务而不是应用程序(主机):

NSObjectProtocol

您还需要更新build.bat中的所有XE5路径,以指向D10或更高版本的等效路径。

Danny的build.bat将BootReceiver.dex与默认的Embaracdero Classes.dex合并,而不是使用应用程序生成的classes.dex(主机)。必须更正批处理文件中的路径。有关更详细的说明,请参阅我的回答here

答案 2 :(得分:0)

我使用Delphi Tokyo 10.2在上周的工作中成功解决了问题以自动启动应用程序。我正在考虑启动后台服务,而不是启动后的应用程序,因为每次设备启动时,启动画面和应用程序当前都会“弹出”。 (我在研究如何启动服务的过程中偶然发现了你的问题,我将在本周末尝试使用建议的“startService”Java方法的变体。经历了痛苦,我可以减轻你的负担。)

基本上对于较新的编译器,您不再需要Danny Wind的文章中修改“Classes.dex”文件的步骤。我在下面描述的东西适用于东京,如果它以同样的方式工作,它可能适用于西雅图,我相信它。

您不能使用Delphi代码注册BroadcastReceiver。这必须在Java中完成,编译的类在JAR中。 Danny Wind的Java包将继续完全解决问题,条件是您在清单文件中包含问题的第4步,并在项目的Android权限中包含问题的第5步。

顺便说一下,您不应该编辑“AndroidManifest.xml”文件,而应该编辑“AndroidManifest.template.xml”文件。

如果你了解如何为后台服务添加JAR,你可以按照相同的方法,通过转到“Android”目标平台下的“Libraries”文件夹,向“BOOT_COMPLETED”添加包含BroadcastReceiver的JAR。 - 鼠标点击并选择“添加”。在这种情况下,您可以添加包含BroadcastReceiver的JAR,而不是添加后台服务JAR(应该已经存在)。

为了将Java编译成一个类,然后将其包含在一个JAR中,我使用以下批处理文件,该文件基于Danny Wind的文章和Delphi运行的命令来编译它为其生成的Java后台服务(您可以在“消息”窗口的“输出”选项卡中看到):

@ECHO OFF
rem Path to Android classes JAR-file
SET ANDROID_JAR="C:\Users\Public\Documents\Embarcadero\Studio\19.0\PlatformSDKs\android-sdk-windows\platforms\android-26\android.jar"
rem Setup parameters
SET SOURCE_FILE=%1
SET JAR_FILE=%2
IF x%2 == x SET JAR_FILE=%SOURCE_FILE%
SET CONFIGURATION=%3
IF x%3 == x SET CONFIGURATION=Debug
rem Ensure directory to hold Java Class files exists for Java Archive
MKDIR JavaClasses\%JAR_FILE% 2> NUL
rem Indicate actions
ECHO .
ECHO Compiling %SOURCE_FILE%.java to %SOURCE_FILE%.class and storing in %CONFIGURATION%\%JAR_FILE%.jar...
ECHO .
rem Compile Java Class file
"%JAVASDK%\javac" -Xlint:deprecation -classpath %ANDROID_JAR% -bootclasspath %ANDROID_JAR% -d JavaClasses\%JAR_FILE% -target 1.6 -g -source 1.6 %SOURCE_FILE%.java
rem Create Java Archive file containing class file
"%JAVASDK%\jar" cf %CONFIGURATION%\%JAR_FILE%.jar -C .\JavaClasses\%JAR_FILE% com
rem Clean-up
SET ANDROID_JAR=""
SET SOURCE_FILE=""
SET JAR_FILE=""
SET CONFIGURATION=""

批处理文件有3个参数:

  1. Java文件的名称,减去任何扩展名。
  2. JAR文件的名称,减去任何扩展名。
  3. 配置名称(即“调试”或“发布”)
  4. 如果只有一个参数,则JAR文件名将与Java文件同名,配置将设置为“Debug”。

    如果只有两个参数,配置将设置为“Debug”。

    请注意,批处理文件现在不会对参数进行任何错误检查。

    批处理文件在调用“javac”时使用的参数与Danny Wind的文章中的参数略有不同。这些是我从Delphi IDE使用的内容(如Output选项卡中所示)。

    您需要更改设置环境变量“ANDROID_JAR”的行,以获得编译器“android.jar”文件的正确路径。

    您还需要将名为“JAVASDK”的环境变量设置为Java SDK的“bin”文件夹的路径。在我的机器上是“C:\ Program Files \ Java \ jdk1.8.0_60 \ bin”。这是我通过“系统属性/高级/环境变量”设置的。

    编译和归档后,包含BroadcastReceiver的JAR将位于“Debug”或“Release”文件夹中,具体取决于您选择的配置。

    将包含BroadcastReceiver的JAR添加到您的项目后,较新版本的Delphi将自动将JAR文件链接到“Classes.dex”,最终将APK链接到您的应用程序。

    将APK部署到您的设备,至少运行一次应用程序,然后重新启动设备。启动完成后,您应该会看到应用启动。