您的位置:首页 > 移动开发 > Android开发

Android笔记一(Broadcast)

2015-08-29 19:29 423 查看
1、接收系统的广播----使用动态注册监控网络的变化

        广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应的逻辑。一般的注册广播有两种形式1、动态注册 (即在java代码中注册)  2、静态注册 (在AndroidManifest.xml 中注册),这里使用的是动态注册的形式。

        那么该如何创建一个广播接收器呢?其实只需要新建一个类, 让它继承自BroadcastReceiver,并重写父类的 onReceive()方法就行了。 这样当有广播到来时, onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。



class NetworkChangeReceiver extends BroadcastReceiver {
// 重写onReceive
@Override
public void onReceive(Context context, Intent intent) {
// 用getSystemService()得到系统服务类,专门用于管理网络连接
ConnectivityManager connect = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// 调用getActiveNetworkInfo(),得到NetworkInfo实例
NetworkInfo networkinfo = connect.getActiveNetworkInfo();
// 调用NetworkInfo的isAvailable()方法,判断是否有网络连接
if (networkinfo != null && networkinfo.isAvailable()) {
Toast.makeText(MainActivity.this, "网络可用!", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(MainActivity.this, "网络不可用,请检查您的网络!",
Toast.LENGTH_SHORT).show();
}
}

}


           看看MainActivity中的代码,当然也可以把上面的类用内部类的形式写到MainActivity中

public class MainActivity extends Activity {
private Button btn1;
private IntentFilter intentFilter;
private NetworkChangeReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btn1 = (Button) findViewById(R.id.btn_01);
// 使用Button的单击事件,来开启动态注册,监听网络的改变
btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// 创建NetworkChangeReceiver实例
receiver = new NetworkChangeReceiver();
// 创建一个InIntentFilter的实例
intentFilter = new IntentFilter();
// 添加一个名为android.net.conn.CONNECTIVITY_CHANGE的action,表示我们的接收器要监听的广播
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
// 注册,NetworkChangeReceiver就会收到所有值为
// android.net.conn.CONNECTIVITY_CHANGE的广播
registerReceiver(receiver, intentFilter);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
}
            添加权限,来查询系统网络状态

<!-- 添加系统网络状态访问的权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

2、接收系统广播----使用静态注册实现开机自启接收广播

      动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。那么有没有什么办法可以让程序在未启动的情况下就能接收到广播呢?这就需要使用静态注册的方式了。

这里我们准备让程序接收一条开机广播, 当收到这条广播时就可以在 onReceive()方法里执行相应的逻辑,从而实现开机启动的功能。新建一个 BootCompleteReceiver 继承自BroadcastReceiver,不能再使用内部类的形式写在MainActivity中。

//定义一个类BootCompleteReceiver,继承BroadcastReceiver,来实现静态注册,开机自启的广播的接收
public class BootCompleteReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "静态注册,开机自启,成功!", Toast.LENGTH_SHORT).show();
}

}
 看看MainActivity中的代码
public class MainActivity extends Activity {
private Button btn2;

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

}

可以看到,这里不再使用内部类的方式来定义广播接收器,因为稍后我们需要在AndroidManifest.xml 中将这个广播接收器的类名注册进去。终于,<application>标签内出现了一个新的标签<receiver>,所有静态注册的广播接收器都是在这里进行注册的。它的用法其实和<activity>标签非常相似,首先通过 android:name来指定具体注册哪一个广播接收器, 然后在<intent-filter>标签里加入想要接收的广播就行了,由于Android系统启动完成后会发出一条值为android.intent.action.BOOT_COMPLETED的广播,因此我们在这里添加了相应的
action。

<!-- 注册一个广播接收器,将广播接收器的类名注册进去,开机自启的接收器 -->
<receiver android:name="com.example.tset.demon06.BootCompleteReceiver">
<intent-filter >
<!-- 加入想要接收 的广播 -->
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
添加开机自启的权限

<!--添加程序开机自启的权限  -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
3、发送自定义的标准广播
在发送广播之前,我们还是需要先定义一个广播接收器来准备接收此广播才行,不然发出去也是白发。因此新建一个 MyBroadcastReceiver继承自 BroadcastRe
4000
ceiver
//定义一个类MyBroadcastReceiver,继承BroadcastReceiver,来实现标准广播的接收
public class MyBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "收到自定义标准广播", Toast.LENGTH_SHORT).show();
}

}
这里当 MyBroadcastReceiver收到自定义的广播时,就会弹出"收到自定义标准广播"的提示,然后在 AndroidManifest.xml 中对这个广播接收器进行注册。可 以 看 到 , 这 里 让 MyBroadcastReceiver 接 收 一 条 值 为“com.example.test.demon6.myBroadcast”的广播,因此待会儿在发送广播的时候,我们就需要发出这样的一条广播。

<!-- 注册一个广播接收器,将广播接收器的类名注册进去,自定义标准广播的接收器 -->
<receiver android:name="com.example.tset.demon06.MyBroadcastReceiver">
<intent-filter >
<!-- 加入想要接收 的广播,让他接收到一条值为com.example.tset.demon06.myBroadcast的广播 -->
<action android:name="com.example.tset.demon06.myBroadcast"/>
</intent-filter>
</receiver>
看看activity中的代码

public class MainActivity extends Activity {
private Button btn2;

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

btn2 = (Button) findViewById(R.id.btn_02);
// 使用Button的单击事件,来发送标准广播
btn2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent("com.example.tset.demon06.myBroadcast");
// 也可以在这里使用Intent传值给广播接收器
// 发送广播,这条广播的值为com.example.tset.demon06.myBroadcast
sendBroadcast(intent);
}
});
}

}
4、发送自定义有序广播
广播主要分为两种类型,标准广播和有序广播。有序广播(Ordered broadcasts)则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。标准广播(Normal
broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。

在发送广播之前,我们还是需要先定义一个广播接收器来准备接收此广播才行,不然发出去也是白发。因此新建一个 OrderBroadcastReceiver继承自 BroadcastReceiver

public class OrderBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "收到自定义有序广播", Toast.LENGTH_SHORT).show();
//截断广播,后面的程序就不能收到这条有序广播了
abortBroadcast();
}

}
<!-- 注册一个广播接收器,将广播接收器的类名注册进去,自定义有序广播的接收器 -->
<receiver android:name="com.example.tset.demon06.OrderBroadcastReceiver">
<!-- 设置优先级为100 -->
<intent-filter android:priority="100">
<!-- 加入想要接收 的广播,让他接收到一条值为com.example.tset.demon06.myBroadcast的广播 -->
<action android:name="com.example.tset.demon06.orderBroadcast"/>
</intent-filter>
</receiver>
<span style="white-space:pre">						</span>public class MainActivity extends Activity {

<span style="white-space:pre">								</span>private Button btn3;

<span style="white-space:pre">								</span>@Override
<span style="white-space:pre">								</span>protected void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre">									</span>super.onCreate(savedInstanceState);
<span style="white-space:pre">									</span>setContentView(R.layout.activity_main);

<span style="white-space:pre">									</span>btn3 = (Button) findViewById(R.id.btn_03);

<span style="white-space:pre">									</span>// 使用Button的单击事件,来发送有序广播
<span style="white-space:pre">									</span>btn3.setOnClickListener(new OnClickListener() {

<span style="white-space:pre">										</span>@Override
<span style="white-space:pre">										</span>public void onClick(View v) {
<span style="white-space:pre">											</span>// TODO Auto-generated method stub
<span style="white-space:pre">											</span>Intent intent = new Intent("com.example.tset.demon06.orderBroadcast");
<span style="white-space:pre">											</span>// 发送广播,这条广播的值为com.example.tset.demon06.myBroadcast
<span style="white-space:pre">											</span>sendOrderedBroadcast(intent,null);
<span style="white-space:pre">										</span>}
<span style="white-space:pre">									</span>});
<span style="white-space:pre">								</span>}

}
可以看到有序广播的发送和标准广播差不多,就是我们通过 android:priority 属性给广播接收器设置了优先级,优先级比较高的广播接收器就可以先收到广播。 这里将 MyBroadcastReceiver的优先级设成了 100。和发送的方法不一样。其中还在接收广播的时候把广播截断了 ,其他地方就不能接收了 。

5、使用本地广播

前面我们发送和接收的广播全部都是属于系统全局广播, 即发出的广播可以被其他任何的任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样就很容易会引起安全性的问题, 比如说我们发送的一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他的程序不停地向我们的广播接收器里发送各种垃圾广播。为了能够简单地解决广播的安全性问题,Android 引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,
并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。本地广播的用法并不复杂,主要就是使用了一个 LocalBroadcastManager 来对广播进行

管理,并提供了发送广播和注册广播接收器的方法。

public class MainActivity extends Activity {
private Button btn4;

private IntentFilter intentFilter1;
private LocalBroadcastManager manager;
private  LocalReceiver localReceiver;

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

btn4 = (Button) findViewById(R.id.btn_04);
manager = LocalBroadcastManager.getInstance(MainActivity.this);

btn4.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
manager.sendBroadcast(intent);
}
});
//创建IntentFilter实例
intentFilter1 = new IntentFilter();
//添加一个名为com.example.broadcasttest.LOCAL_BROADCAST的action,表示我们的接收器要监听的广播
intentFilter1.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
//创建LocalReceiver实例
localReceiver = new LocalReceiver();
//使用LocalBroadcastManager来注册广播
manager.registerReceiver(localReceiver, intentFilter1);
}

// 定义一个内部类LocalReceiver,继承BroadcastReceiver,来实现动态注册本地广播接收器
class LocalReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "接收到本地广播",Toast.LENGTH_SHORT).show();
}

}
}
有没有感觉这些代码很熟悉?没错,其实这基本上就和我们前面所学的动态注册广播接收器以及发送广播的代码是一样。只不过现在首先是通过 LocalBroadcastManager的 getInstance()方法得到了它的一个实例,然后在注册广播接收器的时候调用的是 LocalBroadcastManager的 registerReceiver()方法,在发送广播的时候调用的是LocalBroadcastManager的 sendBroadcast()方法,仅此而已。

以上代码的UI都非常简单,只有几个Button,就不给出具体的布局

这些笔记乃是作者读《第一行代码》整理所得。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息