Bootstrap

【Android】使用广播进行两个APP之间的通信

项目需求

在两个APP中使用广播进行通信,在第一个APP里面发送特定广播,只有第二个APP接收广播,然后将接收到的数据进行处理。

需求实现

在第一个APP里面

首先定义一个广播【Action】

    public static final String CUSTOM_ACTION = "com.cp.jyservice.CUSTOM_ACTION";

然后创建一个Intent

    private static Intent broadcastIntent;

初始化这个Intent

        broadcastIntent = new Intent(CUSTOM_ACTION);
        broadcastIntent.setPackage("com.ex.data"); // 替换为目标应用程序的包名
        broadcastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

然后在需要使用的时候组装数据

broadcastIntent.putExtra("id", id);
broadcastIntent.putExtra("channel", channel);
broadcastIntent.putExtra("result", reUtf);

当数据组装完毕之后,可以发送这个广播了,注意在使用这个【sendBroadcast】方法的时候,一定要注意前面的这个 context 调用的这个 context 属于谁,否则很容易造成广播发送失败的情况

 MyServiceApp.getAppContext().sendBroadcast(broadcastIntent);

在第二个APP里面接收广播
首先自定义一个广播接收

public class CpCanBroadcastRecriver extends BroadcastReceiver {

//定义一个Intent,这个是用来在本app里面使用本地广播进行数据传递的
    private final Intent cpBroadcastIntent = new Intent("com.local.data.DATA_CP_CAN_ACTION");

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("TAG", "action: " + intent.getAction());
        // 处理接收到的广播
        if (intent.getAction().equals("com.cp.jyservice.CUSTOM_ACTION")) {
            int id = intent.getIntExtra("id", 0);
            int channel = intent.getIntExtra("channel", 0);
            String result = intent.getStringExtra("result");
            cpBroadcastIntent.putExtra("id", id);
            cpBroadcastIntent.putExtra("channel", channel);
            cpBroadcastIntent.putExtra("result", result);
            
            //这里面创建了一个本地广播将从第一个app里面接收到的数据发送出去
            LocalBroadcastManager.getInstance(context).sendBroadcast(cpBroadcastIntent);
            ZLog.e("TAG", "数据接收:" + id + channel + result);
        }
    }
}


在注册清单上面需要添加

     <receiver
            android:name=".broadcast.CpCanBroadcastRecriver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.cp.jyservice.CUSTOM_ACTION" />
            </intent-filter>
        </receiver>

这样的话就可以获取到第一个app发送的广播了,然后我们这边可以看到,在接收到数据之后,我们又使用了一个 本地广播将数据发送出去,这样就可以适用比如要把数据更新到UI上面之类的需求,我们可以在Activity里面这样写

    private final BroadcastReceiver cpCanReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if ("com.local.data.DATA_CP_CAN_ACTION".equals(intent.getAction())) {
                // 处理接收到的数据
                int id = intent.getIntExtra("id", 0);
                int channel = intent.getIntExtra("channel", 0);
                String result = intent.getStringExtra("result");
                Log.e("TAG", "数据: id: " + id + " channel: " + channel + " result: " + result);
             
            }
        }
    };

然后需要注册这个广播

        IntentFilter filter = new IntentFilter("com.local.data.DATA_CP_CAN_ACTION");
        LocalBroadcastManager.getInstance(this).registerReceiver(cpCanReceiver, filter);

当然不要忘了,注销

        if (cpCanReceiver != null) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(cpCanReceiver);
        }

PS:广播基础知识

广播介绍

在 Android 中,广播(Broadcast)是一种用于应用程序间或系统组件间传递消息的机制。它允许应用程序向其他应用程序或系统声明事件的发生,以便相应的组件可以采取适当的行动。广播可以是系统发出的(系统广播)或应用程序发出的(自定义广播),具体可以根据目的和发送者的不同进行分类。

概念

广播机制的核心思想是发布-订阅模式,即发送者(广播发送者)发送一个广播,接收者(广播接收者)根据自身的注册情况选择性地接收并响应这个广播。

分类

Android 中的广播可以分为以下几类:

标准广播(Normal Broadcasts):

标准广播是一种完全异步的广播,广播发送后,所有接收者几乎同时接收到广播消息。
它们是最高效的广播类型,因为它们不允许接收者修改广播的内容(除非它们是有序广播的接收者)。
示例:Intent.ACTION_BOOT_COMPLETED 表示系统启动完成时发送的广播。

有序广播(Ordered Broadcasts):

有序广播允许接收者按照优先级依次处理广播,一个接收者处理完后再传递给下一个接收者。
每个接收者都可以中止广播的传播,或者修改广播中携带的数据。
示例:Intent.ACTION_BATTERY_LOW 表示设备电池电量低时发送的广播。

本地广播(Local Broadcasts):

本地广播是应用内部使用的广播机制,只能由同一个应用的组件接收到,不会离开应用的边界,因此更为安全和高效。
使用本地广播可以避免向外部泄露私密信息或增加系统负担。
示例:用于在应用内的各个组件之间通信,而不让其泄漏到应用外部。

粘性广播(Sticky Broadcasts):

粘性广播是一种特殊的广播,它在发送后会一直保持有效,直到接收者处理完毕或者取消。
即使应用在广播发送后才启动,也可以通过查询粘性广播来获取最新的广播信息。
示例:Intent.ACTION_AIRPLANE_MODE_CHANGED 表示飞行模式状态改变时发送的广播。

使用场景
应用内通信:

通过本地广播可以在应用内各个组件之间传递信息,如在后台服务完成某项任务后通知活动更新界面。

系统事件监听:

监听系统事件如网络状态变化、电池状态变化、屏幕开关等,以便进行相应的处理或通知用户。

自定义事件传递:

应用内部定义特定的广播事件,允许不同的组件响应和处理,增强应用的灵活性和可扩展性。

在 Android 中,广播接收者的注册方式有两种:静态注册和动态注册。这两种注册方式适用于不同的场景和需求。

静态注册

静态注册是通过在 AndroidManifest.xml 文件中声明广播接收者的方式。这种方式适合那些需要在应用安装时就能够接收到广播的情况,常见于应用需要响应系统广播或者其他应用发出的广播。

步骤:

在 AndroidManifest.xml 文件中添加 元素,并指定接收者的类名和需要监听的广播事件。

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <!-- 添加其他需要监听的 action -->
    </intent-filter>
</receiver>

在 intent-filter 中可以添加多个 元素,指定接收者要监听的广播动作。

优点:

简单明了,易于理解和管理。
应用安装时就会生效,可以及时响应系统广播。

缺点:

广播接收者的生命周期受应用生命周期影响,容易造成内存泄漏。
静态注册的广播接收者无法在应用退出时解除注册,需要注意资源释放。

动态注册

动态注册是在应用运行时通过代码动态注册广播接收者,适用于那些需要在特定情况下才接收广播或需要动态控制注册和注销的场景。

步骤:

创建广播接收者类并继承 BroadcastReceiver,重写 onReceive() 方法处理接收到的广播内容。

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 处理接收到的广播内容
    }
}

在需要注册的地方(如 Activity 的 onCreate() 方法)动态注册广播接收者,并设置需要监听的广播动作。

MyBroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
// 添加其他需要监听的 action
registerReceiver(receiver, filter);

在不需要接收广播时,记得在合适的时机(如 Activity 的 onDestroy() 方法)解除注册。

unregisterReceiver(receiver);

优点:

灵活控制注册和解除注册的时机,避免不必要的资源消耗和内存泄漏。
可以根据应用需求动态添加或移除监听的广播动作。

缺点:

实现稍复杂,需要手动管理注册和解除注册的过程。
应用退出时需要确保解除注册,否则可能造成内存泄漏。

选择注册方式的建议

静态注册适合需要一直监听某些系统广播或者其他应用发送的广播,且广播接收者的生命周期与应用生命周期保持一致的情况。

动态注册适合需要根据应用运行时的状态动态添加或移除监听的情况,以及需要精确控制注册和解除注册时机的情况。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;