如何构建Android应用程序作为系统服务

时间:2014-11-04 01:23:24

标签: java android android-service android-source android-framework

我遇到的问题是,应用程序是作为Android服务运行的,应该在启动时启动,无需任何用户交互或现有活动。

从其他来源,我们知道这基本上是不可能的:http://commonsware.com/blog/2011/07/13/boot-completed-regression-confirmed.html

目前,出于测试目的,该应用程序具有非常简单的GUI,它按如下方式注册广播接收器:

public class MyAppReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Intent serviceIntent = new Intent(context, MyAppService.class);
            context.startService(serviceIntent);
        }
    }
}

如果用户至少启动一次应用程序以允许接收者获得ACTION_BOOT_COMPLETED,则效果很好。

目标是完全删除GUI,并在启动时启动应用程序,而无需用户执行任何操作。请注意,此软件不会部署在Play商店中,而是构建为自定义AOSP版本的一部分而非公开使用。

我找到的唯一解决方案是将应用程序添加到Android应用程序框架中,将其构建为系统服务。

参见参考文献:

http://www.androidenea.com/2009/12/adding-system-server-to-android.html http://processors.wiki.ti.com/index.php/Android-Adding_SystemService

但是我对这种可能性的优点和缺点感到有点困惑,我希望有人能回答以下问题:

1)该应用是否需要使用整个系统(来自源的AOSP)构建,因此无法部署为APK?

2)一旦系统建成,有没有办法在事后更新应用程序(使用APK)?

3)以这种方式(作为系统服务)运行应用程序是否可行或方便,因为它需要在启动时启动而不是由于其他原因(例如从中实例化代码)等)?

应用程序本身并不特别 - 它是一个客户端/远程服务器模型,用于报告系统统计信息以用于研究目的。

修改

添加清单以确保完整性:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="org.myapp.myapp"
  android:versionCode="1"
  android:versionName="22.0">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.INTERNET" />

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

    <activity android:name="myapp"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name="org.myapp.myappclient.myappservice"
        android:label="myappservice">
        <intent-filter>
            <action android:name="org.myapp.myappclient.myappservice" />
        </intent-filter>
    </service>

    <receiver
        android:enabled="true"
        android:name="org.myapp.myappclient.myappreceiver"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

</application>

3 个答案:

答案 0 :(得分:2)

如果您要修改AOSP,则可以创建一个“持久应用程序”

https://developer.android.com/guide/topics/manifest/application-element#persistent

这会在清单中的应用程序标签上显示

<application
  persistent="true"
  ...
>
  

应用程序是否应始终保持运行-如果应该,则始终为“ true”,否则应始终为“ false”。默认值为“ false”。应用程序通常不应设置该标志;持久模式仅适用于某些系统应用程序。

它必须是系统应用程序,才能正常工作。

它将在启动时启动,带有此标志的所有应用程序都将在从初始化中激发BOOT_COMPLETED意向之前启动。

好处是

  • 这将导致该应用由ActivityManager保持活动状态
  • 如果应用死亡,它将自动神奇地重启
  • 生命周期更改不会导致您的应用关闭

然后,您可以生成服务,或者做您真正想要做的事情。

我确定5年后它不会有帮助,但可能会帮助其他人:-)

答案 1 :(得分:0)

  1. 理论上你应该可以单独部署你的apk,但你可能仍然需要修改启动程序,将你的服务包含在要启动的程序/服务列表中。

  2. 是的,你可以。只需确保使用相同的密钥对您的应用程序包进行签名。

  3. 这取决于。下载并修改应用程序框架是否值得确保您的服务在用户安装应用程序时正常运行然后离开它?我想你可以在某个地方附上一个发行说明,告知用户该应用程序在安装后至少运行一次后才能运行。

  4. <强> 更新

    1. 也许你可以让你的Launcher应用程序来处理它。
    2. 我认为这里有一些混乱。预安装的应用程序不一定是系统应用程序。如果您的应用不需要特殊权限,那么它只是一个预安装的用户应用。试想一下,大多数手机都附带Facebook或Youtube,这些应用程序可以在以后更新。

答案 2 :(得分:0)

1.无需创建系统服务,只需在后台运行的普通服务,您不需要GUI,所以不要使用活动而是服务。 3.如果将其作为系统服务,当发生错误时,整个系统将被重置。