Intent与广播接收

486 阅读2分钟

tag:广播无法接收

本文从注册了应用安装广播Intent.ACTION_PACKAGE_ADDED却收不到开始,浅尝辄止探究了一下Intent中的属性,其中data(类型为Uri)的稍微复杂。

Intent

intent中的重要属性:
action String
category String
data Uri
mComponent ComponentName

有时候说不到广播,除了action要匹配上,还需要其他过滤条件。 比如apk安装、卸载的相关广播:Intent.ACTION_PACKAGE_ADDED、Intent.ACTION_PACKAGE_CHANGED,需要添加DataScheme="package";
再比如外置存储设备(sd卡,U盘在电视上)挂载,Intent.ACTION_MEDIA_MOUNTED,需要添加DataScheme="file"。

data

data是Uri类型,包含scheme、host、port、path、authority、extra等属性。
如安装应用的Intent:{ act=android.intent.action.PACKAGE_ADDED dat=package:com.vk.tv flg=0x4000010 (has extras) }
data是package:com.vk.tv,data内细分,
scheme是package,
SchemeSpecificPart是com.vk.tv,
其他的属性没用到,所以是空。

再比如存储设备挂载的Intent:{ act=android.intent.action.MEDIA_MOUNTED dat=file:///storage/01FF-02E7 flg=0x5000010 (has extras) }
data是file:///storage/01FF-02E7 ,data内的部分,
scheme是file,
SchemeSpecificPart是///storage/01FF-02E7,
path是/storage/01FF-02E7,(这个广播跟文件有关,所以有path)
PathSegments是[storage, 01FF-02E7]
LastPathSegments是01FF-02E7

extra是Bundle,就是用putInt等方法携带的值。

  • 收不到部分系统广播
    收不到部分系统广播,就是除了action,还有DataScheme等过滤条件。
    xml中的写法
<intent-filter>
    <action android:name="android.intent.action.PACKAGE_ADDED" />
    <data android:scheme="package" />
</intent-filter>

java中的写法

intentFilter2.addAction(Intent.ACTION_MEDIA_MOUNTED);
intentFilter2.addDataScheme("file");
  • 多IntentFilter分开
    IntentFilter中可以添加多个Action,但有时添加了DataSchema后可能导致部分Action无法使用,这是要用多个IntentFilter分开。
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.PACKAGE_ADDED" />
    <data android:scheme="package" />
</intent-filter>
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, intentFilter);

intentFilter2.addAction(Intent.ACTION_MEDIA_MOUNTED);
intentFilter2.addDataScheme("file");
registerReceiver(mReceiver, intentFilter2);

Category

一般配置action,或者data、type使用,如启动主Activity都需要配置Category=CATEGORY_LAUNCHER。
例如:am start -n "ru.swlinks.gdch.rulaunch/ru.swlinks.gdch.rulaunch.ui.PreActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
指定了component、action、category。

Type

比如,设置action为ACTION_VIEW,通知指定Type=Image。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行判定。

Component

component包含pkg和className,setClass(class)其实是封装为component