当首次安装.apk文件时如何启动服务

70
在我的应用程序中,没有UI部分,因此我需要在设备上安装应用程序后立即启动服务。我看到了许多链接,其中答案是不可能的,但我认为它肯定是可能的。只需查看Android市场上的PlanB应用程序,它可以满足我的要求。以下是我尝试的清单文件,但服务根本没有被调用。因此,请告诉我在应用程序安装时启动服务的最佳方法是什么。
更新
我也尝试使用android.intent.action.PACKAGE_ADDED来检测其他应用程序的包,但对于自身则无效。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.auto.start"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <application
        android:icon="@drawable/ic_launcher" >

        <service android:name=".MyService">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </service>

        <receiver android:name=".BootUpReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <action android:name="android.intent.action.PACKAGE_INSTALL" />
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <data android:scheme="package"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

@Lalit:你好,你找到了在apk首次安装时启动服务的方法吗? - Mehul Joisar
谢谢您的快速回复。我还有一个疑问,就是是否可以创建一个没有任何应用程序图标的应用程序?也就是说,该应用程序仅包含广播接收器和服务。 - Mehul Joisar
是的,可能性是存在的,但它只能在3.1或3.1以下版本中运行。 - Lalit Poptani
是的,我已经从CommonsWare的答案中读到了这一点。这就是为什么我问你是否找到了任何解决办法来适应更高版本的设备。因为现在大多数设备都是使用ICS或JellyBean系统发布的。无论如何,感谢您的回复! - Mehul Joisar
@MehulJoisar <data android:scheme="package" android:pathPattern="com.example.packagename" />。我将这段代码放在我的Androidmanifest文件中,它可以隐藏应用程序菜单。希望这是你需要的。 - Nitish Patel
显示剩余3条评论
11个回答

80

幸运的是,经过在XOOM和Galaxy Nexus上的测试,Plan B在Android 3.1+上无法使用。

Plan B所做的是利用一个安全漏洞,这可能被驱动型恶意软件利用,这也是Android不再允许其发生的原因。


更新

澄清一下:如inazaruk所发布并我在其他答案的评论中提到的,所有应用程序在安装时都处于“停止”状态。这与用户从设置应用程序中强制停止应用程序后应用程序所处的状态相同。在这种“停止”状态下,除非手动启动活动,否则应用程序不会以任何原因运行。值得注意的是,任何已注册的BroadcastReceviers都将不会被调用,直到用户手动运行应用程序为止。

这个阻止了Plan B远程安装和运行的情况,他们之前正在利用这个漏洞。毕竟,倘若如此,任何有被黑Google帐户的人都面临着自动感染设备的风险。

因此,当OP说:

我需要在设备上安装应用程序时立即启动服务

OP将会失败,并需要重新设计应用程序以避免这种所谓的“需求”。


值得注意的是,无论已注册哪个事件,BroadcastReceviers 都不会被调用,直到用户手动运行应用程序或执行硬件操作。这可能包括启动相机或重新启动设备(正如作者在 https://dev59.com/J3I95IYBdhLWcg3w2Rzz#2127179 中提到的)。请记住,这可能会使您的应用程序在 Google Play 上被标记为恶意软件。 - Abandoned Cart

18

/system分区中安装的应用程序不会在安装后被置于“已停止”状态。如果您有root权限,可以执行以下操作:

$ adb root
$ adb remount
$ adb push your.apk /system/app

它可以立即接收广播意图。这当然不能提供通用解决方案,但为了完整性而提及。

编辑:请记住,不同版本的Android将系统APK放置在不同的位置。例如,Android 8将其放置在/system/app//.apk下面。进入您的设备并浏览,按照其他系统APK使用的相同方案进行操作。


如果他这样做,他将无法更新应用程序,每次都必须执行相同的过程。 - Vipin Sahu
3
当然,只要应用的包名和签名相同,他就能够更新系统应用。更新将被放置在数据分区,但由于先前版本在系统分区上可用,因此仍保持“系统”状态。 - Olle
2
@JeffreyBlattman 是的,我同意你的观点。我是在评论Vipin的评论。我不同意他的说法,即每次更新都必须通过adb命令完成。我的观点是它们只需要完成一次。一旦apk位于/system/app中,就可以使用普通的应用程序安装/更新。 - Olle
@JeffreyBlattman:这只适用于安装在“常规”数据分区上,但使用系统签名的应用程序吗? - Tal Kanel
2
我一直使用平台证书为我的应用进行签名,但是通过adb“正常”安装它。直到我将apk推送到/system/app中,服务才自动启动。这个答案非常有帮助。 - Josh Feldman
显示剩余2条评论

14

我同意CommonsWare对这个问题的回答:如何在安装后启动Android服务。换句话说,你不能在刚刚安装完毕后自动启动你的服务。

关于新的Android平台还有一件事:如果你没有任何UI,即使在Android 3.1+上使用BOOT_COMPLETE意图,你也会遇到启动你的服务的麻烦。

那是因为所有安装的应用都处于停止状态。在这种状态下,应用程序将不会接收到任何广播通知。

为了激活你的应用程序,其他应用程序(或用户)需要启动你的服务或活动,或内容提供者。通常的工作流程是当用户点击你的应用程序图标时。

我在我的博客文章中详细说明了这一点。


你给了一个错误的博客链接,正确的链接是“激活”应用程序。干杯 :) - Alexander Malakhov
1
未找到链接@inazaruk,Alexander Malakhov - Ajay Pandya
@inazaruk:你的博客文章有新链接吗? - Kikiwa
@AjayPandya,**@Kikiwa@AADTechnical**,最新的存档链接 - Dennis T --Reinstate Monica--

5

Plan B通过监听系统中发生的事件来执行此启动。它使用一个接收器,可以监听数百个事件,希望其中一些最终会触发。所以这就是你可以做到的方式。否则,没有内置的方法可以在安装后立即启动应用程序。


1
哦!!!监听100多个事件会消耗最多的电池电量,因此应用程序可能会失败,我不认为会发生这种情况。 - Lalit Poptani
1
@Lalit:“……成本最高的电池使用,因此应用程序可能会失败……”我刚刚安装了Plan B,它自动启用了我的手机上的GPS。你有没有见过HTC Desire上GPS会比使用被动的“BroadcastReceiver”监听各种系统事件更快地耗尽电池? - Squonk
系统并没有提供一种方法来做到这一点,所以Plan B使用的方法是一个明显的黑客攻击,甚至不能保证工作。当然,Plan B打算在丢失的设备上工作,所以所有手段都是好的。但这不是日常应用程序中要使用的方法,这是肯定的。你可以少听一些事件,虽然这会减少你的应用程序启动的机会。 - Malcolm
@Malcolm 嗯,那么发送短信还需要在应用程序安装时调用一些代码。 :) - Lalit Poptani
@LalitPoptani Plan B 应该安装在当前丢失的设备上,因此用户还需要自己发送短信。我不是说它会自动发送。 - Malcolm
显示剩余3条评论

5
我不确定您的限制/目的是什么,但如果您可以安装另一个具有活动的应用程序,则可以使用标志FLAG_INCLUDE_STOPPED_PACKAGES发送意图。这将使用您的应用程序进行意图解析,即使它处于停止状态。如果意图的操作与您的过滤器之一匹配,它也会使包脱离停止状态。

4

我认为您不能在在设备上安装应用程序后立即启动服务,

用户必须通过某种Activity首先调用该应用程序。唯一需要做的就是在manifest中注册适当的意图和Broadcast Receiver,当设备发生某些事情时,这些内容会引发您的服务,但这只适用于Android 3.1版本以下。

编辑:

Android 3.1+ 开始,您无法使用任何Broadcast来启动应用程序,因为所有应用程序在完成设备引导后都处于不活动状态,用户必须调用它才能启动它。(通过触摸应用程序图标)。


每次安装新应用程序时,您都将启动自己的应用程序.... :D。 - N-JOY
@N-JOY 不用担心,我会检查应用程序的包名。在这种情况下。 :D - Lalit Poptani
当然,你会这样做,但是黑客所需要的只是这个广播,并将安装的数据包发送到远程服务器。 - N-JOY
1
“肯定的一个是在RECEIVE_BOOT_COMPLETE上,这个你已经尝试过了。” - 不适用于Android 3.1+。用户必须手动从应用程序启动活动,然后才能使任何“BroadcastReceiver”工作。 - CommonsWare
@CommonsWare 所以 RECEIVE_BOOT_COMPLETE 在应用程序第一次安装时不起作用,但如果用户使用了该应用程序,则之后会起作用,是这样吗? - Lalit Poptani
1
@LalitPoptani:一旦用户启动应用程序的活动(例如通过启动器),所有“BroadcastReceivers”将工作,直到用户从设置应用程序中强制停止应用程序,并且应用程序返回到首次安装时处于“已停止”状态。可能会有任务杀手也有相同的效果 - 我还没有尝试过这个。 - CommonsWare

1

正如CommonsWare在这个问题的答案中所述(我想你们已经看过了,但选择忽略),在安装时启动服务是不可能的-它根本没有被实现到平台中。

然而,在下一次启动时自动启动是可能的。

如PlanB的技术细节所述:

Plan B将尝试在下载后立即启动,但在某些情况下,您需要发送短信才能启动它。

我猜在root手机上,您可能能够在安装时启动Service,但无法保证手机是否已root,这就是为什么PlanB在某些情况下需要接收文本消息,因为它可以被应用程序的IntentFilter注册,然后用于启动Service


是的,我已经检查过了,但您可以检查一下我在问题中提供的PlanB应用程序。 - Lalit Poptani
不过在 Android 3.1 及以上版本,自动启动需要手动开启应用程序中的 Activity,否则任何 Broadcast Receiver 都无法工作。而在下一次引导时自动启动是可能的。 - CommonsWare

1
也许最好的方法是通过社交工程而不是软件工程来实现这一点(现在我在谈论OP的具体意图,即安装程序以检索被盗手机,而不是一般问题)。因此,在主屏幕上突然出现的带有文本的图标,比如“密码列表”或“我的银行账户”,无疑会被点击。看看各种其他网络钓鱼的成功,这里你将针对一个已经有动机继续进行恶意活动的小偷。让小偷为你开始它。 :)

1

在Google Play上有一个应用程序 Android Lost,可以通过收到的短信调用Google推送消息的注册服务,而无需启动应用程序,适用于3.0+版本。


0

有一种方法可以实现这个。

正如你已经提到的,你可以使用 android.intent.action.PACKAGE_ADDED 来检测其他应用程序的安装情况。 最后一步是找到另一个已经在设备上运行的应用程序来查询和启动你的应用程序。

如果你的目标用户已经安装了你合作的任何应用程序,或者查找一些在每个人的设备上预装的常见服务(我不能说更多,但这种方法已经被成千上万的应用程序使用)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接