当前位置: 动力学知识库 > 问答 > 编程问答 >

Only catching BOOT_COMPLETED broadcast if application already running (Android emulator, Lollipop)

问题描述:

Please help me figure out why my app isn't receiving the BOOT_COMPLETED broadcast message unless my app is already running.

My goal is for my application to automatically start up as soon as the device is finished booting (start my GUI). My approach is to catch the BOOT_COMPLETED broadcast and then start my main activity from inside the onReceive() method.

The problem is my app only catches the BOOT_COMPLETED broadcast if it's already running. What I'm expecting is the OS to start my applications process and call the onReceive() entry point when the BOOT_COMPLETED broadcast is sent. Can someone help me figure out where I've gone wrong? I'm thinking my error is likely in my AndroidManifest.xml file,but I'm not sure what I'm missing (my first ever Android project).

I'm using the Android Studio emulator, Lollipop on a Nexus 5. The emulator is set to "Do not launch activity" on boot-up since this is how real hardware would work.

I'm sending the broadcast to the emulator like this, and I do catch it if my app is already running:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.example.matt.catchbootcompletebroadcast

My guess is my problem is in my manifest file, here it is (AndroidManifest.xml):

 <?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.matt.catchbootcompletebroadcast" android:installLocation="internalOnly">

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

<application

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

<receiver android:name=".BootCompleteReceiver" android:enabled="true" android:exported="true">

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED"/>

</intent-filter>

</receiver>

<activity

android:name=".MainActivity"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

</manifest>

And here is my onReceive class:

 package com.example.matt.catchbootcompletebroadcast;

import android.content.BroadcastReceiver;

import android.content.Intent;

import android.content.Context;

import android.util.Log;

/**

* Created by matt on 8/20/2015.

* To send broadcast: adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.example.matt.catchbootcompletebroadcast

*/

public class BootCompleteReceiver extends BroadcastReceiver

{

@Override public void onReceive(Context context, Intent intent)

{

Log.d("ReceivedABroadcast", "Received A Broadcast");

if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))

{

Log.d("ReceivedBootCompleted", "Received BOOT_COMPLETED broadcast");

}

// Open the main activity to this application

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

context.startActivity(startApp);

}

}

All tips are greatly appreciated!

网友答案:

Some ideas:

Try launching it on an android device. If that doesn't work try this: in the Android Manifest file for the <receiver> tag remove the enabled and exported part. And inside the Receiver class remove the if statement.

Reason: Because you have already filtered the intents received by the broadcast receiver the if statement is pretty much useless. If all this doesn't work this may help you: Android declared that the following actions have to be written programmatically only. And I beleive that list contains intent.action.BOOT_COMPLETED so maybe it will work if you declare the receiver programmatically. To me it looks right. But I suppose these ideas may be worth a shot.

网友答案:

To summarize all the comments above, in addition the code in my first post, the solution was:

(1) I could only get my app to receive BOOT_COMPLETED broadcast on boot-up with real hardware. Maybe it's possible with the emulator, but the emulator didn't work for me.
(2) Open the application once manually before rebooting. After this, the application will automatically start after every boot.

(3) My onReceive() had to include the FLAG_ACTIVITY_NEW_TASK flag or the app would crash when it tried to start. My onReceive() ended up looking like this:

    @Override public void onReceive(Context context, Intent intent)
    {
        Log.d("ReceivedABroadcast", "Received A Broadcast");
        if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
        {
            Log.d("ReceivedBootCompleted", "Received BOOT_COMPLETED broadcast");
        }
        // Open the main activity to this application
        Intent startApp = new Intent(context, MainActivity.class);
        startApp.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
        startApp.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);  
        context.startActivity(startApp);
    }

Thanks to everyone for the help!!

分享给朋友:
您可能感兴趣的文章:
随机阅读: