Android 我如何确定应用程序运行时是否调用了广播接收器,而不是应用程序处于休眠状态或处于后台时?

Android 我如何确定应用程序运行时是否调用了广播接收器,而不是应用程序处于休眠状态或处于后台时?,android,Android,我在舱单上注册了一个BroadcatReceiver,用于在电话铃响时静音。我希望广播听众在3种情况下表现不同: 如果在用户使用它时调用它 如果在按下home(主页)按钮后在后台调用它 如果它是在退出请求/onBackButtonPressed()后在后台调用的 我希望这种识别能力,因为我认为广播接收器会自动地以隐藏的方式启动发送通知的服务。如果用户在明确离开应用程序后收到此通知,则会很烦人 以下是我的一些尝试 public class MyBroadcastReceiver extends

我在舱单上注册了一个BroadcatReceiver,用于在电话铃响时静音。我希望广播听众在3种情况下表现不同:

  • 如果在用户使用它时调用它
  • 如果在按下home(主页)按钮后在后台调用它
  • 如果它是在退出请求/onBackButtonPressed()后在后台调用的
  • 我希望这种识别能力,因为我认为广播接收器会自动地以隐藏的方式启动发送通知的服务。如果用户在明确离开应用程序后收到此通知,则会很烦人

    以下是我的一些尝试

      public class MyBroadcastReceiver extends BroadcastReceiver {
        //private final static Global global = Global.getInstance();
        private static final String TAG = MyBroadcastReceiver.class.getName();
    
       @Override
       public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "broadcast recieved");
        //Log.d(TAG, "context package name is: " + context.getPackageName());
    
        Bundle extras = intent.getExtras();
    
        if (extras != null) {
            String state = extras.getString(TelephonyManager.EXTRA_STATE);
            Log.d(TAG, "State : " + state);
    
            if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) 
            {
    
                Log.d(TAG, "context package name: " + context.getPackageName());
    
                Global global = Global.getInstance();
                global.shutUp();
    
                Log.d(TAG, "global package name: " + global.getPackageName());
    
                String phoneNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                Log.d(TAG, "Calling number: " + phoneNumber);
    
    
    
    
    
                //TODO try to condition this if receiver activated from outside the application 
                if(isAppOnForeground(context))
                {
                    Log.d(TAG, "app is in forgeround");
                }
                else
                {
                    Log.d(TAG, "app is not in forgeround");
                }
    
                if(isMyServiceRunning(context))
                {
                    Log.d(TAG, "service running");
                }
                else
                {
                    Log.d(TAG, "service isn't running");
                }
    
    
                //global.stopService(new Intent(ReturnService.class.getName()));
                //Log.d(TAG, "requested return service stoped");
    
            }
        }
    
        //I think this return is imperative so that return service isn't invoked 
        return;
    }
    
    
    private boolean isAppOnForeground(Context context) 
    {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
    
        if (appProcesses == null) 
        {
          return false;
        }
    
        final String packageName = context.getPackageName();
    
        for (RunningAppProcessInfo appProcess : appProcesses) 
        {
          if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) 
          {
            return true;
          }
        }
        return false;
      }
    
    
    private boolean isMyServiceRunning(Context context) 
    {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) 
        {
            if (ReturnService.class.getName().equals(service.service.getClassName())) 
            {
                return true;
            }
        }
        return false;
    }
    
    公共类MyBroadcastReceiver扩展了BroadcastReceiver{
    //private final static Global=Global.getInstance();
    私有静态最终字符串标记=MyBroadcastReceiver.class.getName();
    @凌驾
    公共void onReceive(上下文、意图){
    Log.d(标签“接收广播”);
    //d(标记,“上下文包名称为:”+context.getPackageName());
    Bundle extras=intent.getExtras();
    如果(附加值!=null){
    字符串状态=extras.getString(TelephonyManager.EXTRA_状态);
    Log.d(标签“状态:+状态”);
    if(state.equals(TelephonyManager.EXTRA_state_RINGING))
    {
    Log.d(标记“context包名:”+context.getPackageName());
    Global=Global.getInstance();
    global.shutUp();
    Log.d(标记“全局包名称:”+global.getPackageName());
    String phoneNumber=extras.getString(TelephonyManager.EXTRA\u传入\u号码);
    Log.d(标签,“呼叫号码:”+电话号码);
    //TODO如果接收器从应用程序外部激活,请尝试调节此状态
    if(isAppOn前台(上下文))
    {
    Log.d(标记“应用程序正在伪造”);
    }
    其他的
    {
    Log.d(标记“应用程序不在伪造中”);
    }
    if(isMyServiceRunning(上下文))
    {
    Log.d(标签“服务运行”);
    }
    其他的
    {
    Log.d(标记“服务未运行”);
    }
    //global.stopService(新意图(ReturnService.class.getName());
    //Log.d(标记“请求的返回服务已停止”);
    }
    }
    //我认为这个返回是必需的,这样就不会调用返回服务
    返回;
    }
    专用布尔值isAppOnForeground(上下文)
    {
    ActivityManager ActivityManager=(ActivityManager)context.getSystemService(context.ACTIVITY_服务);
    List appProcesses=activityManager.getRunningAppProcesses();
    if(appprocesss==null)
    {
    返回false;
    }
    最后一个字符串packageName=context.getPackageName();
    for(运行AppProcessInfo appProcess:AppProcesss)
    {
    if(appProcess.importance==RunningAppProcessInfo.importance\u前台和&appProcess.processName.equals(packageName))
    {
    返回true;
    }
    }
    返回false;
    }
    专用布尔值isMyServiceRunning(上下文)
    {
    ActivityManager=(ActivityManager)context.getSystemService(context.ACTIVITY_服务);
    for(RunningServiceInfo服务:manager.getRunningServices(Integer.MAX_值))
    {
    if(ReturnService.class.getName().equals(service.service.getClassName()))
    {
    返回true;
    }
    }
    返回false;
    }
    

    }

    我认为在您的情况下,一个更简单的解决方案是在创建启动器活动时设置一个全局标志,在销毁启动器活动时关闭。如果您的应用程序在广播发送到接收器时未打开,则该标志将关闭,然后您可以相应地操作。

    如果您的应用程序是活动(我不认为它是例如InputMethodService),您可以覆盖活动方法onPause()和onResume()。如果您在其中一个中将某个静态标志设置为true,并在另一个中清除该标志,则该标志将告诉您最后一个活动是否在屏幕上。

    您说“应用程序处于休眠状态或处于后台”。你的应用程序是什么意思,一项活动,一项服务,或者是活动和服务的组合?我的意思是,当应用程序被OSI激活时,用户按下了“主页”按钮并正在执行其他操作。我试图知道广播接收器是在用户使用应用程序时调用的,还是在他按下“主页”按钮并执行其他操作后调用的。您可以检测“后退”按钮还是“主页”按钮按下按钮并在那里挂上国旗。我可以问一下你为什么需要这个功能吗?根据你的建议,我必须从每个活动的onBackPressed()中检测并设置标志,前提是它不影响片段等内部活动功能,并且是整个应用程序的根活动。为每个活动执行此操作很长,并且容易出现错误,并且会创建重复的代码。我将尝试编辑我的问题以使其更清晰。但情况并非总是如此,因为我的所有活动都必须这样做,因为“主页”按钮会像“后退”按钮或普通导航按钮一样调用“暂停”。当你按下“主页”按钮时,应用程序将进入后台。另外,如果您离开一个活动并导航到另一个活动,则可以在onPause()和onResume()之间调用onReceive()。我不确定在这个过渡状态下的应用程序是否处于后台是不正确的。你建议我在所有的活动中实现OnRealView(),并在其中设置静态标志吗?每次用户打开屏幕时,活动就会被破坏和创建,它们的生命周期与视图层次结构的生存期相匹配,但我不认为它符合你的生命周期。。。不管是什么。谷歌文档建议使用一项服务。至于国旗,