高版本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高版本上正常发送和接收广播了。

相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui