You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨应用Broadcast Receiver传递字符串失败问题排查

我帮你排查了下代码里的问题,主要是发送端的Intent配置和接收端的广播匹配逻辑不统一导致的,下面是具体的修正步骤:

一、修正发送端(send App)的Intent配置问题

你的发送代码里同时设置了多个冲突的Intent属性,比如先初始化了Intent("Updated"),又调用setAction(Intent.ACTION_SEND),还设置了Component,这些混乱的配置导致接收端无法匹配到广播。修改后的sendMsg方法如下:

private void sendMsg(){
    final TextView msg = (TextView) findViewById(R.id.sendText);
    Button snd = (Button)findViewById(R.id.sendButton);
    snd.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String inputText = msg.getText().toString().trim();
            if(!inputText.isEmpty()){
                // 直接用接收端定义的action来初始化Intent
                Intent intent = new Intent("action");
                intent.putExtra("TEXT", inputText);
                // 指定Component可以精准定位接收的广播接收器,避免其他App拦截
                intent.setComponent(new ComponentName("com.example.rec","com.example.rec.broadcastReciver"));
                intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
                getApplicationContext().sendBroadcast(intent);
            }else{
                Toast.makeText(getApplicationContext(), "Write text that You want to broadcast!", Toast.LENGTH_LONG).show();
            }
        }
    });
}

关键修改点:

  • 直接用接收端Manifest里定义的"action"作为Intent的Action,去掉了多余的setAction(Intent.ACTION_SEND)和setType("text/plain")(广播不需要设置MIME类型)
  • 保留setComponent可以精准指定接收方,绕开Android高版本对静态广播的限制

二、修正接收端(rec App)的广播注册逻辑

你的接收端同时做了静态注册(Manifest里)和动态注册(代码里),重复注册没必要,推荐二选一:

选项1:保留静态注册(推荐,App后台也能接收)

只需要调整广播接收器的判断逻辑,确保和发送端的Action匹配,同时避免空指针异常:

public class broadcastReciver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null) {
            String sIntentAction = intent.getAction();
            // 这里要和发送端的Intent Action完全一致
            if ("action".equals(sIntentAction)) {
                String data = intent.getStringExtra("TEXT");
                // 先判空再处理,避免崩溃
                if(data != null){
                    Toast.makeText(context, data.trim(), Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(context,"Received empty data",Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(context,"Wrong action received",Toast.LENGTH_SHORT).show();
            }
        }
    }
}

同时删掉MainActivity里的动态注册代码:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 删掉zoviBroadCast(); 这一行
    }
}

选项2:使用动态注册(仅App前台时接收)

如果只想在App前台接收广播,就删除Manifest里的<receiver>标签,然后修改MainActivity的动态注册逻辑,记得手动注销接收器:

public class MainActivity extends AppCompatActivity {
    private broadcastReciver brcv;

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

    private void zoviBroadCast(){
        brcv = new broadcastReciver();
        IntentFilter filter = new IntentFilter("action");
        registerReceiver(brcv, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 动态注册的接收器必须手动注销,否则会内存泄漏
        if(brcv != null){
            unregisterReceiver(brcv);
        }
    }
}

三、额外注意事项

  • 确保两个App的包名和类名完全匹配:发送端里的ComponentName("com.example.rec","com.example.rec.broadcastReciver")要和接收端的实际包名、接收器类名一致(注意类名大小写)
  • Android 12及以上版本对静态广播限制较多,用setComponent指定接收器可以避开这个限制
  • 测试时确保接收端App至少启动过一次(静态广播需要App首次启动激活,你加的FLAG_INCLUDE_STOPPED_PACKAGES可以解决未启动的问题)

这样修改后,点击发送端的按钮,接收端就能正常弹出Toast显示传递的字符串了。

内容的提问来源于stack exchange,提问作者TheName

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:58:12