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

相关推荐
似霰2 小时前
传统 Hal 开发笔记6----App 访问硬件服务
android·framework·hal
爱装代码的小瓶子2 小时前
【c++知识铺子】封装map和set(详细版)
android·java·c++
私人珍藏库3 小时前
AutoGLM无需豆包手机,让AI自动帮你点外卖-刷视频
android·ai·智能手机·工具·软件·辅助·autoglm
孤舟簔笠翁3 小时前
【Android驱动14】Android系统Crash工具使用方法和分析
android
帅得不敢出门4 小时前
MTK Android11 APP调用OTA升级
android·java·开发语言·framework
2501_915909064 小时前
苹果应用加密方案的一种方法,在没有源码的前提下,如何处理 IPA 的安全问题
android·安全·ios·小程序·uni-app·iphone·webview
用户2018792831674 小时前
Android App 换肤原理:用 "装修小房子" 故事浅谈
android
百锦再4 小时前
与AI沟通的正确方式——AI提示词:原理、策略与精通之道
android·java·开发语言·人工智能·python·ui·uni-app
2501_915909065 小时前
iOS 项目中常被忽略的 Bundle ID 管理问题
android·ios·小程序·https·uni-app·iphone·webview