1

I have a basic Android application that is supposed to reboot the phone continuously a set number of times. In order to do this, I need the application to be started upon phone startup. In order to that, I essentially followed the instructions found here, adding the permissions to the manifest and creating a BroadcastReceiver class that starts the activity. Here is some of my relevant code:

public class StartMyServiceAtBootReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    System.out.println("StartMyServiceAtBootReceiver called.");

    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
        // Intent activityIntent = new Intent("com.example.rebooter.MainActivity");
        Intent activityIntent = new Intent(context,MainActivity.class);
        activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(activityIntent);
    }
}

}

From the manifest file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rebooter"
android:versionCode="1"
android:versionName="1.0" >

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

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="15" />

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

    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main" >
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </activity>

    <service
        android:name=".RebootManager"
        android:label="Reboot Manager" >
        <action android:name="com.example.rebooter.RebootManager" />
    </service>

    <receiver android:name=".StartMyServiceAtBootReceiver"
        android:enabled="true"
        android:exported="true"
        android:label="StartMyServiceAtBootReceiver" >
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </receiver>       

</application>

In the Eclipse emulator, the application appears to be working properly. That is, though my emulator isn't rooted and the phone doesn't execute the reboot commands correctly, I do see that, upon startup, the correct activity is started.

Now, when I'm trying it on a particular system running Android 4.0.4, everything in the application is working properly EXCEPT boot upon startup. Any ideas?

I tried to eliminate the possibility of any hardware problems (since I'm not using a commercially-released phone) by installing another application that boots upon startup and confirming that it does indeed boot upon startup, and it does indeed show up under running apps as a cached process after startup.

I would appreciate any help. Let me know if you need any additional information.

Community
  • 1
  • 1
TSM
  • 582
  • 2
  • 10
  • 25

1 Answers1

1

There are a number of issues here.

First, you neglected to post StartMyServiceAtBootReceiver, the component you are expecting to get control at boot time, so we cannot comment on whether there are any particular problems with it.

Second, unless something has explicitly executed one of your components (e.g., the user launched MainActivity from the home screen), StartMyServiceAtBootReceiver will never be invoked, on Android 3.1+. Make sure you run your activity before trying a reboot, and see if that helps.

Third, you implemented a constructor on StartupManager, which is a bad idea. Please move this logic to onCreate().

Fourth, your code will likely crash in that constructor, as getApplication() will not return a valid value at this point in the code, particularly since you failed to chain to the superclass' constructor. Again, moving this code to onCreate() will help here.

Fifth, starting an activity from onCreate() of a service (let alone its constructor) is very unusual and may not be appreciated by the user. Moreover, if that service is not doing anything else, you could just as easily start that activity from StartMyServiceAtBootReceiver and skip StartupManager entirely.

Sixth, you have <intent-filter> elements on your services, as if you are expecting third party developers to invoke those services. If that is the case, fine. If not, please remove the <intent-filter> elements and use explicit Intents within the rest of your app code to refer to them (e.g., new Intent(this, StartupManager.class)), for better security. Or, add android:exported="false" to those services, though that is automatic if you remove the <intent-filter> elements.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Sorry about that, I didn't realize how convoluted I let it get when I was trying to hack together a solution without knowing what I was doing. I've removed the StartupManager completely, because it did nothing but start another activity anyway, and I made several other changes that are all reflected in the OP. Does this look appropriate? Or do I need to start a service that in turn starts the activity? – TSM Aug 03 '12 at 21:47
  • Another note, the new version I've posted in the OP is not working. Even the startmyserviceatboot receiver is posting nothing in the log at runtime. I also see a red console message "no launcher activity found!" – TSM Aug 03 '12 at 22:01
  • @TSM: "Does this look appropriate?" -- unless you are reusing `StartMyServiceAtBootReceiver` for other purposes, you could skip the `if()` check. And that class might need a different name now... :-) Starting an activity at boot time is very very odd -- you might be better served just making your activity be the home screen, which means you could dump all the `BOOT_COMPLETED` stuff. And, you still need the user to run the activity manually (or something equivalent) before your `BOOT_COMPLETED` receiver will respond. – CommonsWare Aug 03 '12 at 22:02
  • @TSM: "I also see a red console message "no launcher activity found!"" -- make sure you are running this project. Sometimes in Eclipse, you accidentally run some different project. Here is a sample of a simple boot receiver: https://github.com/commonsguy/cw-omnibus/tree/master/SystemEvents/OnBoot – CommonsWare Aug 03 '12 at 22:03
  • Thanks a lot for the help. I have another question. As far as the "you still need the user to run the activity manually" part, do you mean, upon each reboot, I need to have them do this? What I'm looking to accomplish is that the user opens the application for the first time, presses a button that would let them reboot the device 100 times in a row, and for it to reboot the phone 100 times in a row without manual labor on the user side. – TSM Aug 03 '12 at 22:05
  • @TSM: "upon each reboot, I need to have them do this?" -- no, it's a one-time thing, unless they Force Close you from Settings (in which case, they have to manually launch you again). With regards to reboot-a-rama, um, whatever floats your boat, I suppose... :-) – CommonsWare Aug 03 '12 at 22:23
  • Thanks for the help. I'll try testing it on an actual board again as soon as I can, and hopefully it'll work. The application is intended for warm reboot testing. :-) – TSM Aug 03 '12 at 23:21
  • So another update: I've tried it on an actual mobile platform again, and the application isn't booting on startup. I'm not quite sure why, since it appears to be working perfectly in the emulator. Any ideas as to what might be causing this? – TSM Aug 07 '12 at 16:58
  • @TSM: It is conceivable that your activity is coming up, but being replaced in the foreground by the home screen. There is no guarantee about the timing of when the `BOOT_COMPLETED` broadcast is sent out. – CommonsWare Aug 07 '12 at 17:05