BroadcastReceiver 作为一个独立的class 会有一些棘手的问题 挡在大家面前
1. 如何把得到的信息返回给某个Thread
2. 代码比较零散 有一些阅读障碍
为解决以上问题,将Broadcast receiver作为内部类接收广播;需进行如下改造:
第一步:MyReceiver 作为内部类接收广播
class MyReceiver extends BroadcastReceiver {
Context context;
public MyReceiver(Context c){
context = c;
}
//动态注册
public void registerAction(String action){
IntentFilter filter = new IntentFilter();
filter.addAction(action);
context.registerReceiver(this,filter);
}
@Override
public void onReceive(Context context, Intent intent) {
//接收广播内容.
}
}
}
第二步:调用MyReceiver 内部类的方法,在当前主类中进行动态注册
动态注册一般在onResume()方法里面注册。
@Override
public void onResume() {
myReceiver = new MyReceiver(this);
myReceiver.registerAction("myreceiver.action.name");
}
在onPause()方法里面取消注册。
@Override
protected void onPause() {
unregisterReceiver(myReceiver);
super.onPause();
}
********************************************************************************************************************************************************
分界线
********************************************************************************************************************************************************
本人最终实现的“apk1发送端 <——> apk2接收端” 发广播并回发广播消息的源码如下,可成功实验通过;
//apk1:发送端
package com.amaker.ch08.app_send;
import com.amaker.ch08.app_send.R;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
/**
* @author
* apk1 发送端apk:发送广播信息到接收端,之后接收接收端返回的广播信息
* 特点:注册该Receiver采用动态注册,且Broadcast receiver作为内部类接受广播
*/
public class MainActivity extends Activity {
// 定义一个Action常量
private static final String MY_ACTION2 = "com.amaker.ch08.action.MY_ACTION2";
private static final String MY_ACTION = "com.amaker.ch08.action.MY_ACTION";
// 定义一个Button对象
private Button btn;
private MyReceiver myreceiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置当前布局视图
setContentView(R.layout.main);
// IntentFilter send_intent = new IntentFilter();
// send_intent.addAction(MY_ACTION);
// registerReceiver(myreceiver, send_intent);
myreceiver = new MyReceiver(this);
myreceiver.registerAction(MY_ACTION2);
btn = (Button)findViewById(R.id.Button01);
// 为按钮设置单击监听器
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 实例化Intent对象
Intent intent = new Intent();
// 设置Intent action属性
intent.setAction(MY_ACTION);
// 为Intent添加附加信息
intent.putExtra("msg", "发送端Sending");
Log.v("heky","heky click");
// 发出广播
sendBroadcast(intent);
}
});
}
//Receiver采用动态注册,且Broadcast receiver放在一个类里面,不作为内部类(即单独作为一个类,这样很麻烦)
// public BroadcastReceiver myreceiver = new BroadcastReceiver(){
//
// @Override
// public void onReceive(Context cxt, Intent intent) {
// // 从Intent中获得信息
// String msg = intent.getStringExtra("msg");
// // 使用Toast显示
if("接收端Sending".equals(msg))
// {
// Toast.makeText(cxt, "这是发送端", Toast.LENGTH_LONG).show();
// //接收来自接收端的广播
// Log.i("my_tag", "heky 发送端:\t"+"msg="+msg+"++++++++++++");
//
//发送广播到接收端【构成了一个广播"发送<——>接收"的死循环;
Intent Recv_intent = new Intent();
// 设置Intent action属性
Recv_intent.setAction("com.amaker.ch08.action.MY_ACTION");
// 为Intent添加附加信息
Recv_intent.putExtra("msg", "发送端Sending");
// 发出广播
cxt.sendBroadcast(Recv_intent);
// }
// }
// };
}
package com.amaker.ch08.app_send;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import android.content.IntentFilter;
/**
* @author
* 作用:注册该Receiver采用动态注册,且Broadcast receiver作为内部类接受广播
*/
public class MyReceiver extends BroadcastReceiver{
Context context;
@Override
public void onReceive(Context cxt, Intent intent) {
// 从Intent中获得信息
String msg = intent.getStringExtra("msg");
// 使用Toast显示
if("接收端Sending".equals(msg))
{
//Toast.makeText(cxt, "这是发送端", Toast.LENGTH_LONG).show();
//接收来自接收端的广播
Log.i("my_tag", "heky 发送端:\t"+"msg="+msg+"++++++++++++");
// //发送广播到接收端【构成了一个广播"发送<——>接收"的死循环;
// Intent Recv_intent = new Intent();
// // 设置Intent action属性
// Recv_intent.setAction("com.amaker.ch08.action.MY_ACTION");
// // 为Intent添加附加信息
// Recv_intent.putExtra("msg", "发送端Sending");
// // 发出广播
// cxt.sendBroadcast(Recv_intent);
}
}
public MyReceiver(Context cxt){
context = cxt;
}
//动态注册
public void registerAction(String action){
IntentFilter filter = new IntentFilter();
filter.addAction(action);
context.registerReceiver(this,filter);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.amaker.ch08.app_send"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
********************************************************************************************************************************************************
分界线
********************************************************************************************************************************************************
//apk2 接收端
package com.amaker.ch08.app_recev;
import com.amaker.ch08.app_recev.MyReceiver;
import com.amaker.ch08.app_recev.R;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* @author
* apk2 接收端apk:接收发送端的广播信息,并回发广播至发送端
* 特点:注册该Receiver采用动态注册,且Broadcast receiver作为内部类接受广播
*/
public class MainActivity extends Activity {
// 定义一个Action常量
private static final String MY_ACTION = "com.amaker.ch08.action.MY_ACTION";
private static final String MY_ACTION2 = "com.amaker.ch08.action.MY_ACTION2";
// 定义一个Button对象
private Button btn;
private MyReceiver myreceiver2 ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置当前布局视图
setContentView(R.layout.main);
// IntentFilter recv_intent = new IntentFilter();
// recv_intent.addAction(MY_ACTION);
// registerReceiver(myreceiver, recv_intent);
myreceiver2 = new MyReceiver(this);
myreceiver2.registerAction(MY_ACTION);
btn = (Button)findViewById(R.id.Button01);
// 为按钮设置单击监听器
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 实例化Intent对象
Intent intent = new Intent();
// 设置Intent action属性
intent.setAction(MY_ACTION2);
// 为Intent添加附加信息
intent.putExtra("msg", "接收端Sending");
// 发出广播
sendBroadcast(intent);
}
});
}
}
package com.amaker.ch08.app_recev;
import android.R.string;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.widget.Toast;
/**
* @author
* 作用:注册该Receiver采用动态注册,且Broadcast receiver作为内部类接受广播
*/
public class MyReceiver extends BroadcastReceiver{
Context context;
@Override
public void onReceive(Context cxt, Intent intent) {
// 从Intent中获得信息
String msg = intent.getStringExtra("msg");
// 使用Toast显示
if("发送端Sending".equals(msg))
{
Toast.makeText(cxt, "这是接收端", Toast.LENGTH_LONG).show();
Log.i("my_tag", "heky 接收端:\t"+"msg2="+msg+"--------------");
Intent Recv_intent = new Intent();
// 设置Intent action属性
Recv_intent.setAction("com.amaker.ch08.action.MY_ACTION2");
// 为Intent添加附加信息
Recv_intent.putExtra("msg", "接收端Sending");
// 发出广播
cxt.sendBroadcast(Recv_intent);
}
}
public MyReceiver(Context cxt){
context = cxt;
}
//动态注册
public void registerAction(String action){
IntentFilter filter = new IntentFilter();
filter.addAction(action);
context.registerReceiver(this,filter);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.amaker.ch08.app_recev"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>