Intent 和 Intent 过滤器

Intent 和 Intent 过滤器

参考链接:谷歌中国开发者网站

https://blog.csdn.net/qweewqpkn/article/details/84141614

链接中原文比较详细,这里简介提取要点。

1.概述

Intent 是一个消息传递对象,可以使用它从其他应用组件请求操作。

可以通过Intent打开一个指定的Activity或者打开某个具有某种功能(例如发邮件)的Ativity去执行某个操作。

基本用例主要包括启动 Activity、启动服务、传递广播。

2.Intent类型

  • 显式 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 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。

3.构建 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() 方法。

4.强制使用应用选择器

如果有多个应用响应隐式 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);
}

5.接收隐式 Intent

要想让自己的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_MAIN 操作指示这是主要入口点,且不要求输入任何 Intent 数据。
  • CATEGORY_LAUNCHER 类别指示此 Activity 的图标应放入系统的应用启动器。 如果 元素未使用 icon 指定图标,则系统将使用 元素中的图标。

6.常见Intent

参考链接

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);
            }
...
}

你可能感兴趣的:(Android基础)