只有在应用程序已经运行的情况下(Android emulator、棒棒糖)才能捕获启动完成的广播

只有在应用程序已经运行的情况下(Android emulator、棒棒糖)才能捕获启动完成的广播,android,broadcast,boot,Android,Broadcast,Boot,请帮助我找出为什么我的应用程序没有收到BOOT_COMPLETED广播消息,除非我的应用程序已经运行 我的目标是让我的应用程序在设备完成引导后自动启动(启动我的GUI)。我的方法是捕获BOOT_完成的广播,然后从onReceive()方法内部开始我的主要活动 问题是,我的应用程序只有在启动时才能捕捉到已完成的广播。我期望的是,当启动完成的广播发送时,操作系统启动我的应用程序进程并调用onReceive()入口点。有人能帮我找出哪里出了问题吗?我想我的错误可能在我的AndroidManifest.

请帮助我找出为什么我的应用程序没有收到BOOT_COMPLETED广播消息,除非我的应用程序已经运行

我的目标是让我的应用程序在设备完成引导后自动启动(启动我的GUI)。我的方法是捕获BOOT_完成的广播,然后从onReceive()方法内部开始我的主要活动

问题是,我的应用程序只有在启动时才能捕捉到已完成的广播。我期望的是,当启动完成的广播发送时,操作系统启动我的应用程序进程并调用onReceive()入口点。有人能帮我找出哪里出了问题吗?我想我的错误可能在我的AndroidManifest.xml文件中,但我不确定我遗漏了什么(我的第一个Android项目)

我正在使用Android Studio模拟器,Nexus5上的棒棒糖。模拟器在启动时设置为“不启动活动”,因为这是实际硬件的工作方式

我像这样将广播发送到模拟器,如果我的应用程序已经在运行,我会捕获广播:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.example.matt.catchbootcompletebroadcast
我猜我的问题在清单文件中,这里是(AndroidManifest.xml):

非常感谢所有提示

一些想法:

尝试在android设备上启动它。如果不起作用,请尝试以下操作:在Android清单文件中的
标记中删除
已启用的
导出的
部分。并在Receiver类中删除
if
语句


原因:因为您已经过滤了广播接收器接收到的意图,
if
语句几乎毫无用处。如果所有这些都不起作用,这可能会对您有所帮助:Android声明以下操作必须仅以编程方式编写。我相信该列表包含
intent.action.BOOT\u COMPLETED
,因此如果您以编程方式声明接收器,它可能会起作用。在我看来,这是正确的。但我想这些想法可能值得一试

总结以上所有评论,除了我第一篇文章中的代码,解决方案是:

(1) 我只能让我的应用程序在使用真正的硬件启动时接收BOOT_COMPLETED广播。也许可以使用模拟器,但模拟器不适合我。
(2) 重新启动前手动打开应用程序一次。在此之后,应用程序将在每次启动后自动启动

(3) 我的onReceive()必须包含标志\u ACTIVITY\u NEW\u TASK标志,否则应用程序在尝试启动时会崩溃。我的onReceive()最终看起来像这样:

    @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);
    }

谢谢大家的帮助

你的应用程序在安装后是否至少被用户启动过一次?这对我来说似乎完全正确。试着在android设备上启动它。你在真正的设备上尝试过吗?谢谢大家@Karakuri,是的,它运行应用程序,然后关闭模拟器,然后通过android studio重新启动。但这可能会自动重新安装应用程序,我猜这会将其重置为以前从未运行过。模拟器设置为在重新启动时不清除用户数据。我试图通过“adb重新启动”重新启动仿真器,但一旦操作系统关闭,仿真器就会挂在黑屏上。@AnggrayudiH和KISHORE-我还没有在真正的硬件上尝试过。我唯一真正的设备是我的锁着的手机,我会试着弄到一个真正的设备并试一试。谢谢你的提示!谢谢,我会尝试使用真正的硬件并试一试。好的,也可以尝试其他想法,如果你想给我发送编译过的apk,我有一个设备。如果你愿意,我可以测试一下。非常感谢你的帮助!我可以通过此网站向您发送apk吗,或者我需要将其托管在第三方网站上并共享链接吗?很可能您必须使用第三方应用程序,如Google drive或mediafire,因为我认为您无法通过堆栈溢出本身直接发布apk。我已经获得了一些真正的硬件来测试这一点,我将报告我的结果,一旦我弄清楚如何将其安装在那里。再次感谢您愿意为我测试,我很感激!为了澄清您的体验:(2)应用程序必须(由用户)运行一次,以便其任何接收者接收任何事件。这是从KitKat开始设计的!(3) 如果没有新的_任务,操作系统希望新的活动遵循现有的活动,否则会使你的应用程序崩溃!
    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);
    }

}
    @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);
    }