Android: Broadcast receiver won't receive boot

2019-07-17 07:48发布

问题:

I've a class MyBroadcastReceiver that is registered to start at boot up. The manifest is below. I am running this via eclipse on a Android Motorola Xoom wifi only tablet - which is Android 3.2, API level 13 (from the dev.android site).

I have googled for this and tried a few things:

  • put android:exported="true"

  • used android:installLocation="internalOnly" to make sure it doesn't install on the SD card

  • after installing on the device, I ran the app a couple of times before testing the bootup (as some links said Android 3.x onwards won't immediately start sending boot events to the app unless user has manually initiated it at least once)

However even now the broadcast receiver doesn't seem to run when the device boots up (based on logcat).

Here is my manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.mypack"
      android:versionCode="1"
      android:versionName="1.0"
      android:installLocation="internalOnly">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

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

    <application android:icon="@drawable/icon" android:label="@string/app_name">
      <activity android:name=".MainCamApp" 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=".UploaderService" />

     <receiver android:name=".MyBroadcastReceiver"  android:enabled="true" android:exported="true">
      <intent-filter>
          <action android:name="android.intent.action.BOOT_COMPLETED"/>
      </intent-filter>
     </receiver>

    </application>
</manifest>

Code for broadcast receiver -

import java.util.Calendar;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyBroadcastReceiverX extends BroadcastReceiver {
    private String TAG = "Broadcast Receiver:";
    AlarmManager alarm;

    @Override
    public void onReceive(Context arg0, Intent arg1) {
        Log.i(TAG, "Entered onReceive.");
        alarm = (AlarmManager) arg0.getSystemService(Context.ALARM_SERVICE);
        Intent intentUploadService = new Intent (arg0, UploaderService.class);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND, 10);

        PendingIntent pi = PendingIntent.getBroadcast(arg0, 0, intentUploadService , 0);
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5000, pi);
        Log.i(TAG, "Alarm set. Exiting onReceive.");

        Intent myIntent = new Intent(arg0, UploaderService.class);
        arg0.startService(myIntent);
    }

}

Seems to be working now.. final manifest below if it helps -

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example"
      android:versionCode="1"
      android:versionName="1.0"
      android:installLocation="internalOnly"
      android:permission="android.permission.RECEIVE_BOOT_COMPLETED">

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

    <uses-sdk android:minSdkVersion="8" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
      <activity android:name=".MainCamApp" 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=".UploaderService" />

    <receiver android:name=".MyBroadcastReceiverX"  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"/> 
          </action>
      </intent-filter>
    </receiver>

    </application>
</manifest>

回答1:

Try the following:

<receiver android:name=".MyBroadcastReceiverX"  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"/> 
      </action>
  </intent-filter>
</receiver>

You also have incorrect class name specified in manifest - it should be MyBroadcastReceiverX rather then MyBroadcastReceiver



回答2:

You need to write code after receiving the android.intent.action.BOOT_COMPLETED intent.

try this.

@Override
public void onReceive(Context context, Intent intent) {
    Log.d("TEST", intent.getAction());
    if (intent.getAction().equalsIgnoreCase(
            "android.intent.action.BOOT_COMPLETED")) {
         Log.i(TAG, "Entered onReceive.");
    alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intentUploadService = new Intent (context, UploaderService.class);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.SECOND, 10);

    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intentUploadService , 0);
    alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5000, pi);
    Log.i(TAG, "Alarm set. Exiting onReceive.");

    //no need to initialize intent twice
    // Intent myIntent = new Intent(context, UploaderService.class);

 context.startService(intentUploadService );
    }

}