【发布时间】:2019-08-20 04:14:33
【问题描述】:
我遇到了一个应用程序的问题,该应用程序被构建为作为 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>
【问题讨论】:
-
“请注意,此软件不会部署在 Play 商店中,而是构建为自定义 AOSP 构建的一部分,不供公众使用。” -- 我假设可以将预安装的应用程序设置为已经从停止状态中移出。如果您购买 Android 手机,并查看已安装应用程序列表,则有许多不是“系统服务”的预加载条目(例如,“Basic Daydreams”、“Certificate Installer”、“Face Unlock”) 、“Google 备份传输”、“Nfc 服务”,只是从我坐在这里的 Nexus 4 中挑选一些)。
-
这是一个很好的观点,我没有考虑过。该应用程序必须安装在 /system/app 下,以避免用户卸载它。我确实从源代码构建了整个系统,但是我还不知道在不间断状态下构建应用程序的最佳方法。我会做更多的研究!
-
是的,我还不够系统级的人知道你是怎么做到的。可能仅仅在系统分区上就足够了。
标签: java android android-service android-source android-framework