高版本Android跨应用广播通信实例
在高版本的Android上,应用间发送广播需要特别注意权限和导出设置。以下是完整的发送和接收广播的代码示例:
1. 发送广播的应用
AndroidManifest.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 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
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 配置
<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 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> <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
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)
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
<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
<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 中添加:
<permission android:name=\"com.example.receiver.CUSTOM_PERMISSION\" android:protectionLevel=\"signature\" /><uses-permission android:name=\"com.example.receiver.CUSTOM_PERMISSION\" />
在发送应用中:
<uses-permission android:name=\"com.example.receiver.CUSTOM_PERMISSION\" />
在发送广播时:
intent.putExtra(\"message\", \"Hello from sender app!\");sendBroadcast(intent, \"com.example.receiver.CUSTOM_PERMISSION\");
关键要点:
- 导出:接收广播的组件必须设置
android:exported=\"true\"
- 安全性:使用特定的包名和自定义Action来避免广播被其他应用拦截
- 权限:根据需要添加适当的权限声明
- Intent Filter:确保发送和接收的Action字符串完全匹配
这样配置后,两个应用就可以在Android高版本上正常发送和接收广播了。