高版本Android跨应用广播通信实例

在高版本的Android上,应用间发送广播需要特别注意权限和导出设置。以下是完整的发送和接收广播的代码示例:

1. 发送广播的应用

AndroidManifest.xml 配置

xml 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sender">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">
        
        <!-- 发送广播的Activity -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

MainActivity.java

java 复制代码
package com.example.sender;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private static final String CUSTOM_ACTION = "com.example.CUSTOM_BROADCAST";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button sendButton = findViewById(R.id.send_button);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendCustomBroadcast();
            }
        });
    }

    private void sendCustomBroadcast() {
        Intent intent = new Intent(CUSTOM_ACTION);
        // 添加接收应用的包名,提高安全性(必要,注意是接收应用的包名,不是发送应用的包名)
        intent.setPackage("com.example.receiver");
        
        // 传递数据
        intent.putExtra("message", "Hello from sender app!");
        intent.putExtra("timestamp", System.currentTimeMillis());
        
        try {
            // 发送广播
            sendBroadcast(intent);
            Toast.makeText(this, "Broadcast sent successfully", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Toast.makeText(this, "Failed to send broadcast: " + e.getMessage(), 
                         Toast.LENGTH_SHORT).show();
        }
    }
}

2. 接收广播的应用

AndroidManifest.xml 配置

xml 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.receiver">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">

        <!-- 接收广播的Activity -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 注册BroadcastReceiver exported必须设置为 true -->
        <receiver 
            android:name=".CustomBroadcastReceiver"
            android:exported="true"
            android:enabled="true">
            <intent-filter>
                <action android:name="com.example.CUSTOM_BROADCAST" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

CustomBroadcastReceiver.java

java 复制代码
package com.example.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class CustomBroadcastReceiver extends BroadcastReceiver {
    
    private static final String TAG = "CustomBroadcastReceiver";
    
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null && "com.example.CUSTOM_BROADCAST".equals(intent.getAction())) {
            // 获取传递的数据
            String message = intent.getStringExtra("message");
            long timestamp = intent.getLongExtra("timestamp", 0);
            
            Log.d(TAG, "Received broadcast: " + message + ", timestamp: " + timestamp);
            
            // 显示通知或Toast
            Toast.makeText(context, "Received: " + message, Toast.LENGTH_LONG).show();
            
            // 可以启动Activity或Service来处理数据
            Intent activityIntent = new Intent(context, MainActivity.class);
            activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            activityIntent.putExtra("received_message", message);
            context.startActivity(activityIntent);
        }
    }
}

MainActivity.java (接收应用的主Activity)

java 复制代码
package com.example.receiver;

import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private TextView messageTextView;

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

        messageTextView = findViewById(R.id.message_text);
        
        // 检查是否有从广播传递过来的消息
        String receivedMessage = getIntent().getStringExtra("received_message");
        if (receivedMessage != null) {
            messageTextView.setText("Received message: " + receivedMessage);
        }
    }
}

3. 布局文件

发送应用的 activity_main.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Sender App"
        android:textSize="24sp"
        android:layout_marginBottom="32dp" />

    <Button
        android:id="@+id/send_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Broadcast" />

</LinearLayout>

接收应用的 activity_main.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Receiver App"
        android:textSize="24sp"
        android:layout_marginBottom="32dp" />

    <TextView
        android:id="@+id/message_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Waiting for broadcast..."
        android:textSize="16sp" />

</LinearLayout>

4. 安全注意事项

使用权限保护(可选)

如果需要更高级别的安全保护,可以添加自定义权限:

在接收应用的 AndroidManifest.xml 中添加:

xml 复制代码
<permission 
    android:name="com.example.receiver.CUSTOM_PERMISSION"
    android:protectionLevel="signature" />

<uses-permission android:name="com.example.receiver.CUSTOM_PERMISSION" />

在发送应用中:

xml 复制代码
<uses-permission android:name="com.example.receiver.CUSTOM_PERMISSION" />

在发送广播时:

java 复制代码
intent.putExtra("message", "Hello from sender app!");
sendBroadcast(intent, "com.example.receiver.CUSTOM_PERMISSION");

关键要点:

  1. 导出 :接收广播的组件必须设置 android:exported="true"
  2. 安全性:使用特定的包名和自定义Action来避免广播被其他应用拦截
  3. 权限:根据需要添加适当的权限声明
  4. Intent Filter:确保发送和接收的Action字符串完全匹配

这样配置后,两个应用就可以在Android高版本上正常发送和接收广播了。

相关推荐
Kapaseker3 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴3 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭13 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab14 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe20 小时前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋1 天前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我2 天前
让我们实现一个更好看的内部阴影按钮
android·flutter