当设备打开(启动完成)时启动应用程序 [英] Start app when device turn on (on boot completed) firemonkey

查看:95
本文介绍了当设备打开(启动完成)时启动应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据文章启动后自动启动Delphi XE5 Android应用来构建一个Android FireMonkey应用,该应用可在启动时启动,但始终会收到错误 INSTALL_FAILED_UID_CHANGED

I am trying from the article Auto start Delphi XE5 Android App after boot to build a Android FireMonkey app that starts on boot, but always got the error INSTALL_FAILED_UID_CHANGED

文章中的引用:

如何在Android设备上进行BOOT_COMPLETED后使用广播接收器自动启动Delphi XE5应用。

How to use a broadcast receiver to automatically start a Delphi XE5 App after BOOT_COMPLETED on an Android device.

在DOS时代,我们可以在启动后通过将应用程序添加到autoexec.bat中来启动应用程序。在Windows下,您可以使用注册表将程序添加到启动中,也​​可以使用msconfig查看启动程序。但是,这在Android下如何工作?

In good ol’ DOS days we could start an application after boot by adding it to autoexec.bat. Under Windows you can add a program to startup using the registry or view startup programs with msconfig. But how does this work under Android?

在设备启动后自动启动Delphi XE5 Android应用程序可以通过创建广播接收器来侦听BOOT_COMPLETED广播来完成

Automatically starting a Delphi XE5 Android app after the device has booted up can be done by creating a broadcast receiver that listens to the BOOT_COMPLETED broadcast intent.

本文介绍了使用Delphi XE5创建此类广播接收器的必要步骤:

This article descibes the steps necessary to create such a broadcast receiver with Delphi XE5:

创建一个新的Delphi XE5 Android项目
集使用权限来接收启动完成的
修改AndroidManifest.template.xml以使Android系统知道您具有广播接收器
编写一些Java代码
add它将其添加到classes.dex
中,并在您的项目中使用此新的classes.dex
在设备
上运行该应用程序创建一个新的Delphi XE5 Android项目

create a new Delphi XE5 Android project set uses permissions to receive boot completed modify AndroidManifest.template.xml to let the Android system know you have a broadcast receiver write some Java code add it to the classes.dex use this new classes.dex in your project run the app on device Create a new Delphi XE5 Android project

此步骤应该很容易,File |新增| Firemonkey移动应用程序。只需将其保存在您也可以通过命令提示符控制台访问的位置。

This step should be easy enough, File | New | Firemonkey Mobile Application. Just save it someplace that you can also reach with the command prompt console.

设置使用权限

所有Android应用必须在Android清单中注册所需的权限。在安装应用程序包时,清单文件由Android系统读取,并向用户通知所请求的权限。如果忘记列出所需的权限,系统将拒绝访问该功能。在这种情况下,我们需要接收启动完成权限。

All Android apps must register which permissions they need in the Android Manifest. The manifest is read by the Android system when installing the app package and the user is notified of the requested permissions. If you forgot to list a permission you need, access to that function will be denied by the system. In this case we need the receive boot completed permission.

打开项目|选项并使用权限将此权限设置为true。

Open Project | Options and uses permissions to set this permission to true.

ReceiveBootCompleted

ReceiveBootCompleted

修改AndroidManifest.template.xml

Modify AndroidManifest.template.xml

每次将项目部署到apk时,Delphi IDE都会使用Android Manifest模板为Android包(.apk)重新创建清单。如果要修改清单,则可以在此处进行修改。

The Android Manifest template is used by the Delphi IDE to re-create the manifest for your Android package (.apk), each time you deploy the project to an apk. If you want to modify the Manifest, this is the place to do so.

在此清单中,我们将通知Android系统我们有一个广播意图BOOT_COMPLETED的接收者。新代码为黑色,现有代码为蓝色:

In this manifest we will notify the Android system that we have a receiver for the broadcast intent BOOT_COMPLETED. The new code is in black, existing stuff in blue:

</activity>
<receiver android:name="com.embarcadero.firemonkey.notifications.FMXNotificationAlarm" />
<receiver android:name="com.dannywind.delphi.BootReceiver"
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>
</application>
</manifest>
<!– END_INCLUDE(manifest) –>

写一些Java代码

不幸的是当前版本的Delphi没有可用于自动启动应用程序的预定义接收器。为了使之成为可能,我们必须编写一些Java代码并将其包含在您的Delphi Android应用程序的classes.dex文件中。

Unfortunately the current version of Delphi does not have a pre-defined receiver that we can use to autostart the app. To make this possible we have to write a bit of Java code and include this into the classes.dex file of your Delphi Android app.

Java代码如下。使用BootReceiver.java作为文件名:

The Java code is as follows. Use BootReceiver.java as the file name:

package com.dannywind.delphi;import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import android.util.Log;
public class BootReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Intent launchintent = new Intent();
launchintent.setClassName(context, "com.embarcadero.firemonkey.FMXNativeActivity");
launchintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(launchintent);
}
}

用于启动活动的上下文变量实际上是您的应用程序的上下文。本质上,我们是从应用程序内部启动应用程序,这是一项新任务。由于默认Delphi应用程序中的本机活动具有默认名称,因此我们可以启动当前应用程序的com.embarcadero.firemonkey.FMXNativeActivity。

The context variable used to start the activity is actually your app’s context. We’re essentially starting the app, from within the app as a new task. Because the native activity in a default Delphi app has a default name, we can just start the com.embarcadero.firemonkey.FMXNativeActivity of the current app.

将其添加到classes.dex

Add it to the classes.dex

Delphi有一个预编译的classes.dex,可在部署步骤中放入任何Delphi Android软件包中。我们将把此Java代码添加到classes.dex中,并使用Deployment Manager用我们的修改版本替换默认的classes.dex。

Delphi has a pre-compiled classes.dex which is put into any Delphi Android package in the deployment step. We are going to add this Java code to the classes.dex, and use the deployment manager to replace the default classes.dex with our modified version.

在您的项目目录中创建一个子目录java\src\com\dannywind\delphi,然后在其中放置BootReceiver.java代码。使用以下批处理文件代码构建Java代码:

In your project directory create a subdirectory java\src\com\dannywind\delphi and place the BootReceiver.java code there. Build the Java code using the following batch file code:

@echo off
echo.
echo Compiles your Java code into classes.dex
echo Verified to work in Delphi XE5 Update 1 and 2
echo.
echo Place this batch in a java folder below your project (project\java)
echo Place the source in project\java\src\com\dannywind\delphi
echo If your source file location or name is different, please modify it below.
echo.setlocal
set ANDROID_JAR="C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk\platforms\android-17\android.jar"
set DX_LIB="C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk\build-tools\android-4.2.2\lib"
set EMBO_DEX="C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\android\debug\classes.dex"
set PROJ_DIR=%CD%
set VERBOSE=0
set JAVASDK="C:\Program Files\Java\jdk1.7.0_25\bin"
set DX_BAT="C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk\build-tools\android-4.2.2\dx.bat"
echo.
echo Compiling the Java source files
echo.
pause
mkdir output 2> nul
mkdir output\classes 2> nul
if x%VERBOSE% == x1 SET VERBOSE_FLAG=-verbose
%JAVASDK%\javac %VERBOSE_FLAG% -Xlint:all -classpath %ANDROID_JAR% -d output\classes -source 1.6 -target 1.6 src\com\dannywind\delphi\BootReceiver.java

echo.
echo Creating jar containing the new classes
echo.
pause
mkdir output\jar 2> nul
if x%VERBOSE% == x1 SET VERBOSE_FLAG=v
%JAVASDK%\jar c%VERBOSE_FLAG%f output\jar\test_classes.jar -C output\classes com

echo.
echo Converting from jar to dex…
echo.
pause
mkdir output\dex 2> nul
if x%VERBOSE% == x1 SET VERBOSE_FLAG=–verbose
call %DX_BAT% –dex %VERBOSE_FLAG% –output=%PROJ_DIR%\output\dex\test_classes.dex –positions=lines %PROJ_DIR%\output\jar\test_classes.jar

echo.
echo Merging dex files
echo.
pause
%JAVASDK%\java -cp %DX_LIB%\dx.jar com.android.dx.merge.DexMerger %PROJ_DIR%\output\dex\classes.dex %PROJ_DIR%\output\dex\test_classes.dex %EMBO_DEX%

echo.
echo Now use output\dex\classes.dex instead of default classes.dex
echo And add broadcastreceiver to AndroidManifest.template.xml
echo.

:Exit
endlocal

以上批处理文件最初是由Brian Long编写,用于将自己的Java脚本与classes.dex合并。感谢Brian提供它。我已经对其做了一些小的修改。

The above batch file was originally written by Brian Long for merging your own Java scripts with classes.dex. Thanks to Brian for making it available. I have made some minor modifications to it.

将build.bat文件放入项目目录project\java下的java子目录中,打开命令提示符,然后运行build.bat。

Place the build.bat file into the java subdirectory under your project directory project\java, open a command prompt and just run build.bat.

运行批处理文件时,您将看到警告未设置引导程序类路径。我们使用与Delphi XE5捆绑在一起的Java SDK 1.7来为classes.dex构建1.6兼容的源代码。如果确实安装了1.6,则可以添加此选项以摆脱警告 -bootclasspath C:\jdk1.6.0\lib\rt.jar,但您也可以安全地忽略它,因为它不会

When running the batch file you’ll see a warning "bootstrap class path not set". We are using the Java SDK 1.7 that is bundled with Delphi XE5 to build 1.6 compatible source code for classes.dex. If you do have 1.6 installed you can add this option to get rid of the warning "-bootclasspath C:\jdk1.6.0\lib\rt.jar", but you can also just ignore it safely as it will not in any way interfere with our snippet of Java code.

使用此新类。dex

使用Deployment Manager我们将禁用默认的classes.dex,并使用添加文件按钮添加新的扩展后的classes.dex文件。

Using the deployment manager we disable the default classes.dex, and add our new expanded classes.dex file with the add files button.

DeploymentClassesDex

DeploymentClassesDex

在设备上运行应用程序

现在在Android设备上运行应用程序。如果成功运行,则让其运行,然后长按开/关按钮关闭设备。 Android会询问您是否要关闭它,当然可以。现在将其重新打开,启动顺序完成后,您的Delphi应用程序将自动运行。

Now run the app on the Android device. If it runs succesfully, just let it run, and switch the device off with a long press on the on/off button. Android will ask you if you want to switch it off, which of course you do. Now turn it back on and your Delphi app will autorun after the boot sequence is completed.

提示

Delphi XE5 IDE确实希望您使用默认的classes.dex文件,因此它将在每次切换部署配置时重新启用它。如果收到应用已停止消息,请首先检查Delphi是否没有重新启用默认的classes.dex文件。您还可以通过扫描logcat来确认找不到类 com.dannywind.delphi.BootReceiver。

The Delphi XE5 IDE really wants you to use the default classes.dex file, so it will re-enable it every time you switch deployment configuration. If you get a "App has stopped" message, please check first if Delphi hasn’t re-enabled the default classes.dex file. You can also confirm this by scanning logcat for "Didn’t find class "com.dannywind.delphi.BootReceiver"".

使用Project |部署后,Delphi将在本地硬盘上创建一个.apk文件。它实际上并未部署到您的Android设备。要部署到设备,只需运行它即可。

When you use Project | Deploy, Delphi creates an .apk file on your local harddisk. It does not actually deploy to your Android device. To deploy to device, just run it.

您的自动运行的Delphi应用程序处于停止状态时,不会收到启动完成事件。此功能已添加到Android 3.1中,以提高安全性( http:/ /developer.android.com/about/versions/android-3.1.html#api )。这意味着用户必须至少运行一次该应用程序,因为这将使它脱离锁定状态。同样,如果您使用管理应用程序强制停止应用程序,则该应用程序将再次处于停止状态,并且将不再自动运行。只需再次运行该应用程序,自动运行将再次起作用。请注意,使用最近使用的应用程序按钮关闭该应用程序,然后向上滑动;不等于合力且不会使其处于停止状态。如果您以这种方式关闭应用程序,它将在重新启动后成功自动运行。

Your autorun Delphi app will not receive a boot completed event if it is in a stopped state. This is a feature that was added to Android 3.1 to improve security (http://developer.android.com/about/versions/android-3.1.html#api). What this means is the user must run the app at least once, as this will get it out of lockdown. Also if you force stop the app using manage applications it will again be in a stopped state and will no longer autorun. Just run the app once again and autorun will work again. Please note that closing the app with the recent apps button and then swiping it up; does not equal a force close and does not put it in a stopped state. If you close your app this way it will succesfully autorun after reboot.

有人用这种方法成功吗?

还是有人知道另一种方法?

Does anybody got success with this method?
Or someone knows another method?

推荐答案

我刚刚有一个理由要重新访问我的可启动服务Delphi Android项目,所以我想在这里添加答案。

I've just had a reason to revisit my bootable service Delphi Android project, so I thought I'd add an answer here.

Brian Long(后来由Danny Wind)提供的原始批处理文件的问题在于它使用EMBT classes.dex,而不是使用项目本身构建中的classes.dex!也就是说: EMBO_DEX 变量应指向类似以下内容:

The problem with the original batch file supplied by Brian Long (and later by Danny Wind) is that it uses the EMBT classes.dex, instead of using the classes.dex from a build of the project itself! That is: the EMBO_DEX variable should point to something like:

SET EMBO_DEX = C:\MyProject\Android\Debug\classes.dex

SET EMBO_DEX=C:\MyProject\Android\Debug\classes.dex

换句话说,您可以构建目标首先使用MyProject,然后生成项目的classes.dex,然后运行批处理文件以生成合并的dex文件(可在java\output\dex文件夹中找到)。

In other words to achieve the goal, you build your MyProject first, then once the project's classes.dex has been generated, you run the batch file to generate a merged dex file (which will be found in the java\output\dex folder).

然后必须与您的应用一起部署合并的dex,而不是C:\MyProject\Android\Debug\文件夹中的classes.dex!调整您的项目->部署以确保执行此操作。当您从IDE运行应用程序时,将发生(合并的dex文件的)部署。

It is the merged dex must then be deployed with your app and not the classes.dex from C:\MyProject\Android\Debug\ folder! Adjust your project->deployment to make sure it does that. Deployment (of the merged dex file) occurs when you RUN the app from the IDE.

根据所使用的Delphi版本,bat文件中的某些路径还需要更新:

Depending on the Delphi version you are using, some of the paths in the bat file need to be updated also:

例如,对于Delphi 10.1,这些变量看起来像:

For Delphi 10.1, for example, these vars look like:

set ANDROID_JAR="C:\Users\Public\Documents\Embarcadero\Studio\18.0\PlatformSDKs\android-sdk-windows\platforms\android-22\android.jar"
set DX_LIB="C:\Users\Public\Documents\Embarcadero\Studio\18.0\PlatformSDKs\android-sdk-windows\build-tools\22.0.1\lib"
set DX_BAT="C:\Users\Public\Documents\Embarcadero\Studio\18.0\PlatformSDKs\android-sdk-windows\build-tools\22.0.1\dx.bat"

并取决于您安装的Java版本在系统上

and depending on which version of Java you have installed on your system

set JAVASDK="C:\Program Files\Java\jdk1.8.0_60\bin"

对于与这项工作相关的其他任务,丹尼Wind的原始指南仍然有效。

For the other tasks related to making this work, the Danny Wind's original guide is still as valid as ever.

这篇关于当设备打开(启动完成)时启动应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆