bashintosh
bashintosh

Reputation: 59

How to build an Android app as system service

I am facing a problem with an app that is built to run as Android service and should start on boot without any user interaction or existing activity.

From other sources, we know that this is basically not possible: http://commonsware.com/blog/2011/07/13/boot-completed-regression-confirmed.html

Currently for testing purposes the application has a very simple GUI and it registers a broadcast receiver as follows:

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);
        }
    }
}

This works great if the user launches the app at least once in order to allow the receiver to get ACTION_BOOT_COMPLETED.

The goal is to remove the GUI completely and yet have the application starting on boot without any action needed from the user. Note that this software will not be deployed on the Play Store but rather it's built to be part of a custom AOSP build not for public usage.

The only solution I found is to build the application as system service by adding it to the Android application framework.

See references:

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

However I am a bit confused about the advantages and disadvantages of this possibility and I hope someone can answer the following questions:

1) Does the app need to be built with the whole system (AOSP from source) and therefore it cannot be deployed as APK?

2) Is there any way to update the application afterwards (with an APK) once the system has been built?

3) Is it even possible or convenient to run the app this way (as system service) purely because it needs to start on boot and not because of other reasons (such as instantiating code from it etc.)?

The app itself is nothing special - it's a client/remote-server model that reports system statistics for research purposes.

EDIT

Adding the manifest for completeness:

<?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>

Upvotes: 3

Views: 6330

Answers (3)

Blundell
Blundell

Reputation: 76458

If you are modifying AOSP You can create a "persistent app"

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

This goes on your application tag in the manifest

<application
  persistent="true"
  ...
>

Whether or not the application should remain running at all times — "true" if it should, and "false" if not. The default value is "false". Applications should not normally set this flag; persistence mode is intended only for certain system applications.

It has to be a system app for it to work.

It will start on boot, any apps with this flag are started just before the BOOT_COMPLETED intent is fired from init.

Benefits being:

  • It'll cause the app to be kept alive by the ActivityManager
  • It'll be auto-magically restarted if the app dies
  • The lifecycle changes won't result in your app closing

Then you can spawn services, or do whatever you want really.

I'm sure it won't help 5 years later, but might help someone else :-)

Upvotes: 3

Endor
Endor

Reputation: 394

  1. In theory you should be able to deploy your apk separately but you may still have to modify the boot procedure to include your service to the list of programs/services to be launched.

  2. Yes you can. Just make sure you use the same key to sign your application package.

  3. This depends. Is it worth it to go down and modify the application framework just to make sure your service will function correctly in the event your user installs the app and then just leaves it? I guess you could include a release note somewhere to inform users that the app will not work until they run it at least once after installation.

UPDATE

  1. Maybe you can get your Launcher app to take care of it then.
  2. I think there is some confusion here. Pre-installed apps are not necessarily system apps. If your app does not require special permission, then it is just a pre-installed user app. Just think about that most phones ship with Facebook or Youtube and that those apps can be later updated.

Upvotes: 1

Kevin Lin
Kevin Lin

Reputation: 1

1.No need to create a system service, just a normal service which run in background,you don't need GUI so don't use activity but service. 3. If make it as a system service ,when error occurred ,the whole system will be reset.

Upvotes: 0

Related Questions