Intent相关

2020-06-08  本文已影响0人  Yobin_He

一、定义

消息传递的对象,可以用来从其他应用组件请求操作,基本用例如下:

  1. startActivity() 启动新的activity,其中intent可以携带相应的数据,但是携带数据必须可序列化,String和基本数据类型。同时数据携带有大小限制,具体限制大小可以查看该网址

      Intent intent = new Intent(MainActivity.this, SecondActivity.class);
      startActivity(intent);
    
  1. startActivityForResult() 启动新的Acitivity并在新页面返回时候,可携带部分数据返回。注意①如果跳转前页面为fragment,必须重写它依赖的Activity或者父类fragment,否则会出现接收不了情况 ②如果所在fragment在viewpager下,不仅应该重写Acitity,而且应该区别处理回调处理,防止所有fragment收到相关回调。

       Intent intent = new Intent(this, SecondActivity.class);
       startActivityForResult(intent, REQUEST_CODE);
    
  1. 对于API 21之前的版本,可以用intent.startService()来启动服务
  2. 服务旨在使用客户端-服务端接口,通过bindService()将intent传递

二、Intent类型

1.显示调用

​ 通过目标的包名称或者组件名称,启动相应组件。

        //  使用构造函数,传入context,class
//       Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        Intent intent = new Intent();
        //使用className来
        intent.setClassName(MainActivity.this, "com.yobin.testintent.SecondActivity");
        startActivity(intent);
2.隐式调用

不会指定特定的组件,只是声明常规操作,从而允许其他应用中的组件来处理

三、构建Intent

四、CreateChooser()的作用

  1. 如果有多个应用可以响应Intent,选择要使用的应用后,并设置默认选项后,那么每次都会执行该默认操作,但是如果用户希望每次使用不同应用,用createChooser()可以强制显示选择对话框,并且无法设置默认操作。

            Intent sendIntent = new Intent();
            sendIntent.setAction(Intent.ACTION_SEND);
            sendIntent.putExtra(Intent.EXTRA_TEXT, "你好,是什么出现");
            sendIntent.setType("text/plain"); //发送短信
            Intent chooseIntent = Intent.createChooser(sendIntent, "这是选择的应用"); //包裹原始intent
            if (chooseIntent.resolveActivity(getPackageManager()) != null) {//判断该intent是否有activity意图
                startActivity(chooseIntent);
            }
    
  1. 如果没有应用响应,使用原始的startActivtiy,如果没有去resolveActivty方法判断,会抛出ActivityNotFoundException,而用createChooser会显示无应用可以执行操作

  2. 用于过滤不需要的应用显示在弹窗中

     public void clickView(View view) { 
            Intent sendIntent = getIntent(); 
         //遍历查询所有可以打开页面信息
            List<ResolveInfo> resolveInfosNew = context.getPackageManager().queryIntentActivities(sendIntent, 0); 
            List<Intent> targetIntents = new ArrayList<>();
            if (!resolveInfosNew.isEmpty()) { 
                for (ResolveInfo resolveInfo : resolveInfosNew) {
                    ActivityInfo activityInfo = resolveInfo.activityInfo;
                    String packageName = activityInfo.packageName; //可以利用packageName来进行过滤
                    if (!packageName.equals("com.android.bluetooth")) { //需要过滤的蓝牙
                        Intent intent = getIntent();
                        intent.setComponent(new ComponentName(packageName, activityInfo.name));//设置组件信息
                        targetIntents.add(intent);
                    }
                }
            }
    
            if (targetIntents.size() > 0) {
                Intent chooseIntent = Intent.createChooser(new Intent(), "这是选择的应用"); //包裹实际的应用
                //将需要的intent加入到chooseIntent中
                chooseIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{}));
                if (chooseIntent.resolveActivity(getPackageManager()) != null) { //解析是否有intent对应的activity.
                    startActivity(chooseIntent);
                }
            }
        }
    
        public Intent getIntent() { //需要加载的意图
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SEND);
            intent.putExtra(Intent.EXTRA_TEXT, "你好呢,哈哈");
            intent.setType("text/plain");
            return intent;
        }
    

五、接收隐式Intent

要公布应用可以接收哪些隐式Intent,需要在清单文件中使用intent-filter元素为每个应用组件声明一个或多个Intent过滤器,每个过滤器可以有<action>,<data>,<category>三个组成

  1. <action> 声明可以接收的操作,可以自定义,但是该值必须是操作的文本字符串,不可以是类常量

  2. <data> 使用一个或多个指定数据URI(scheme、host、port、path),各个方面和MIME类型属性,声明接收的数据类型。

    注意:每个<data>元素均可以指定URI结构和数据类型,URI包括scheme、host、port、path

    <scheme>://<host>:<port>/<path>

    content://com.yobin.project:200/folder/subfolder/etc
    架构<scheme>:content
    主机<host>:com.yobin.project
    端口<port>:200
    路径<path>:folder/subfolder/etc
    上述属性存在依赖关系
        1. 如果没有指定架构,就忽略主机
        2. 没有指定主机,忽略端口
        3. 未指定主机和架构,忽略路径
        
    当Intent中URI与过滤器中URI规范进行比较时候,仅与过滤器包含的部分URI进行比较
        1. 如果过滤器仅指定架构,则具有该架构的所有URI均与过滤器匹配
        2. 如果过滤器指定架构和权限,但未指定路径,则具有相同架构和权限的所有 URI 都会通过过滤器,无论其路径如何均是如此
        3. 如果过滤器指定架构、权限和路径,则仅具有相同架构、权限和路径的 URI 才会通过过滤器
        注意: 路径规范可以包含星号通配符 (*),因此仅需部分匹配路径名即可
    数据测试会将 Intent 中的 URI 和 MIME 类型与过滤器中指定的 URI 和 MIME 类型进行比较。规则如下:
        1. 仅当过滤器未指定任何 URI 或 MIME 类型时,不含 URI 和 MIME 类型的 Intent 才会通过测试。
        2. 对于包含 URI 但不含 MIME 类型(既未显式声明,也无法通过 URI 推断得出)的 Intent,仅当其 URI 与过滤器的 URI 格式匹配、且过滤器同样未指        定 MIME 类型时,才会通过测试。
        3.仅当过滤器列出相同的 MIME 类型且未指定 URI 格式时,包含 MIME 类型但不含 URI 的 Intent 才会通过测试。
        4.仅当 MIME 类型与过滤器中列出的类型匹配时,同时包含 URI 类型和 MIME 类型(通过显式声明,或可以通过 URI 推断得出)的 Intent 才会通过测试的       MIME 类型部分。如果 Intent 的 URI 与过滤器中的 URI 匹配,或者如果 Intent 具有 content: 或 file: URI 且过滤器未指定 URI,则             Intent 会通过测试的 URI 部分。换言之,如果过滤器只是列出 MIME 类型,则假定组件支持 content: 和 file: 数据
    注意:指定了Intent的URI和MIME类型,如果数据中没有<data>,则匹配失败。      
        
    
  1. <category> name属性中声明接收类别,必须是可以操作的文本字符串值,不能为常量。注意,接收隐式Intent必须将CATEGORY_DEFAULT类别包括在Intent过滤器中,startActivity()和startActivityForResult()将按照其声明类别处理所有Intent,如果没有此声明,那么隐式Intent不会解析Activity.
    <activity android:name="MainActivity">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
   </activity>

    <activity android:name="ShareActivity">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

注意

本文是来源是Android开发者网站,以及部分网址,进行了相关的整理,增加了部分自己的东西。

Android developer

Intent属性详解二 Action、Category

intent隐式调用大全(调用系统的的组件)

createchooser应用选择器

上一篇下一篇

猜你喜欢

热点阅读