参考链接:谷歌中国开发者网站
https://blog.csdn.net/qweewqpkn/article/details/84141614
链接中原文比较详细,这里简介提取要点。
Intent 是一个消息传递对象,可以使用它从其他应用组件请求操作。
可以通过Intent打开一个指定的Activity或者打开某个具有某种功能(例如发邮件)的Ativity去执行某个操作。
基本用例主要包括启动 Activity、启动服务、传递广播。
显式 Intent: 指定一个Activity或服务,开启它,如:
// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);
** 隐式 Intent:** 指定一个功能,然后启动一个包含这个功能的Activity,如:
// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) { //做个保护 防止打开失败(没有应用等原因)
startActivity(sendIntent);
}
创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。 如果 Intent 与 Intent 过滤器匹配,则系统将启动该组件,并向其传递 Intent 对象。 如果多个 Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。
上面展示了显式与隐式intent的例子。Intent 对象携带了 Android 系统用来确定要启动哪个组件的信息,主要包括以下几种:
组件名称:要启动的组件名称。Activity显式需要,隐式不需要。Service一直需要。
操作:指定要执行的通用操作(例如,“查看”或“选取”)的字符串。如ACTION_VIEW,ACTION_SEND
数据:引用待操作数据和/或该数据 MIME 类型的 URI(Uri 对象)。例如,如果操作是 ACTION_EDIT,则数据应包含待编辑文档的 URI。
要仅设置数据 URI,请调用 setData()。 要仅设置 MIME 类型,请调用 setType()。如有必要,您可以使用setDataAndType()
同时显式设置二者(setType,setData两者不可同时调用,会抵消)。
类别:一个包含应处理 Intent 组件类型的附加信息的字符串。 您可以将任意数量的类别描述放入一个 Intent 中,但大多数 Intent 均不需要类别。如:CATEGORY_LAUNCHER
,可以使用 addCategory()
指定类别。
Extra:携带完成请求操作所需的附加信息的键值对。可以使用各种 putExtra() 方法添加 extra 数据,还可以创建一个包含所有 extra 数据的 Bundle 对象,然后使用 putExtras() 将Bundle 插入 Intent 中
标志:在 Intent 类中定义的、充当 Intent 元数据的标志。 标志可以指示 Android 系统如何启动 Activity(例如,Activity 应属于哪个任务),以及启动之后如何处理(例如,它是否属于最近的 Activity 列表)。setFlags() 方法。
如果有多个应用响应隐式 Intent,则用户可以选择要使用的应用,并将其设置为该操作的默认选项。 如果用户可能希望今后一直使用相同的应用执行某项操作(例如,打开网页时,用户往往倾向于仅使用一种网络浏览器),则这一点十分有用。
但是,如果多个应用可以响应 Intent,且用户可能希望每次使用不同的应用,则应采用显式方式显示选择器对话框。 选择器对话框每次都会要求用户选择用于操作的应用(用户无法为该操作选择默认应用)。 例如,当应用使用 ACTION_SEND 操作执行“共享”时,用户根据目前的状况可能需要使用另一不同的应用,因此应当始终使用选择器对话框。
要显示选择器,请使用createChooser()
创建 Intent,并将其传递给 startActivity()。例如:
Intent sendIntent = new Intent(Intent.ACTION_SEND);
...
// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);
// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
要想让自己的Activity接收别人的隐式Intent调用,需要在清单文件中使用 元素为每个应用组件声明一个或多个 Intent 过滤器。
仅当隐式 Intent 可以通过 Intent 过滤器之一传递时,系统才会将该 Intent 传递给应用组件。
注:显式 Intent 始终会传递给其目标,无论组件声明的 Intent 过滤器如何均是如此。
应用组件应当为自身可执行的每个独特作业声明单独的过滤器。例如,图像库应用中的一个 Activity 可能会有两个过滤器,分别用于查看图像和编辑图像。 当 Activity 启动时,它将检查 Intent 并根据 Intent 中的信息决定具体的行为(例如,是否显示编辑器控件)。
每个 Intent 过滤器均由应用清单文件中的
元素定义,并嵌套在相应的应用组件(例如, 元素)中。 在 内部,您可以使用以下三个元素中的一个或多个指定要接受的 Intent 类型:
< action>
在 name 属性中,声明接受的 Intent 操作。该值必须是操作的文本字符串值,而不是类常量。
< data>
使用一个或多个指定数据 URI 各个方面(scheme、host、port、path 等)和 MIME 类型的属性,声明接受的数据类型。
< category>
在 name 属性中,声明接受的 Intent 类别。该值必须是操作的文本字符串值,而不是类常量。
注:为了接收隐式 Intent,必须将 CATEGORY_DEFAULT 类别包括在 Intent 过滤器中。 方法 startActivity() 和 startActivityForResult() 将按照已申明 CATEGORY_DEFAULT 类别的方式处理所有 Intent。 如果未在 Intent 过滤器中声明此类别,则隐式 Intent 不会解析为您的 Activity。
如:
参考链接
ACTION_IMAGE_CAPTURE 拍照
ACTION_PICK 相册选图
ACTION_SET_ALARM 创建闹钟
案例:
打开相机拍照:
public void TakePhoto() {
Uri mPhotoUri = GetUri(CreateFile("temp.png"));
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
if (intent.resolveActivity(getPackageManager()) != null) { //防止打开相机失败(没有应用)
startActivityForResult(intent, TAKE_PHOTO);
}
}
打开相册:
//调用相册
public void OpenGallery() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, OPEN_GALLERY);}
}
然后拍完后会走到:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_CANCELED) {
Log.d("unity", "user cancel operator!!");
return;
}
switch (requestCode) {
case TAKE_PHOTO: {
StartCrop(mPhotoUri);
}
...
}