android IntentFilter详解

1.由一个问题引发的思考:

对于启动一个广播,静态注册一个广播,intent-filter中什么也不设置,在发送广播中对intent也不设置,是否可以匹配到?

写代码验证,直接编译不通过:

Missing one of the key attributes 'action#name,category#name' on element intent-filter at AndroidManifest.xml:20:13-25:29

2.IntentFilter过滤规则的全面学习

(1)IntentFilter的解释:

/**
 * Structured description of Intent values to be matched.  An IntentFilter can
 * match against actions, categories, and data (either via its type, scheme,
 * and/or path) in an Intent.  It also includes a "priority" value which is
 * used to order multiple matching filters.
 *
 * 

IntentFilter objects are often created in XML as part of a package's * {@link android.R.styleable#AndroidManifest AndroidManifest.xml} file, * using {@link android.R.styleable#AndroidManifestIntentFilter intent-filter} * tags.

意思就是IntentFilter是和intent相匹配的,其中action,category,组成了匹配规则。同时intentFilter还可以设置优先级,其中默认是0,范围是【-1000,1000】,值越大优先级越高。并且IntentFilter多被通过AndroidManifest.xml的形式使用。

(2)使用场景

activity的隐式启动和广播的匹配

(3)IntentFilter的匹配规则

IntentFilter的过滤信息有action,category,data.一个组件可以包含多个intent-filter,一个intent只要能完全匹配一组intent-filter即可成功的启动对应的组件。

1.action的匹配规则

intent-filter中必须包含一个action,intent信息中也必须指定一个action。intent-filter中可以有一个或者多个action,只要intent匹配其中的一个action即可。

2.category的匹配规则

intent中可以不指定category,在receiver的intent-filter中也可以不指定category,但是当要隐式启动一个activity是就必须指定android.intent.category.DEFAULT的category。否则系统也会报找不到指定的activity.当intent中指定了一个category时,就会在具有category的intent-filter中去找匹配组件。

3.data的匹配规则

data由两部分组成mimeType和URI.mimeType指媒体类型,比如image/jpeg、audio/*等。

URI的结构为

//:/[ | |]

scheme :URI的模式,比如http、file、content等,如果URI中没有指定scheme,那么整个URI的其他参数无效。

host:URI的主机名,比如www.baidu.com,如果host么有指定那么真个URI的其他参数无效。

port:URI的端口号。

path,pathPattern,pathPrefix:这三个参数指定路径信息

data的规则是如果inent-filter中描述了data,那么必须要在intent中描述匹配的data信息,如果intent-filter中没有描述data信息,那么intent中可以不指定data信息。data的规则中如果intent-filter只指定了mimeType,那么其默认的URI的scheme是file或者content。在intent中就必须同时设置mimeType和URI。如果intent-filter中有多组data,那么intent中只需要匹配一组即可。

例如:

android:name=".MyBroadcastReceiver">
    
        android:name="xcr"/>

        android:mimeType="text/*"/>

        android:name="android.intent.category.ALTERNATIVE"/>
    
public class MainActivity extends AppCompatActivity {
    private static final String TAG ="MainActivityxcr";
    MyBroadcastReceiver mMyBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent= new Intent();
        intent.setAction("xcr");
//        intent.addCategory("xxx");
//        intent.setDataAndType(Uri.parse("file://abc"),"text/*");

        PackageManager manager = this.getPackageManager();
        ComponentName componentName = intent.resolveActivity(manager);
        Log.d(TAG,"componentName =" + componentName);
        startActivity(intent);
        Intent intent1 =new Intent();
        intent1.setDataAndType(Uri.parse("file://abc"),"text/*");
        intent1.setAction("xcr");
        sendBroadcast(intent1);



    }
}

log:

07-14 18:36:27.027 9409-9409/? D/MyBroadcastReceiver: onReceive


(3)可以通过

PackageManager manager = this.getPackageManager();
ComponentName componentName = intent.resolveActivity(manager);

来判断是否有匹配的activity,并且这个方法是过滤了不包含intent-filter中category声明了android.intent.category.DEFAULT的。如果有匹配的activity,那么就会返回都匹配的组件,如果没有就会返回null。




你可能感兴趣的:(android进阶)