【问题标题】:How to Send BroadCast from one app to another app如何将广播从一个应用程序发送到另一个应用程序
【发布时间】:2016-02-03 05:33:57
【问题描述】:

我有 App A 和 App B。在 App A 中,我想向 App B 发送广播。 这是应用 A 的代码:

final Intent intent = new Intent();
intent.setAction("com.pkg.perform.Ruby");
intent.putExtra("KeyName", "code1id");
intent.setComponent(new ComponentName("com.pkg.AppB", "com.pkg.AppB.MainActivity"));
sendBroadcast(intent);

在 App B 中 - 在 MainActivity 中,我有 MyBroadCastReceiver 类。

public class MainActivity extends Activity {
    private MyBroadcastReceiver MyReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Receive broadcast from External App
        IntentFilter intentFilter = new IntentFilter("com.pkg.perform.Ruby");
        MyReceiver = new MyBroadcastReceiver();
        if(intentFilter != null)
        {
            registerReceiver(MyReceiver, intentFilter);
        }
    }

    public class MyBroadcastReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(MainActivity.this, "Data Received from External App", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(MyReceiver != null)
            unregisterReceiver(MyReceiver);
    }
}

我收到错误 - 接收方未注册

【问题讨论】:

  • 两个应用程序都在运行?
  • 是的,两个应用程序都在运行
  • 我已经阅读了这些链接
  • 应用 B 是在 XML 中声明广播接收器还是通过代码注册/删除它?如果是第二个,那么很可能是应用 B 删除了接收器,因为它的 Activity 已被销毁。

标签: android broadcastreceiver broadcast


【解决方案1】:

MyReceiver 是类而不是对象。创建

myReceiver = new MyReceiver(); 

然后放............

registerReceiver(myReceiver,intentFilter);

【讨论】:

  • 你是否更正了这一行 if(MyReceiver!= null) unregisterReceiver(MyReceiver);取消注册接收器(myReceiver);在 OnDestroy 中
  • 请提供更多关于您的答案的信息,以便其他用户将来也可以使用它。
【解决方案2】:

可能有两种情况:

  1. 您的 appB 未运行,因此未实例化 Activity,因此未注册接收器。
  2. 您的活动已销毁,意味着您已取消注册您通过 onCreate() 中的 registerReceiver() 注册的接收器

解决方案:

在清单中注册您的广播接收器。

appB 内部清单:

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.pkg.perform.Ruby" />
    </intent-filter>
</receiver>

并注释掉appA中的行

intent.setComponent(new ComponentName("com.pkg.AppB","com.pkg.AppB.MainActivity"));

在 MyBroadcastReceiver 中编写逻辑以显示相关数据/启动新活动

【讨论】:

  • Activity B 运行良好,没有问题
  • 您是否尝试过使用清单注册接收器并注释掉 setComponent 部分
  • 好的,它现在可以工作了。我忘了评论 set component 语句。这是一个愚蠢的错误
  • 谁能帮我多做 1 步,我在 App B 中收到了内容,现在有一些额外的内容我想将其发送回 App A。
【解决方案3】:

首先要在清单文件中声明应用 B 中的接收器,如下所示:

<receiver android:name=".MyBroadcastReceiver"
    android:enabled="true"
    android:exported="true">
        <intent-filter>
          <action android:name="com.pkg.perform.Ruby" />
        </intent-filter>
</receiver>

发送广播时,将FLAG_INCLUDE_STOPPED_PACKAGES 标志添加到intent [src],因为当您从应用程序A 广播到应用程序B 时,应用程序B 可能未运行,此标志可确保即使未运行的应用程序也能到达广播:

FLAG_INCLUDE_STOPPED_PACKAGES 标志被添加到它之前的意图 被发送以指示意图被允许启动一个 已停止应用程序的组件。

intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);

你的情况是这样的:

    final Intent intent=new Intent();
    intent.setAction("com.pkg.perform.Ruby");
    intent.putExtra("KeyName","code1id");
    intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
    intent.setComponent(  
        new ComponentName("com.pkg.AppB","com.pkg.AppB.MyBroadcastReceiver"));  
    sendBroadcast(intent);

【讨论】:

  • 正如文档所说,FLAG_INCLUDE_STOPPED_PACKAGES 默认是隐式的
  • 小米后台移除应用程序无效
  • 只有将new ComponentName("com.pkg.AppB","com.pkg.AppB.MainActivity"));改为new ComponentName("com.pkg.AppB","com.pkg.AppB.MyBroadcastReceiver"));才有效,MyBroadcastReceiver是这个接收器的类名。
  • 是的,我似乎遇到了复制/粘贴错误。不过我会检查一下谢谢
  • @Kanchan Chowdhury 在小米、金立等 OEM 中:应用程序从最近删除时会被强制停止,因此所有广播和服务都会被删除和销毁。直到用户再次打开应用程序才会启动。
【解决方案4】:

如果这对某人有帮助并且对我有用

在 App A 的活动中或在内容提供者中-

  Intent intent = new Intent("Updated");
  intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
  intent.setComponent (new
  ComponentName "com.exam.appA",
  "com.exam.appA.DbaseChanged"));
  getContext().sendBroadcast(intent);

在清单中的应用 B 中

      <receiver
        android:name=".DbaseChanged"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="Updated" />
        </intent-filter>
      </receiver>

在 App B 广播接收器类中-

    public class DbaseChanged extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent
     intent)   {

           String act = intent.getAction();
           if(act != null && act.equals("Updated")  )
            {
                Toast.makeText(context, act ,
              Toast.LENGTH_SHORT).show();

            }

            }
       }

【讨论】:

  • 我的应用 A 是一项始终处于活动状态的服务。 App B 只需要响应广播,如果它是活动的。
【解决方案5】:

在 App A 中:在此处发送广播。

 final Intent i= new Intent();
 i.putExtra("data", "Some data");
 i.setAction("com.pkg.perform.Ruby");
 i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
 getApplicationContext().sendBroadcast(i);

在应用 B 清单中

 <receiver  android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.pkg.perform.Ruby" />
            </intent-filter>
        </receiver>

在App B MainActivity中:注册receiver oncreate(),注销onDestroy()

 public class MainActivity extends AppCompatActivity
 {
      private MyBroadcastReceiver MyReceiver;

       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            MyReceiver = new MyBroadcastReceiver();
            IntentFilter intentFilter = new IntentFilter("com.pkg.perform.Ruby");
            if(intentFilter != null)
            {
               registerReceiver(MyReceiver, intentFilter);
            }
       }

       @Override
       protected void onDestroy()
       {
           super.onDestroy();
           if(MyReceiver != null)
               unregisterReceiver(MyReceiver);
       }
  }

在应用 B 广播接收器中

public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        String data = intent.getStringExtra("data");
        Log.i("BR" ,"Data received:  " + data);
    }
}

【讨论】:

  • 如果你在 MainActivity 中监听接收器,那么在清单中包含它是没有意义的。
  • 不需要放在清单中。附:我发现广播接收器应该在清单中注册时没有触发。
  • 如果SDK版本为OREO或以上,需要重新注册activity。不允许再在 manifest 中注册隐式广播。
【解决方案6】:

当我在 Manifest 中注册广播接收器时,我需要调用 setPackage("package_name") 以确保明确性。即使应用程序完全关闭,我也能够接收数据。

// sending app sends broadcast
Intent intent = new Intent(ACTION_RECOMMEND);
intent.putExtra(LISTEN_RECOMMENDATION, "Triggered - Jhene Aiko");
intent.putExtra(WATCH_RECOMMENDATION, "Goblin - Kim Go-eun");
intent.setPackage("com.example.package.receiverapp");
sendBroadcast(intent);


//receiving app manifest registers receiver
<receiver
   android:name=".ManifestRegisteredBroadcastReceiver"
   android:exported="true">
   <intent-filter>
       <action android:name="com.random.action.RECOMMEND" />
   </intent-filter>
</receiver>

我在通过activity注册receiver时不需要添加intent.setPackage(package_name),但这也意味着如果activity被销毁(应用关闭,应用长期处于后台)我无法获取数据

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多