Search code examples
androidandroid-activityandroid-serviceandroid-manifestandroid-broadcastreceiver

Getting Android apk to run after installing (reboot)?


Hello I'm trying to get my Android application (it has no UI, its just supposed to be a background service) to run when it's installed or at least when the device is rebooted. Here's my work so far, anyone have any ideas why it won't start when install the apk and reboot the device?

Android Manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="gitlab.project" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="@string/app_name" >
    <activity
        android:name="gitlab.project.MainActivity"
        android:label="@string/app_name"
        android:theme = "@android:style/Theme.NoDisplay">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </activity>

    <receiver
            android:name="gitlab.project.AutoStart"
            android:enabled="true"
            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>
    <service android:name="gitlab.project.AlphaService"
             android:enabled="true"
             android:exported="true" />
</application>
</manifest>

MainActivity:

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = new Intent(this, AlphaService.class);
    this.startService(intent);
}
}

AlphaService:

public class AlphaService extends Service implements
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private Profiler profiler;
private AlphaApiClient alphaApiClient;
private GoogleApiClient googleApiClient;
private int batteryHealth;

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
    batteryHealth = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 2);

    if (googleApiClient == null) {
        googleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    googleApiClient.connect();

    return Service.START_STICKY;
}

@Override
public void onConnected(Bundle connectionHint) {
    ProcService procService = new DefaultProcService();
    SystemInformationService systemInformationService = new SystemInformationService(googleApiClient, getContentResolver());
    profiler = new Profiler(procService, systemInformationService);
    alphaApiClient = new AlphaApiClient(getString(R.string.USERNAME), getString(R.string.PASSWORD));
    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            Log.d("Alpha service", "Profiling system info...");
            AndroidSystem androidSystem = profiler.profile(batteryHealth);
            String url = getString(R.string.API_URL);
            alphaApiClient.doPostRequest(androidSystem, url);
        }
    });
    thread.start();

    //Stop service once it finishes its task
    stopSelf();
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
public void onDestroy() {
    AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
    alarm.set(
            AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis() + (4000 * 60 * 60),
            PendingIntent.getService(this, 0, new Intent(this, AlphaService.class), 0)
    );
}
}

AutoStart (Broadcast Receiver):

public class AutoStart extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Intent i = new Intent(context, MainActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);

    context.startService(new Intent(context, AlphaService.class));
}
}

Any ideas why my background service won't run? I'm able to get it to run using adb, but not when trying to install manually from the phone/tablet. Any help is greatly appreciated.


Solution

  • The app won't run any services or broadcast receivers unless it's in started state. It's in started state after it's been run from launcher or via ADB.

    1) Make an activity which will a) start your service and b) disable itself (How to enable and disable a component?).

    2) Make an on boot receiver (Android BroadcastReceiver on startup - keep running when Activity is in Background).


    Your on boot receiver is already starting the service, it does not need to start the activity. The activity only needs to be launched once after install. Here's the correct setup.

    AndroidManifest.xml

    <activity
        android:name="gitlab.project.MainActivity"
        android:theme = "@android:style/Theme.NoDisplay">
        <intent-filter>
            <!-- Activity needs to show up in launcher. -->
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
    <receiver
            android:name="gitlab.project.AutoStart"
            android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    

    AutoStart.java

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