0

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.

Tuco
  • 902
  • 3
  • 18
  • 33
  • 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 (http://stackoverflow.com/questions/17409907/how-to-enable-and-disable-a-component). 2) Make an on boot receiver (http://stackoverflow.com/questions/5290141/android-broadcastreceiver-on-startup-keep-running-when-activity-is-in-backgrou). – Eugen Pechanec Oct 10 '16 at 21:22
  • Is my AutoStart boot receiver missing something? – Tuco Oct 10 '16 at 21:27
  • Why are you stopping the service right after spawning the thread? – Eugen Pechanec Oct 10 '16 at 21:39
  • NoDisplay activity has to `finish()` before `onCreate()` returns. – Eugen Pechanec Oct 10 '16 at 21:40

2 Answers2

1

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));
        }
    }
}
Community
  • 1
  • 1
Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
0

I think the problem is in your AutoStart class:

Intent i = new Intent(context, MainActivity.class);

Your packaging the intent with your MainActivity. Try changing it to AlphaService.

Karl Jamoralin
  • 1,240
  • 1
  • 14
  • 27
  • I've also tried removing the first 3 lines from my AutoStart class, so that it only starts the Service and it didn't work either. Is this what you are suggesting? – Tuco Oct 10 '16 at 21:34
  • Yes. Hmm. I implemented something similar, might be useful for you to check out: https://github.com/karljamoralin/internet-speed-meter – Karl Jamoralin Oct 10 '16 at 21:41