【问题标题】:Broadcast receiver not working when app is closed应用程序关闭时广播接收器不工作
【发布时间】:2022-02-14 20:25:24
【问题描述】:

所以我制作了两个不同的应用程序,一个发送广播,另一个接收广播并显示敬酒。但是,当我关闭接收器应用程序时,即使我在清单文件中定义了接收器,第二个应用程序也不再接收广播。

app1的MainActivity中的广播发送者。

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button b = (Button)findViewById(R.id.button2);
    b.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent();
            i.setAction("com.example.ali.rrr");
            i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
            sendBroadcast(i);
            Log.e("Broadcast","sent");
        }
    });
}

App 2 广播接收器:

public class MyReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // TODO: This method is called when the BroadcastReceiver is receiving
    // an Intent broadcast.
    Toast.makeText(context, "Broadcast has been recieved!", Toast.LENGTH_SHORT).show();
    Log.e("SUCCESS", "IN RECIEVER");
    //throw new UnsupportedOperationException("Not yet implemented");
}

App 2s 清单:

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <receiver
        android:name=".MyReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.example.ali.rrr" />
        </intent-filter>
    </receiver>

    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main"
        android:theme="@style/AppTheme.NoActionBar" />
    <activity
        android:name=".Main2Activity"
        android:label="@string/title_activity_main2"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

【问题讨论】:

  • 当你的应用被销毁时,你应该取消注册你的广播接收器,你可以使用服务而不是广播接收器。
  • 它在打开应用 2(接收器应用)时工作?
  • @MohitKacha 我试图让它作为广播接收器工作,即使应用程序关闭,清单中静态注册的接收器也应该工作。
  • @JdPrajapati 是的,当我在后台保持 App2 打开时它正在工作。
  • @kumail 你只能使用服务和接收者的组合来实现这一点。但是您的代码使用 Activity 进行广播,因此这是不可能的,因为 Activity 需要上下文,而 Activity 在后台时无法提供上下文

标签: java android android-intent broadcastreceiver


【解决方案1】:

在清单中静态注册我的 BroadcastReceiver (BR)、应用适当的意图过滤器、使用 JobIntentService(并在清单中注册)处理从我的 BR 调用的工作后,我仍然得到不一致的结果。

完成我上面列出的所有操作后,即使应用程序已关闭,您也应该能够发送 ADB 命令来激活您的广播并处理您的服务中的工作。这在某些时候对我有用,但不是所有时间。

This article 描述了对 BR 的限制。 “从 Android 3.1 开始,如果用户从未启动过相应的应用程序或用户通过 Android 菜单明确停止了应用程序,Android 系统默认将所有接收者排除在接收意图之外”(AKA 用户执行强制停止)

当我通过调试启动应用程序,然后在我的设备上将其滑动关闭时,我的 ADB 命令永远不会激活我的 BR。但是,在我的调试会话结束后,当我在我的设备上打开应用程序并将其关闭时,我可以通过 ADB 命令激活我的 BR。

这是因为当您调试应用程序,然后在设备上手动将其关闭时,Android 认为这是强制停止,因此为什么我的 BR 无法激活直到我重新打开设备上的应用,无需调试

在互联网上搜索了几个小时,但无法找到我的解决方案,所以我想我会在这里发布它,以防万一某个可怜的不幸的灵魂遇到与我相同的奇怪功能。

编码愉快:)

【讨论】:

  • 我刚刚注意到我正在调试应用程序。在我手动打开应用程序后,BR 可以正常工作。谢谢!
  • 在找到这个答案之前,我花了很多时间调试应用程序。非常感谢分享这个。否则我会浪费更多的时间! ;-)
  • 那么这个问题有什么解决办法吗?即使在应用程序被强制关闭后,我也想调用 BroadcastReceiver。
  • @shaby 不幸的是,我不知道 Android 操作系统会改变这种行为,并且认为他们不太可能会改变这种行为。从用户的角度考虑。如果你强制停止一个应用程序,当你没有重新启用该应用程序时,你不希望它随机执行(可能长时间运行)后台操作,对
【解决方案2】:

首先,您需要使用服务才能使此功能发挥作用。

在 Activity 中,您可以使用以下代码启动和停止服务。

// to start a service
Intent service = new Intent(context, MyBrodcastRecieverService.class);
context.startService(service);

// to Stop service
Intent service = new Intent(context, MyBrodcastRecieverService.class);
context.stopService(service);

那么你就可以使用下面的服务了

public class MyBrodcastRecieverService extends Service
{
    private static BroadcastReceiver br_ScreenOffReceiver;

    @Override
    public IBinder onBind(Intent arg0)
    {
        return null;
    }

    @Override
    public void onCreate()
    {
        registerScreenOffReceiver();
    }

    @Override
    public void onDestroy()
    {
        unregisterReceiver(br__ScreenOffReceiver);
        m_ScreenOffReceiver = null;
    }

    private void registerScreenOffReceiver()
    {
        br_ScreenOffReceiver = new BroadcastReceiver()
        {
            @Override
            public void onReceive(Context context, Intent intent)
            {
                Log.d(TAG, "ACTION_SCREEN_OFF");
                // do something, e.g. send Intent to main app
            }
        };
        
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
        registerReceiver(br_ScreenOffReceiver, filter);
    }
}

【讨论】:

  • 有什么办法只使用广播接收器吗?
  • 如果您在清单文件中将自己的 BroadcastReceiver 注册为接收者,它将始终被调用。
  • 如果您对我的回答感到满意,请您将其设为已接受,以便我也可以帮助其他人。
  • 没有必要为此使用Service
  • @SujithKs 我确实在 Manifest 中注册了它,但只有在打开应用程序时才会调用它。
【解决方案3】:

我最近遇到了这个问题。即使应用程序从模拟器和三星手机的后台删除,BroadcastReceiver 也能正常工作。但它无法在 Realme、Mi 等中国制造的手机上启动我的应用程序。在努力寻找解决此问题的方法时,我发现在应用程序详细信息页面中有电池优化设置,其中 自动启动 功能被禁用。在我启用它之后,该应用程序运行良好,并且 BroadcastReceiver 能够启动该应用程序。我无法找到以编程方式启用此设置的方法,但我找到了question,它帮助我将用户引导至该设置页面。

【讨论】:

    【解决方案4】:

    您可以通过以下解决方案;

    Activity.java

    Intent intent=new Intent(MainActivity.this,BroadcastService.class);
    startService(intent);
    

    BroadcastService.java

    public class BroadcastService extends Service {
    
    private static MusicIntentReceiver br_ScreenOffReceiver;
    
    @Override
    public IBinder onBind(Intent arg0)
    {
        return null;
    }
    
    @Override
    public void onCreate()
    {
        registerScreenOffReceiver();
    }
    
    @Override
    public void onDestroy()
    {
    
    }
    
    private void registerScreenOffReceiver()
    {
        br_ScreenOffReceiver = new MusicIntentReceiver()
        {
            @Override
            public void onReceive(Context context, Intent intent)
            {
                if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
                    int state = intent.getIntExtra("state", -1);
                    switch (state) {
                        case 0:
                            Log.e("AAAAAAAAAA", "Headset is unplugged");
                            break;
                        case 1:
                            Log.e("AAAAAAAAA", "Headset is plugged");
                            break;
                        default:
                            Log.e("AAAAAAAAAAAA", "I have no idea what the headset state is");
                    }
                }
            }
        };
        IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
        registerReceiver(br_ScreenOffReceiver, filter);
    }
    
    
    }
    

    菜单

    <service android:enabled="true" android:name=".BroadcastService" />
    

    【讨论】:

      【解决方案5】:

      试试这个方法..

      Intent i = new Intent();
      i.setAction("com.example.ali.rrr");
      i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
      i.setComponent(  
              new ComponentName("PackageNameApp2","PackageNameApp2.MainActivity"));  
      sendBroadcast(i);
      

      【讨论】:

      • 我改变了动作,你现在可以试试吗?
      • 在您的清单中,您添加了另一个接收器。错误...将 MyReceiver6 更改为 MyReceiver
      • 不幸的是它仍然是同一个问题
      猜你喜欢
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多