Android 开发中使用广播的那些事儿

记得小时候,村里有什么事,都会通过村广播站的大喇叭进行通知,到现在仍是如此。对于一些事情的传达,广播是一种简单有效的方式。在Android系统中,也存在类似的广播机制,而且使用起来更加灵活。下面逐步介绍Android中各种广播的使用方法。

1.标准广播

标准广播是Android中最常见的一种广播方式,其完全采用异步的方式进行,也就是说,一旦广播发出,所有注册该广播接收者的程序都将在几乎同时受到该广播,其工作原理如下图所示。
这里写图片描述
要想接收到广播,首先要注册一个广播接收者,注册方式可以分为动态注册和静态注册两种。但无论哪种注册方式,我们都必须要先创建一个接收类,该类继承BroadcastReceiver,并重写它的onReceive()方法。onReceive()就是程序接收到广播之后要进行的逻辑。

class Demo1Recceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "onReceive:  this is demo1 receiver!");
        }
    }

这里,我创建了一个内部类,并在onReceive()中打印一行日志,表示程序收到了这条广播。下面就是将这个广播接收者注册到系统中了。

先来看动态注册,顾名思义,就是在程序中使用代码进行注册,这种注册方式简单明了,但有一个缺点就是必须要在我们的应用启动起来之后才能够接收到广播,如果需要监听系统广播如开启广播等,最好不要使用这种注册方式。

IntentFilter filter=new IntentFilter("com.example.demo1.BROADCAST");
Demo1Recceiver receiver=new Demo1Recceiver();
registerReceiver(receiver,filter);

可以看到,这里首先创建了一个IntentFilter,该对象的作用主要是说明我们要接收的是哪一条广播,com.example.demo1.BROADCAST就是我们指明的一条广播动作,需要与发送广播时填入的动作相一致才能接收到广播。此时,广播接收者已经注册完毕了,下面我们就发送一条广播来检验一下是否能接收到。
首先,在主页面添加一个按钮,当我们点击按钮时就发送一条广播,如下图所示,
这里写图片描述
关于添加按钮及点击事件的代码这里就不贴出来了,直接看发送广播的方法

Intent intent=new Intent("com.example.demo1.BROADCAST");
sendBroadcast(intent);

是的,只需要简单的两行代码就可以发送一条广播。这里Intent传入的参数需要与注册广播接收者时IntentFilter里的参数相一致,并保证在整个应用程序中是唯一的。相信如果你了解Intent的用法应该能想到,在发送广播时,我们可以在intent中传入数据,然后在onReceive()中获取数据以进行相应操作。下面验证一下上述代码是否有效,运行程序,点击发送广播按钮,后台打印这样一条日志信息:
02-24 06:05:31.399 22997-22997/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive: this is demo1 receiver!
可见,广播已经发送并成功接收。需要注意的是,采用动态方式注册的广播接收者需要在适当的地方解注册,以免造成混乱。例如,我们是在activity中注册的广播接收者,那么可以在onDestory()方法中解注册。

@Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

上述广播发送方式不仅在应用内部可以收到,对于注册了相应动作的别的应用程序同样能够收到,下面我们就验证一下。新建一个Android应用程序BroadcastDemo2,以上述同样的方式在BroadcastDemo2中注册一个广播接收者,并更改日志信息如下:

class Demo2Receiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "onReceive: this is demo2 receiver!");
        }
    }

将BroadcastDemo2安装到手机上,然后打开BroadcastDemo1点击发送广播按钮,注意,从BroadcastDemo2返回BroadcastDemo1时,一定要按home键返回,然后在打开BroadcastDemo1,不能按返回键直接退出,因为前文中说过,动态注册的方式只有在程序运行时才能接收到广播,一下两种结果分别是按home和按返回键退出情况下的日志信息:

02-24 06:14:20.505 13084-13084/com.example.broadcastdemo2 D/BroadcastReceiverDemo: onReceive: this is demo2 receiver!
02-24 06:14:20.506 22997-22997/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive:  this is demo1 receiver!
02-24 06:20:00.978 22997-22997/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive:  this is demo1 receiver!

可以看到,BroadcastDemo2确实可以接收到广播,但当以动态方式注册时,必须保持BroadcastDemo2正在运行。

说完了动态注册,我们再聊一聊静态注册,静态注册的最大优点就是可以在应用程序不运行的情况下接收广播并触发相应操作,如接收开机广播以启动某项服务等。静态注册需要在AndroidManifest.xml文件中添加代码,下面我们注释掉BroadcastDemo2中的动态注册代码,并将原有的内部类接收者改为外部类,重新在它的AndroidManifest.xml文件中application标签下添加如下代码:

<receiver android:name=".Demo2Receiver"
      android:enabled="true"
      android:exported="true">
      <intent-filter>
           <action android:name="com.example.demo1.BROADCAST"/>
      </intent-filter>
</receiver>

name属性表示我们要注册的广播接收者是哪个,intent-filter标签里的action就是发送广播时传入的动作。
下面我们按返回键关掉BroadcastDemo2,然后点击发送广播按钮,日志信息如下:

02-24 06:39:39.686 4126-4126/com.example.broadcastdemo2 D/BroadcastReceiverDemo: onReceive: this is demo2 receiver!
02-24 06:39:39.690 22997-22997/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive:  this is demo1 receiver!

可见,即使BroadcastDemo2不运行,它仍然能够接收到BroadcastDemo1的广播。

2.带权限的标准广播

通过以上例子你也许会想到,既然我们的应用发出的广播别的应用也可以收到,那会不会造成安全隐患呢?是的,上述普通广播 的确存在安全问题,主要体现在两个方面:
1. 如果别的应用程序监听我们的广播,那么会造成我们应用程序的数据泄露;
2. 如果别的应用程序冒充我们的应用发送广播,那么就会频繁的启动我们的广播接收程序,造成我们应用的混乱,甚至崩溃。
好在,Android早已考虑了这个问题,为我们提供了权限机制。首先针对第一个问题,在我们发送广播时,可以为它指定一个权限,只有具有该权限的应用才能接收到广播,如下所示:

Intent intent=new Intent("com.example.demo1.BROADCAST");  sendBroadcast(intent,"com.example.demo1.BROADCAST_PERMISSION");

其中com.example.demo1.BROADCAST_PERMISSION就是我们指定的权限,该权限可以是任意的,但必须保证其唯一性。将代码做出上述更改后,运行程序,点击发送按钮,可以看到,没有任何日志输出,也就是说无论是BroadcastDemo1还是BroadcastDemo2都没有收到广播,这是为什么呢?因为上述两个应用都没有添加我们发送广播时指定的权限,所以收不到,下面我们先在BroadcastDemo1的AndroidManifest.xml中添加如下代码:

<permission android:name="com.example.demo2"/>
<uses-permission android:name="com.example.demo1.BROADCAST_PERMISSION"/>

运行程序发送广播,日志输出如下:

02-24 08:08:58.703 21027-21027/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive:  this is demo1 receiver!

可以看到,BroadcastDemo1已经可以收到广播,但BroadcastDemo2仍然没有收到,再次为BroadcastDemo2添加上述权限,运行程序,日志输出如下:

02-24 08:08:58.703 21027-21027/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive:  this is demo1 receiver!
02-24 08:08:58.706 3338-3338/com.example.broadcastdemo2 D/BroadcastReceiverDemo: onReceive: this is demo2 receiver!

通过两次对比可以看到,对于指定了权限的广播,只有具备指定权限的应用才能接收到。
对于不安全性的第二个问题,同样可以利用权限机制解决。即在注册广播接收者时,也指定一个权限,只有具备指定权限的应用程序发送的广播,并且动作匹配,才能够被我接收到。动态和静态两种注册方式指定权限的方法如下:

IntentFilter filter=new IntentFilter("com.example.demo1.BROADCAST");
receiver=new Demo2Recceiver();
registerReceiver(receiver,filter,"com.example.demo2",null);
<receiver
    android:name=".Demo2Receiver"
    android:permission="com.example.demo2"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.demo1.BROADCAST" />
     </intent-filter>
</receiver>

上述两种方式,我们都为BroadcastDemo2的广播接收者指定了com.example.demo2这个权限,运行BroadcastDemo2程序,然后从BroadcastDemo1发送广播,可以看到日志输出如下:

02-24 08:15:57.105 21027-21027/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive:  this is demo1 receiver!

BroadcastDemo2并没有接收到广播,这是因为BroadcastDemo1不具备com.example.demo2这个权限,所以它发送的广播BroadcastDemo2接收不到,下面我们在BroadcastDemo1中添加如下权限:

<permission android:name="com.example.demo2"/>
<uses-permission android:name="com.example.demo2"/>

再次运行BroadcastDemo1发送广播,日志输出如下:

02-24 08:22:51.673 21027-21027/com.example.broadcastdemo1 D/BroadcastReceiverDemo: onReceive:  this is demo1 receiver!
02-24 08:22:51.673 3338-3338/com.example.broadcastdemo2 D/BroadcastReceiverDemo: onReceive: this is demo2 receiver!

BroadcastDemo2已经成功收到了广播。
由上,标准广播的安全性问题得到完美解决,不仅是标准广播,下面我们要说到的有序广播的安全问题,解决方法也是相同的。

3.有序广播

除了异步方式的标准广播,Android还提供了了一种采用同步方式的有序广播。在有序广播中,优先级高的广播接收者将先收到广播,并可将自己的处理结果添加到广播中继续向下传递,同时也可以终止广播的传播,终止后优先级低的广播接收者将收不到广播,其工作原理如下图所示:
这里写图片描述
发送有序广播的方法如下:

Intent orderedIntent=new Intent("com.example.demo1.ORDERED_BROADCAST");
sendOrderedBroadcast(orderedIntent,null);

其中,null表示指定的权限,为简单起见,我们这里没有设置权限。下面我们从高到低创建三个不同等级的广播接收者,关键代码如下:

public class HighPriorityReceiver extends BroadcastReceiver {
    private static final String TAG="HighPriorityReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: this is a high priority receiver");
    }
}
public class MiddlePriorityReceiver extends BroadcastReceiver {
    private static final String TAG="MiddlePriorityReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: this is a middle priority receiver");
    }
public class LowPriorityReceiver extends BroadcastReceiver {
    private static final String TAG="LowPriorityReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: this is a low priority receiver"+getResultCode());
    }
}

创建完接收者之后,就是对他们进行注册了,注册的时候可以为它们指定不同的优先级。同样注册方式可分为动态注册和静态注册,先看动态注册中指定优先级的方式:

        //注册高权限接收者
        IntentFilter highFilter=new IntentFilter("com.example.demo1.ORDERED_BROADCAST");
        highFilter.setPriority(100);
        highReceiver=new HighPriorityReceiver();
        registerReceiver(highReceiver,highFilter);
        //注册中等权限接收者
        IntentFilter midFilter=new IntentFilter("com.example.demo1.ORDERED_BROADCAST");
        midFilter.setPriority(50);
        midReceiver=new MiddlePriorityReceiver();
        registerReceiver(midReceiver,midFilter);
        //注册低权限接收者
        IntentFilter lowFilter=new IntentFilter("com.example.demo1.ORDERED_BROADCAST");
        lowFilter.setPriority(10);
        lowReceiver=new LowPriorityReceiver();
        registerReceiver(lowReceiver,lowFilter);

调用IntentFilter的setPriority(int priority)方法设置优先级,参数值可以是-1000~1000,值越大,优先级越高。同样的在静态注册中,通过设置intent-filter标签的priority属性来设置优先级,代码如下:

        <receiver
            android:name=".HighPriorityReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.example.demo1.ORDERED_BROADCAST" />
            </intent-filter>
        </receiver>

下面我们验证一下上述代码是否有效,在BroadcastDemo1的MainActivity中添加一个发送有序广播的按钮,发送之后,可以看到日志的输出结果如下:

02-24 09:57:24.088 18935-18935/com.example.broadcastdemo1 D/HighPriorityReceiver: onReceive: this is a high priority receiver
02-24 09:57:24.098 18935-18935/com.example.broadcastdemo1 D/MiddlePriorityReceiver: onReceive: this is a middle priority receiver
02-24 09:57:24.102 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: onReceive: this is a low priority receiver

观察各个接收者收到广播的时间,可以看到的确是按照优先级顺序排列的。需要指出的是,无论是标准广播还是有序广播,在接收者的onReceive()方法中都不宜有耗时操作,否则可能会导致应用程序的崩溃。
接下来我们看看如何将高优先级接收者的处理结果传递给低优先级接收者:

public class HighPriorityReceiver extends BroadcastReceiver {
    private static final String TAG="HighPriorityReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle=new Bundle();
        bundle.putString("name","Alice");
        bundle.putInt("age",25);
        setResultExtras(bundle);
        Log.d(TAG, "onReceive: this is a high priority receiver");
    }
}
public class MiddlePriorityReceiver extends BroadcastReceiver {
    private static final String TAG="MiddlePriorityReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle=getResultExtras(false);
        String name=bundle.getString("name");
        int age=bundle.getInt("age");
        Log.d(TAG, "onReceive: this is a middle priority receiver");
        Log.d(TAG, "The name is "+name+",The age is "+age);
        bundle.putString("name","Tom");
        setResultExtras(bundle);
    }
}
public class LowPriorityReceiver extends BroadcastReceiver {
    private static final String TAG="LowPriorityReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        String name=getResultExtras(false).getString("name");
        int age=getResultExtras(false).getInt("age");
        Log.d(TAG, "onReceive: this is a low priority receiver");
        Log.d(TAG, "The name is "+name+", The age is "+age);
    }
}

在这里,我们在HighPriorityReceiver的onReceive()方法中添加一些数据,然后在MiddlePriorityReceiver 中进行读取,并修改部分数据,最后再在LowPriorityReceiver 读取,程序的运行结果如下:

02-24 11:31:43.403 18935-18935/com.example.broadcastdemo1 D/HighPriorityReceiver: onReceive: this is a high priority receiver
02-24 11:31:43.415 18935-18935/com.example.broadcastdemo1 D/MiddlePriorityReceiver: onReceive: this is a middle priority receiver
02-24 11:31:43.415 18935-18935/com.example.broadcastdemo1 D/MiddlePriorityReceiver: The name is Alice,The age is 25
02-24 11:31:43.417 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: onReceive: this is a low priority receiver
02-24 11:31:43.417 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: The name is Tom, The age is 25

可以看到,数据已经成功从高优先级的接收者传递给低优先级的接收者,并且传递过程中可以改变数据。当然,对于发送广播时,通过Intent传递的数据,这部分数据无法改变,并且所有接收者都可以通过onReceive()方法的intent参数获取,除非高优先级的接收者终止了广播。
对于广播的终止,只需要在onReceive()中添加一行代码即可,改变HighPriorityReceiver的代码如下:

    public void onReceive(Context context, Intent intent) {
        Bundle bundle=new Bundle();
        bundle.putString("name","Alice");
        bundle.putInt("age",25);
        setResultExtras(bundle);
        Log.d(TAG, "onReceive: this is a high priority receiver");
        abortBroadcast();
    }

再次运行程序,日志输出如下:

02-24 11:37:16.623 18935-18935/com.example.broadcastdemo1 D/HighPriorityReceiver: onReceive: this is a high priority receiver

由于高优先级的HighPriorityReceiver终止了广播,所以低优先级的MiddlePriorityReceiver和LowPriorityReceiver将无法再接收到广播。但是Android也提供了一种机制,保证一个广播在传递途中是否被终止,都将有一个最终的广播接收者收到广播并作出相应处理。这种机制需要在发送有序广播时指定一个最终的广播接收者,方法如下:

sendOrderedBroadcast(orderedIntent,null,new LowPriorityReceiver(),null,RESULT_OK,null,null);

我们指定LowPriorityReceiver()为最终的广播接收者,保持其他程序代码不变再次运行程序:

02-24 11:44:19.848 18935-18935/com.example.broadcastdemo1 D/HighPriorityReceiver: onReceive: this is a high priority receiver
02-24 11:44:19.850 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: onReceive: this is a low priority receiver
02-24 11:44:19.850 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: The name is Alice, The age is 25

可以看到,MiddlePriorityReceiver没有收到广播,而比他优先级低的LowPriorityReceiver却收到了广播,并且解析出的数据就是HighPriorityReceiver传递的数据。但是也应该指出,指定的最终接收者是在正常的广播传递之后进行的,也就是说,虽然上述代码中LowPriorityReceiver得到执行,但是这并不改变其优先级低的本质。我们做如下实验,将HighPriorityReceiver中终止广播的代码注释掉,再运行程序,结果如下:

02-24 11:49:20.986 18935-18935/com.example.broadcastdemo1 D/HighPriorityReceiver: onReceive: this is a high priority receiver
02-24 11:49:20.997 18935-18935/com.example.broadcastdemo1 D/MiddlePriorityReceiver: onReceive: this is a middle priority receiver
02-24 11:49:20.997 18935-18935/com.example.broadcastdemo1 D/MiddlePriorityReceiver: The name is Alice,The age is 25
02-24 11:49:20.998 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: onReceive: this is a low priority receiver
02-24 11:49:20.998 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: The name is Tom, The age is 25
02-24 11:49:21.002 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: onReceive: this is a low priority receiver
02-24 11:49:21.002 18935-18935/com.example.broadcastdemo1 D/LowPriorityReceiver: The name is Tom, The age is 25

可以看到,LowPriorityReceiver的onReceive()方法执行了两遍,这充分说明,最终广播接收者的执行是在正常的有序广播传递结束之后运行的。

3.本地广播

不管是标准广播还是有序广播,如果不设置权限,均可以被第三方应用收到,即便设置了权限,如果权限被第三方应用获取到,依然存在安全性问题。因此,如果我们发送的广播只需要在应用内部传递,那么就可以使用本地广播。发送本地广播的方法和标准广播类似,方法如下:
发送广播:

LocalBroadcastManager localManager=LocalBroadcastManager.getInstance(this);
Intent localIntent=new Intent("com.example.demo1.LOCAL_BROADCAST");
localManager.sendBroadcast(localIntent);

注册广播:

public class LocalReceiver extends BroadcastReceiver {
    private static final String TAG="LocalReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: this is local receiver!");
    }
}
IntentFilter localFilter=new IntentFilter("com.example.demo1.LOCAL_BROADCAST");
LocalReceiver localReceiver=new LocalReceiver();
localManager.registerReceiver(localReceiver,localFilter);

需要说明的是,本地广播只能通过动态方式注册,其实这也很好理解,本地广播就是在应用内部传递的,发送广播时,应用肯定已经启动了,所以不需要采用静态注册的方式。

4.Sticky广播

除了上述三种广播,Android还有一种Sticky广播,从字面意思看sticky叫粘性的,发送Sticky广播,可以使广播一直滞留在系统中,一旦有新的广播接收者注册,立即就能收到这种广播,并触发相应的操作。滞留在系统中的广播只能是最后发出的一条,不能多条广播共存。但是Sticky已经在Android 5.0之后被废弃了,因为它没有权限控制,存在安全性问题,所以除非特别必要,否则尽量不要使用。发送sticky广播的方法很简单,与标准广播没有大的差别。不过要发送Sticky广播要在AndroidManifest.xml中注册一条权限:

<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
Intent stickyIntent=new Intent("com.example.demo1.STICKY_BROADCAST");
sendStickyBroadcast(stickyIntent);

5.系统广播

除了我们自己发出的广播,Android系统也会发出一些广播,例如,接打电话、系统启动完成、接收到短信等,我们也可以在自己的应用中注册接收系统广播的接收者,以触发相应的操作。注册系统广播的接收者一般采用静态方式,只需要添加相应的action即可,这里不再赘述了。不过,有些系统广播需要相应的权限才能接收到。下面给出一些系统广播的action:
//关闭或打开飞行模式时的广播
Intent.ACTION_AIRPLANE_M;

//充电状态,或者电池的电量发生变化;//电池的充电状态、电荷级别改变,不能通过组建声;
Intent.ACTION_BATTERY_CH;

//表示电池电量低
Intent.ACTION_BATTERY_LO;

//表示电池电量充足
Intent.ACTION_BATTERY_OK;

//关闭或打开飞行模式时的广播
Intent.ACTION_AIRPLANE_MODE_CHANGED;

//充电状态,或者电池的电量发生变化//电池的充电状态、电荷级别改变,不能通过组建声明接收这个广播,只有通过Context.registerReceiver()注册
Intent.ACTION_BATTERY_CHANGED;

//表示电池电量低
Intent.ACTION_BATTERY_LOW;

//表示电池电量充足,即从电池电量低变化到饱满时会发出广播
Intent.ACTION_BATTERY_OKAY;

//在系统启动完成后,这个动作被广播一次(只有一次)。
Intent.ACTION_BOOT_COMPLETED;

//按下照相时的拍照按键(硬件按键)时发出的广播
Intent.ACTION_CAMERA_BUTTON;

//当屏幕超时进行锁屏时,当用户按下电源按钮,长按或短按(不管有没跳出话框),进行锁屏时,android系统都会广播此Action消息
Intent.ACTION_CLOSE_SYSTEM_DIALOGS;

//设备当前设置被改变时发出的广播(包括的改变:界面语言,设备方向,等,请参考Configuration.java)
Intent.ACTION_CONFIGURATION_CHANGED;

//设备日期发生改变时会发出此广播
Intent.ACTION_DATE_CHANGED;

//设备内存不足时发出的广播,此广播只能由系统使用,其它APP不可用
Intent.ACTION_DEVICE_STORAGE_LOW;

//设备内存从不足到充足时发出的广播,此广播只能由系统使用,其它APP不可用
Intent.ACTION_DEVICE_STORAGE_OK;

//发出此广播的地方frameworks\base\services\java\com\android\server\DockObserver.java
Intent.ACTION_DOCK_EVENT;

//移动APP完成之后,发出的广播(移动是指:APP2SD)
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE;

//正在移动APP时,发出的广播(移动是指:APP2SD)
Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;

//Gtalk已建立连接时发出的广播
Intent.ACTION_GTALK_SERVICE_CONNECTED;

//Gtalk已断开连接时发出的广播
Intent.ACTION_GTALK_SERVICE_DISCONNECTED;

//在耳机口上插入耳机时发出的广播
Intent.ACTION_HEADSET_PLUG;

//改变输入法时发出的广播
Intent.ACTION_INPUT_METHOD_CHANGED;

//设备当前区域设置已更改时发出的广播
Intent.ACTION_LOCALE_CHANGED;

//表示用户和包管理所承认的低内存状态通知应该开始。
Intent.ACTION_MANAGE_PACKAGE_STORAGE;

//未正确移除SD卡(正确移除SD卡的方法:设置–SD卡和设备内存–卸载SD卡),但已把SD卡取出来时发出的广播 ,扩展介质(扩展卡)已经从 SD 卡插槽拔出,但是挂载点 (mount point) 还没解除 (unmount)
Intent.ACTION_MEDIA_BAD_REMOVAL;

//按下”Media Button” 按键时发出的广播,假如有”Media Button” 按键的话(硬件按键)
Intent.ACTION_MEDIA_BUTTON;

//插入外部储存装置,比如SD卡时,系统会检验SD卡,此时发出的广播?
Intent.ACTION_MEDIA_CHECKING;

//已拔掉外部大容量储存设备发出的广播(比如SD卡,或移动硬盘),不管有没有正确卸载都会发出此广播, 用户想要移除扩展介质(拔掉扩展卡)。
Intent.ACTION_MEDIA_EJECT;

//插入SD卡并且已正确安装(识别)时发出的广播, 扩展介质被插入,而且已经被挂载。
Intent.ACTION_MEDIA_MOUNTED;

//拓展介质存在,但使用不兼容FS(或为空)的路径安装点检查介质包含在Intent.mData领域。
Intent.ACTION_MEDIA_NOFS;

//外部储存设备已被移除,不管有没正确卸载,都会发出此广播, 扩展介质被移除。
Intent.ACTION_MEDIA_REMOVED;

//广播:已经扫描完介质的一个目录
Intent.ACTION_MEDIA_SCANNER_FINISHED;

//请求媒体扫描仪扫描文件并将其添加到媒体数据库。
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE;

//广播:开始扫描介质的一个目录
Intent.ACTION_MEDIA_SCANNER_STARTED;

// 广播:扩展介质的挂载被解除 (unmount),因为它已经作为 USB 大容量存储被共享。
Intent.ACTION_MEDIA_SHARED;

Intent.ACTION_MEDIA_UNMOUNTABLE;//

// 广播:扩展介质存在,但是还没有被挂载 (mount)
Intent.ACTION_MEDIA_UNMOUNTED

Intent.ACTION_NEW_OUTGOING_CALL;

//成功的安装APK之后//广播:设备上新安装了一个应用程序包。//一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_ADDED;

//一个已存在的应用程序包已经改变,包括包名
Intent.ACTION_PACKAGE_CHANGED;

//清除一个应用程序的数据时发出的广播(在设置--应用管理--选中某个应用,之后点清除数据时?)//用户已经清除一个包的数据,包括包名(清除包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_DATA_CLEARED;

//触发一个下载并且完成安装时发出的广播,比如在电子市场里下载应用?
Intent.ACTION_PACKAGE_INSTALL;

//成功的删除某个APK之后发出的广播, 一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_REMOVED;

//替换一个现有的安装包时发出的广播(不管现在安装的APP比之前的新还是旧,都会发出此广播?)
Intent.ACTION_PACKAGE_REPLACED;

//用户重新开始一个包,包的所有进程将被杀死,所有与其联系的运行时间状态应该被移除,包括包名(重新开始包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_RESTARTED;

//插上外部电源时发出的广播
Intent.ACTION_POWER_CONNECTED;

//已断开外部电源连接时发出的广播
Intent.ACTION_POWER_DISCONNECTED;

Intent.ACTION_PROVIDER_CHANGED;//

//重启设备时的广播
Intent.ACTION_REBOOT;

//屏幕被关闭之后的广播
Intent.ACTION_SCREEN_OFF;

//屏幕被打开之后的广播
Intent.ACTION_SCREEN_ON;

//关闭系统时发出的广播
Intent.ACTION_SHUTDOWN;

//时区发生改变时发出的广播
Intent.ACTION_TIMEZONE_CHANGED;

//时间被设置时发出的广播
Intent.ACTION_TIME_CHANGED;

//广播:当前时间已经变化(正常的时间流逝), 当前时间改变,每分钟都发送,不能通过组件声明来接收
,只有通过Context.registerReceiver()方法来注册
Intent.ACTION_TIME_TICK;

//一个用户ID已经从系统中移除发出的广播
Intent.ACTION_UID_REMOVED;

//设备已进入USB大容量储存状态时发出的广播?
Intent.ACTION_UMS_CONNECTED;

//设备已从USB大容量储存状态转为正常状态时发出的广播?
Intent.ACTION_UMS_DISCONNECTED;

Intent.ACTION_USER_PRESENT;//

//设备墙纸已改变时发出的广播
Intent.ACTION_WALLPAPER_CHANGED;
(第五部分参考:http://blog.sina.com.cn/s/blog_7dbac1250101mt5h.html

关于Android广播的部分就先总结这么多,以后有新的认识会再补充。

欢迎转载,转载请注明出处:http://blog.csdn.net/tianweitao/article/details/57074933

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值