Android 之 intent内容解析

2023-11-09

intent

intent中文名字叫做意图,是一个将要执行的动作的抽象的描述,简单来说就是穿的消息,由Intent协助完成各个组件之间的通讯。

既能在Activity之间沟通,又能在Activity与Service之间沟通,也能在Activity与Broadcast之间沟通。它主要完成下列3部分工作:

(1) 标明本次通信请求从哪里来、到哪里去、要怎么走。
(2) 发起方携带本次通信需要的数据内容,接收方从收到的意图中解析数据。
(3) 发起方若想判断接收方的处理结果,意图就要负责让接收方传回应答的数据内容。

intent 属性

Intent对象大致包括7大属性:Action(动作)、Data(数据)、Category(类别)、Type(数据类型)、Component(组件)、Extra(扩展信息)、Flag(标志位)。

元素名称 设置方法 说明与用途
Action setAction 动作,它指定意图的动作行为
Category addCategory 类别,指定意图的操作类别
Data setData 即Uri,它指定动作要操作的数据路径
Component setComponent 组件,它指定意图的来源与目标
Type setType 数据类型,表示一个MIMEtypes的string
Extras putExtras 扩展信息,它指定装载的包裹信息
Flags setFlags 标志位,它指定活动的启动标志

1. Action

一个字符串变量(action 字符串 随便写,一般是包名+action名,为了防止不同应用混淆),用来指定Intent要执行的动作类别。系统提供常见的action有:

Intent 类的系统动作常量名 系统动作的常量值 作用
ACTION_MAIN android.intent.action.MAIN App启动时的入口
ACTION_VIEW android.intent.action.VIEW 向用户显示数据
ACTION_SEND android.intent.action.SEND 分享内容
ACTION_CALL android.intent.action.CALL 直接拨号
ACITON_DIAL android.intent.action.DIAL 准备拨号
ACTION_SENDTO android.intent.action.SENDTO 发送短信
ACTION_ANSWER android.intent.action.ANSWER 接听电话

动作名称既可以通过setAction方法指定,也可以通过构造函数Intent(String action)直接生成意图对象。

当然,由于动作是模糊匹配,因此有时需要更详细的路径, 比如仅知道某人住在天通苑小区,并不能直接找到他家,还得说明他住在天通苑的哪一期、哪栋楼、哪一层、哪一个单元。

Uri和Category便是这样的路径与门类信息,Uri数据可通过构造函数Intent(String action, Uri uri)在生成对象时一起指定,也可通过setData方法指定
(setData这个名字有歧义,实际相当于setUri) Category可通过addCategory方法指定,之所以用add而不用set方法,是因为一个意图允许设置多个Category,方便一起过滤。

<intent-filter>
    <action android:name="com.example.demo.hhhh" /> // 自定义的action 
    <action android:name="android.intent.action.VIEW" /> // 系统提供的action
    ...
</intent-filter>

匹配规则: Action匹配只要有一个与Intent中携带Action相同即可

可以指定一个或者多个action ,Intent 中指定的action 必须与过滤器中列出的某一aciton匹配 即可通过。
intent.setAction 是set方法,所以intent只能指定一个Action请求,多个setAction的话,依最后的set为准。

2.Category

一个包含Intent额外信息的字符串(可以自定义,系统也有提供),用来表示action的类别。常用的category如下:

类型 作用
CATEGORY_DEFAULT 默认的category
CATEGORY_LAUNCHER 决定应用程序是否显示在程序列表里
CATEGORY_BROWSABLE 以通过浏览器打开的类别

我们通过action可以定位到一个组件,但是我还想细分。比方说action是一个小区,我通过action找到了这个人在对应的小区,现在我还想知道这个人他住在小区的哪一栋楼,category相当于楼号。action+category就知道了这个人在哪个小区哪个楼号。

注意:

  1. android.intent.category.DEFAULT 是一种默认的category ,在调用StartActivity()方法的时候会自动将category添加到Intent中。

  2. 匹配规则 : intent filter中可以声明多个category。intent filter声明的category,Intent中可以不全部指定,但是Intent指定的类别,Intent Filter必须全部匹配。也就是说Intent 指定的类别 是Intent filter声明类别的子集。

这也说明了所以当我们执行StartActivity方法,打来另一个组件的时候,由于intent 会默认指定 android.intent.category.DEFAULT ,所以该组件的Intent filter一定要添加上这个默认类别。即 :如果该activity想要通过隐式intent方式激活,那么不能没有任何category设置,至少包含一个android.intent.category.DEFAULT

3.Data

名字起的有点歧义,其实就是Uri,接受一个Uri对象,通常都是以字符串的形式传入到Uri.parse()方法中解析产生,更精确的指定当前Intent能够响应什么类型的数据。

前面我们说Action是小区,category是楼栋,Data就相当于是门牌号了。<data>标签主要配置一下内容。

类型 说明
android:scheme 用于指定数据的协议部分 如http:
android:host 用于指定数据的主机名部分
android:port 用于指定数据的端口部分
android:path 主机名和端口之后的部分。
android:mimeType 指定可以处理的数据类型,允许使用通配符的方式指定

只有data标签中指定的内容和Intent中携带的Data完全一致时,当前活动才能响应该Intent。

4. Component

要启动的组件名称

package com.example.otherapp.test;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.os.Bundle;
import android.util.Log;

import com.example.otherapp.R;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

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

        ComponentName component = getIntent().getComponent();
        String packageName = component.getPackageName(); // 返回android应用包名,而不是组件所在包名 com.example.otherapp
        String className = component.getClassName(); //返回组件所在全包名 com.example.otherapp.test.MainActivity
        
        
        Log.d(TAG, "onCreate: "+packageName);
        Log.d(TAG, "onCreate: "+className);


    }
}
类型 使用 说明
构造函数 intent(当前组件.this,目标组件.class) 启动本地应用
setClass intent.setClass(当前组件.this,目标组件.class) 启动本地应用
setClassName intent.setClassName(应用包名, 组件所在全包名) 可以用于打开外部应用
setComponent intent.setComponent(new ComponentName(应用包名,组件所在全包名); 可以用于打开外部应用
public class IntentActivityDemo1 extends AppCompatActivity {

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

        findViewById(R.id.intent_btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 构造函数
                Intent intent = new Intent(IntentActivityDemo1.this,IntentActivityDemo3.class);
                // setClass
                intent.setClass(IntentActivityDemo1.this,IntentActivityDemo3.class);
                // setClassName
                intent.setClassName("com.example.otherApp","com.example.otherApp.MainActivity");
                // setComponent
                intent.setComponent(new ComponentName("com.example.otherApp","com.example.otherApp.MainActivity"));
                startActivity(intent);
            }
        });
    }
}

注意:

  1. 包名说的的android应用包名,是android应用的唯一标识。 在manifest package属性指定
  2. setClassName内部也是调用的setComponent。
  3. 打开外部应用时,如果两个应用在一个项目可以直接打开,否则,外部应用必须处于运行状态下,才可以,要不然系统找不到。

5. Type

指的是 要执行action的目标Activity所能处理的MIME数据类型 比方说指定intent.setType(“image/*”), 会显示所有支持图片类型的应用。

Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导

注意:
在Intent对象中,Data项和Type项很多时候是互斥使用的。当调用Intent.setType时,之前设定的Data信息就会被清空;反过来,调用Intent.setData时,Type信息也会被清除。可以使用setDataAndType(Uri uri, String type)方法。

6. Extras

intent携带的参数信息都是放在Extras中的。。Intent重载了很多种putExtra方法传递各种类型的参数,包括整型、双精度型、字符串等基本数据类型,甚至Serializable、Parcelable这样的序列化结构。

putExtra方法接受两个参数,第一个参数是键,用于后面从Intent中取值,第二个参数才是真正要传递的数据。
在这里插入图片描述

存数据:



                Intent intent = new Intent(IntentActivityDemo1.this,IntentActivityDemo3.class);
                intent.putExtra("Integer",1);
                intent.putExtra("String","hhhh");
                intent.putExtra("boolean",true);
                ... 
                
                startActivity(intent);

取数据:


				Intent intent = getIntent();
				int num = intent.getIntExtra("Intenger");
				String str = intent.getStringExtra("String");
				Boolean boolean = intent.getBooleanExtar("boolean");
				...
	

只是调用putExtra方法显然不好管理,像送快递一样大小包裹随便扔,不但找起来不方便,丢了也难以知道。所以Android引入了Bundle概念,可以把Bundle理解为超市的寄包柜或快递收件柜,大小包裹由Bundle统一存取,方便又安全。
Bundle内部用于存放消息的数据结构是Map映射,既可添加或删除元素,还可判断素是否存在。开发者若要把Bundle数据全部打包好,只需调用一次意图对象的putExtra方法;若要把Bundle数据全部取出来**,也只需调用一次意图对象的getExtras方法**

Bundle对各类型数据的读写方法说明如下:

数据类型 读方法 写方法
整型数 getInt putInt
浮点数 getFloat putFloat
双精度数 getDouble putDouble
布尔值 getBoolean putBoolean
字符串 getString putString
字符串数组 getStringArray putStringArray
字符串列表 getStringArrayList putStringArrayList
可序列化结构 getSerializable putSerializable

示例代码:

存数据:

// 创建一个意图对象,准备跳到指定的活动页面
Intent intent = new Intent(this, ActReceiveActivity.class);
Bundle bundle = new Bundle(); // 创建一个新包裹
// 往包裹存入名为request_time的字符串
bundle.putString("request_time", DateUtil.getNowTime());
// 往包裹存入名为request_content的字符串
bundle.putString("request_content", tv_send.getText().toString());
intent.putExtras(bundle); // 把快递包裹塞给意图
startActivity(intent); // 跳转到意图指定的活动页面

取数据:


// 从上一个页面传来的意图中获取快递包裹
Bundle bundle = getIntent().getExtras();
// 从包裹中取出名为request_time的字符串
String request_time = bundle.getString("request_time");
// 从包裹中取出名为request_content的字符串
String request_content = bundle.getString("request_content");


7. Flags

Intent的运行模式,与activity的启动模式相辅相成。用来指示系统如何启动一个Activity,可以通过setFlags()或者addFlags()可以把标签flag用在Intent中。

类型 作用
FLAG_ACTIVITY_CLEAR_TOP 相当于SingleTask
FLAGE_ACTIVITY_SINGLE_TOP 相当于SingleTop
FLAG_ACTIVITY_NEW_TASK 类似于SingleInstance
FLAG_ACTIVITY_NO_HISTORY 当离开该Activity后,该Activity将被从任务栈中移除

参考链接

  1. 如何通过浏览器链接启动本地 Activity
  2. Action、Category、Data以及匹配规则
  3. 官方:intent和intent过滤器
  4. Intent解析
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 之 intent内容解析 的相关文章

  • Android 中读取未提交的事务

    我正在进行大量数据库操作 这会向我的数据库添加大约 10 000 条记录 由于这可能需要很长时间 因此最好使用事务 db startTransaction do write operations db setTransactionSucce
  • Android 中的短信编码

    我的问题是我想发送特定类别和特定编码的短信 0 类和 7 位编码 当检查 Android Telephony SmsManager 和 SmsMessage 时 您无能为力 SmsManager 提供两个功能 发送文本消息和发送数据消息 如
  • cordova - 删除不必要的权限

    我需要在游戏中播放声音 因此我将 org apache cordova media 插件添加到我的应用程序中 现在platforms android AndroidManifest xml包含2个我不需要的条目
  • 无法从视图转换为按钮

    我在这里遇到非常令人沮丧的问题 我有这个代码 Button b findViewById android R id button1 我收到了这个错误 类型不匹配 无法将表单视图转换为按钮 但是按钮1is一个按钮 在我的 XML 布局文档中
  • Android 上的嵌套滚动

    我们的活动中有一个主要的水平滚动视图 以及嵌套在其中的几个垂直滚动视图 这个想法是水平滚动 直到找到所需的垂直列表 然后上下滚动 理想情况下 一旦开始垂直滚动 我希望垂直滚动具有 锁定 现在会发生什么 如果您非常小心 您可以垂直滚动 但如果
  • Android - 如何设置所有屏幕的背景颜色?

    维护字体和颜色样式的最佳实践是什么 我制作了一个 color xml 文件 用于更改按钮等单独元素的颜色 但我不确定 Android 希望开发人员如何组织他们的样式 例如 我希望所有屏幕都具有相同的背景颜色 我怎么做 我需要为每个 Acti
  • Android - 对话框内VideoView的MediaController出现在对话框后面

    我有一个VideoView在自定义对话框中 我正在为VideoView即时并将其分配给VideoView在代码中 但是控制器实际上并没有出现在视频上 它出现在对话框后面 知道如何让控制器位于视频上方吗 我创建了一个静态对话框帮助器类来帮助构
  • 如何在android中播放内部和外部SD卡中的mp3文件?

    我正在开发一个 mp3 播放器应用程序 它可以播放内部 SD 卡内任何位置的 mp3 文件 我使用以下代码来获取内部存储中存在的 mp3 文件 ArrayList
  • 即时应用程序上的文本转语音崩溃

    我正在实现一个即时应用程序 该应用程序利用 Android 设备上提供的文本转语音功能 我已经设法得到了TextToSpeech按照 Android 开发博客文章中详细说明的说明 实例已初始化并可在非即时应用程序中正常工作Android 中
  • 喷气背包中不同类型的宽度组成

    我正在 jetpack compose 的文本字段中工作 我想建立这样的东西 TextField value value onValueChange value it modifier Modifier requiredWidth 56 d
  • 当我单击 GridView 项时返回 ImageView 实例

    当我点击GridView项时如何返回ImageView实例 我为 ItemClick 创建自定义绑定事件 public class ItemClickSquareBinding MvxBaseAndroidTargetBinding pri
  • Android appwidget 远程视图未更新

    当我从某些活动更新小部件时 列表远程视图不会更新 我的意思是刷新自身 它会出现直到应用程序小部件的更新 日志显示 但不会进入列表视图的适配器以用新数据填充它 public void onUpdate Context context AppW
  • Android:了解 OnDrawFrame、FPS 和 VSync (OpenGL ES 2.0)

    一段时间以来 我在 Android 游戏中遇到了运动精灵间歇性 卡顿 的情况 这是一个非常简单的 2D OpenGL ES 2 0 游戏 这是一个持续存在的问题 我已经多次重新访问过 在我的游戏循环中 我有 2 个 计时器 一个用于记录前一
  • 尝试在后台使用 AsyncTask 解析 JSON 时强制关闭

    我是 Android 开发新手 正在研究 json 数据 我设法让解析工作 我想显示一个 ProgressDialog 我读到我需要使用 AsyncTask 但由于某种原因 一旦我将相同的工作代码放入 doInBackground 中 即使
  • 我收到“循环依赖”Android Dagger Hilt 错误

    我从头开始检查了所有内容 但找不到错误 我找不到错误 可能是什么 我收到以下编译错误 HomeViewModel java 6 error ComponentProcessor MiscError dagger internal codeg
  • 如何在清单文件中添加符合我意图的标志

    我们知道 我们可以使用 java 代码中的 addFlags 方法将一些标志添加到我们的意图中 有什么方法可以将这些标志添加到清单文件本身中 而不是用 java 代码编写 我需要为清单中的一项活动添加 REORDER TO FRONT 标志
  • Visual Studio代码无法检测到模拟器设备或连接的电话

    I was running my app with vscode using Android emulator or my phone however all of a sudden vscode could not identify an
  • 在片段视图之间切换

    在 xml 布局文件中声明片段的标准方法是
  • Flutter 中 Android RecyclerView.SCROLL STATE IDLE 的等价物是什么

    Android 给出的滚动状态如下RecyclerView SCROLL STATE IDLE它告诉用户何时停止滚动 我找不到任何选择在颤动中Pageview or ListView滚动监听器 我的问题 我需要检测 PageView 中的向
  • 从 NDK 获取应用程序名称

    我需要从本机端获取我的 Android 应用程序的名称 如下所示 android content context context android content context this current activiy Resources

随机推荐

  • 计算机科学导论(5):计算机网络

    原文链接 计算机科学导论 5 计算机网络 远行的舟 参考 纪录片 互联网时代 计算机科学导论 TCP IP 入门经典 维基百科 阮一峰老师博客 哈尔滨工业大学阿里巴巴技术联盟互联网笔试面试整理 HTTP 权威指南 1776 年 3 月 瓦特
  • 几种负荷预测方法及其应用

    1 趋势分析法 趋势分析法称之趋势曲线分析 曲线拟合或曲线回归 它是迄今为止研究最多 也最为流行的定量预测方法 它是根据已知的历史资料来拟合一条曲线 使得这条曲线能反映负荷本身的增长趋势 然后按照这个增长趋势曲线 对要求的未来某一点估计出该
  • rust 学习笔记1

    RUST Rust 语言是一种高效 可靠的通用高级语言 其高效不仅限于开发效率 它的执行效率也是令人称赞的 是一种少有的兼顾开发效率和执行效率的语言 Rust的应用 Rust 语言可以用于开发 传统命令行程序 Rust 编译器可以直接生成目
  • MFC 单文档中添加OnPaint

    单文档中添加OnPaint 方法 1 在xxxView h里添加 生成的消息映射函数 protected DECLARE MESSAGE MAP public afx msg void OnPaint 2 实现OnPaint 3 在xxxV
  • 微信小程序渗透测试

    一 工具准备 burpsuite 夜神模拟器 把微信装好 node js wxappUnpacker 二 获取源码 1 配置Burp和模拟器 模拟器需导入ca证书 打开模拟器的WLAN gt 高级设置 gt 输入物理机的ip以及一个没被占用
  • Gof23设计模式之原型模式

    1 概述 用一个已经创建的实例作为原型 通过复制该原型对象来创建一个和原型对象相同的新对象 2 结构 原型模式包含一下角色 抽象原型类 规定了具体原型对象必须实现的clone 方法 具体原型类 实现了抽象圆形类的clone 方法 它是可被复
  • ASP.NET开发公众号时微信支付遇到签名错误

    请求返回来xml数据
  • 7-21 口罩发放(标准注释+测试点说明)

    为了抗击来势汹汹的 COVID19 新型冠状病毒 全国各地均启动了各项措施控制疫情发展 其中一个重要的环节是口罩的发放 某市出于给市民发放口罩的需要 推出了一款小程序让市民填写信息 方便工作的开展 小程序收集了各种信息 包括市民的姓名 身份
  • 事件流及事件处理程序总结

    事件流 事件捕获阶段 处于目标阶段 事件冒泡阶段 事件捕获与事件冒泡的区别 如何阻止事件的默认行为 以及如何阻止事件冒泡 事件捕获和事件冒泡的概念是相反的 事件捕获 不具体的节点更早接收到事件 而最具体的节点最后接收到事件 DOM2级事件
  • EndNote在Word中插入文献不能自动生成编号 - 解决方案

    本文出处 新浪博客 小数码植物摄影 之http blog sina com cn s blog 629be3eb0100sih3 html 新浪博客 小数码植物摄影 首页 http blog sina com cn u 1654383595
  • Android Studio中怎样引用图片资源

    随着不断接触Android Studio 越来越发现和Eclipse有着巨大的差别 不管是表面的目录结构 还是内在对各种资源的管理 本篇就来聊聊Android Studio中怎样来显示图片 以及与Eclipse中的差别 在Eclipse中依
  • requests爬虫遇到404怎么办_Python爬虫基础库和实践

    爬虫有三大基础库Requests BeautifulSoup和Lxml 这三大库对于初学者使用频率最高 现在大家一起来看看这基础三大库的使用 Requests库 Requests库的作用就是请求网站获取网页数据 Code res reque
  • C# Modbus Rtu实现

    Modbus Rtu的实现与Modbus Tcp的实现类似 C ModBus Tcp的学习及Master的实现 我们还是需要借用一个开源库NModbus4 在vs中 打开NuGet管理器 安装NModbus4 具体实现 具体实现与之前的Mo
  • 主流大语言模型的技术原理细节

    作者 spring 1 比较 LLaMA ChatGLM Falcon 等大语言模型的细节 tokenizer 位置编码 Layer Normalization 激活函数等 2 大语言模型的分布式训练技术 数据并行 张量模型并行 流水线并行
  • Vue组件(插槽)

    1 插槽属于Vue组件的三个核心之一 其余两个分别是属性和事件 今天主要学习插槽的使用 2 插槽 slot 将子组件和父组件进行组合 可以弥补视图的不足 是组件具有更好的拓展性 组件的封装方式 抽取共性 3 插槽的使用方式 1 vue2 0
  • 解决'Unknown custom element'问题

    报错截图 解决方法 模板少写了一个 然后删除多余的模板就行啦
  • 如何安装mysql5.7包_安装mysql 5.7 最完整版教程

    安装环境 CentOS7 64位 MINI版 安装MySQL5 7 1 配置YUM源 在MySQL官网中下载YUM源rpm安装包 http dev mysql com downloads repo yum 下载mysql源安装包 shell
  • anaconda python3.8目录_Linux系统下Anaconda的安装和使用教程

    一 Anaconda的安装 去官网下载 https www anaconda com products individual 下载到本地后利用FileZilla软件上传到服务器 我这里上传到了 data bioinfosoftware文件夹
  • vcpkg编译第三方库leveldb

    vcpkg编译leveldb 1 安装vcpkg 使用git命令直接pull vcpkg源码 git clone https github com microsoft vcpkg 2 在vcpkg目录执行bootstrap vcpkg ba
  • Android 之 intent内容解析

    文章目录 intent intent 属性 1 Action 匹配规则 Action匹配只要有一个与Intent中携带Action相同即可 2 Category 注意 3 Data 4 Component 5 Type 6 Extras 存