BroadcastReceiver works only after first execution of adb shell

1.8k Views Asked by At

I tried many different examples, and after some (long) time, I finally managed (almost) to receive logs from BroadcastReceiver, after that notifications (via service). Still, problem persists.

When I install apk, or build it and run it on usb, BroadcastReceiver doesn't receive intent. I tried to manually run application dozen of times, then to restart (power on/off) my phone - nothing. After that, I tried to debug it with adb shell:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -n com.myapp.example/.BootCompletedReceiver

And, voila! It worked. I checked with reboot - it worked! After that, I reinstaled application, and again - didn't work. After I tried with adb shell - again, everything is working. Seams like it should work, but only after I run adb shell command from above, for the first time.

I didn't try with AVD (it's too slow on my machine), just with my HTC ONE (I also checked for HTC ONE issues, knowing that it was a problem with some versions of HTC phones - without any help).

This is my manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.example" >

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppThemeWhiteActionBar" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"

        android:screenOrientation="portrait"
        android:theme="@style/AppThemeWhite" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    ...
    <receiver android:name=".BootCompletedReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>
    <receiver android:name=".util.AlarmReceiver"/>
    <service android:name=".NotifyingDailyService" >
    </service>
</application>

And those are BootCompletedReceiver and NotifyingDailyService (almost same as from many examples here):

public class BootCompletedReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent arg1) {
    Log.w("boot_broadcast_poc", "starting service...");
    context.startService(new Intent(context, NotifyingDailyService.class));
}

}

public class NotifyingDailyService extends Service {

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public int onStartCommand(Intent pIntent, int flags, int startId) {
    NotificationManager mNotificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    Notification.Builder builder = new Notification.Builder(this);
    builder.setSmallIcon(R.drawable.ic_launcher);
    builder.setContentTitle(getString(R.string.random_string));
    builder.setContentText(getString(R.string.random_string));
    builder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS);
    mNotificationManager.notify(12345, builder.build());
    return super.onStartCommand(pIntent, flags, startId);
}
}
2

There are 2 best solutions below

2
On

Installation is not sufficient for your app to start listening to the BOOT_COMPLETED broadcast. The application needs to be started once, i.e. your Custom app class or entry Activity needs to be started once for the BroadcastReceiver to be able to hear the BOOT_COMPLETED system broadcast. This behaviour is by design, for security reasons.

You can read more about it on this blog by CommonsWare.

1
On

There is an option to restrict Startup Applications in Android. I guess that your application is restricted too. Go to Settings->Personal->Startup Manager. There you can allow or restrict boot_completed broadcast reception.