跨应用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
相关产品推荐
相关产品推荐

