Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android Intent

Android Intent详解(最新推荐)

作者:urkay-

Intent是Android中组件间通信的重要机制,用于启动组件、传递数据和描述操作意图,它分为显式Intent和隐式Intent,接下来通过本文给大家介绍Android Intent的相关操作过程,感兴趣的朋友跟随小编一起看看吧

在Android开发中,Intent 是组件间通信的核心机制,用于在Activity、Service、BroadcastReceiver等组件之间传递消息、启动组件或共享数据。它相当于一个“意图”载体,描述了操作的目的、数据和附加信息,是Android组件解耦的关键。

一、Intent 核心作用

二、Intent 类型

根据目标组件的指定方式,Intent分为显式Intent隐式Intent,适用场景不同。

1. 显式 Intent(Explicit Intent)

特点:直接指定目标组件的完整类名(ComponentName),明确告诉系统要启动哪个组件。
适用场景:启动应用内部组件(如本应用的Activity、Service),因为开发者明确知道目标组件的类名。

示例:启动应用内的SecondActivity

// Kotlin
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
// Java
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);

进阶:通过ComponentName指定
如需动态指定组件(如跨进程启动已知类名的组件),可通过ComponentName构造:

val component = ComponentName(packageName, "com.example.app.SecondActivity")
val intent = Intent().setComponent(component)
startActivity(intent)

2. 隐式 Intent(Implicit Intent)

特点:不直接指定目标组件,而是通过“动作(Action)”“类别(Category)”“数据(Data)”等描述操作意图,由系统根据这些信息匹配最合适的组件(如系统浏览器、邮件应用)。
适用场景:启动跨应用组件(如调用系统浏览器打开网页、调用相机拍照),无需知道目标组件的类名。

示例:打开指定网页(调用系统浏览器)

val intent = Intent(Intent.ACTION_VIEW) // 动作:查看内容
intent.data = Uri.parse("https://www.example.com") // 数据:网页地址
startActivity(intent)

系统会匹配所有声明了ACTION_VIEW且支持http协议的组件(通常是浏览器),并让用户选择打开方式。

三、Intent 核心属性

Intent通过一系列属性描述操作意图,核心属性包括ActionCategoryDataTypeExtraFlag等。

1. Action(动作)

一个字符串,描述要执行的操作(如“查看”“发送”“编辑”)。系统预定义了大量Action,也可自定义。

常用系统Action

Action常量含义适用场景
Intent.ACTION_VIEW查看数据打开网页、图片、文档等
Intent.ACTION_SEND发送数据分享文本、图片(调用分享面板)
Intent.ACTION_CALL拨打电话需要CALL_PHONE权限
Intent.ACTION_EDIT编辑数据编辑联系人、图片等
Intent.ACTION_MAIN应用入口launcher启动应用的主Activity

自定义Action
需使用全限定名(避免冲突),如com.example.app.ACTION_CUSTOM,用于应用内组件通信或跨应用约定。

2. Category(类别)

对Action的补充,描述组件的额外特性(如“默认组件”“ launcher入口”)。一个Intent可包含多个Category,系统会匹配所有声明的类别。

常用系统Category

示例:隐式启动时添加默认类别

val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.example.com")
intent.addCategory(Intent.CATEGORY_DEFAULT) // 必须添加,否则可能匹配失败
startActivity(intent)

3. Data 与 Type(数据与类型)

注意DataType会相互覆盖,若需同时设置,需用setDataAndType()而非分别调用setData()setType()

// 正确:同时设置Data和Type
intent.setDataAndType(Uri.parse("content://media/external/images/1"), "image/jpeg")
// 错误:setType()会覆盖Data的类型信息
intent.data = Uri.parse("content://media/external/images/1")
intent.type = "image/jpeg" // 此操作会清除data

4. Extra(附加数据)

键值对形式的附加数据,用于在组件间传递数据(如传递用户ID、文本内容)。支持基本类型、数组、集合,以及实现SerializableParcelable的对象。

存储与获取数据

// 存储数据
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("userId", 123) // 基本类型
intent.putExtra("username", "张三") // 字符串
intent.putExtra("isVip", true) // 布尔值
// 传递对象(需实现Parcelable或Serializable)
val user = User("张三", 20) // 假设User实现了Parcelable
intent.putExtra("user", user)
startActivity(intent)
// 目标组件中获取数据
val userId = intent.getIntExtra("userId", -1) // 第二个参数为默认值
val username = intent.getStringExtra("username") // 可为null
val isVip = intent.getBooleanExtra("isVip", false)
val user = intent.getParcelableExtra<User>("user") // 需指定泛型

注意

5. Flag(标记)

通过addFlags()设置,用于控制组件的启动模式、任务栈(Task)行为等。

常用Flag

Flag作用
Intent.FLAG_ACTIVITY_NEW_TASK启动新任务栈(常用于Service中启动Activity)
Intent.FLAG_ACTIVITY_CLEAR_TOP若目标Activity已在栈中,清除其上方所有Activity
Intent.FLAG_ACTIVITY_SINGLE_TOP若目标Activity在栈顶,则复用,不创建新实例
Intent.FLAG_GRANT_READ_URI_PERMISSION授予Uri的读权限(跨应用访问文件时需用)

示例:启动新任务栈中的Activity(如从Service启动)

val intent = Intent(this, NotificationActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // 必须添加,否则Service中启动会崩溃
startActivity(intent)

四、Intent 过滤器(Intent Filter)

隐式Intent需要通过Intent过滤器匹配目标组件。过滤器在AndroidManifest.xml中声明,用于告诉系统“该组件能处理哪些Intent”。

一个组件可声明多个过滤器,只要Intent匹配其中一个即可启动该组件。

过滤器匹配规则

Intent与过滤器的匹配需满足3个条件(全部匹配):

  1. Action匹配:Intent的Action必须在过滤器的action列表中(或过滤器无Action,Intent也无Action)。
  2. Category匹配:Intent的所有Category必须在过滤器的category列表中(过滤器至少包含CATEGORY_DEFAULT,否则隐式启动失败)。
  3. Data/Type匹配:Intent的Data/Type需与过滤器的data规则匹配(如协议、MIME类型)。

示例:为Activity配置过滤器

声明一个能处理“查看图片”和“编辑图片”的Activity:

<activity android:name=".ImageHandlerActivity">
    <intent-filter>
        <!-- Action:支持查看和编辑图片 -->
        <action android:name="android.intent.action.VIEW" />
        <action android:name="android.intent.action.EDIT" />
        <!-- Category:必须包含默认类别 -->
        <category android:name="android.intent.category.DEFAULT" />
        <!-- Data:支持图片类型(image/*),协议不限 -->
        <data android:mimeType="image/*" />
    </intent-filter>
</activity>

当其他应用发送包含ACTION_VIEWCATEGORY_DEFAULTimage/jpeg类型的Intent时,系统会将该Activity列为可选目标。

五、特殊用法

1. 启动组件并获取返回结果

通过Activity Result API(替代旧版startActivityForResult())启动Activity并获取返回数据。

示例:启动相机拍照并获取照片

// 1. 注册结果回调
val takePictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
    if (isSuccess) {
        // 拍照成功,处理照片(photoUri为拍照后保存的路径)
        imageView.setImageURI(photoUri)
    }
}
// 2. 启动相机(photoUri为提前创建的临时文件路径)
val photoUri = createTempPhotoUri() // 自定义方法:创建保存照片的Uri
takePictureLauncher.launch(photoUri)

2. PendingIntent(延迟Intent)

一种特殊的Intent,用于在未来某个时刻由其他组件(如系统服务)执行。常用于通知(Notification)、闹钟(AlarmManager)、快捷方式等场景。

特点

示例:通知中添加PendingIntent(点击通知打开Activity)

// 创建打开DetailActivity的Intent
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("id", 100)
// 创建PendingIntent(FLAG_IMMUTABLE:不可变,安全性更高)
val pendingIntent = PendingIntent.getActivity(
    this,
    0, // 请求码(区分不同PendingIntent)
    intent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
// 构建通知
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("新消息")
    .setContentText("点击查看详情")
    .setSmallIcon(R.drawable.ic_notification)
    .setContentIntent(pendingIntent) // 绑定PendingIntent
    .build()
// 显示通知
notificationManager.notify(NOTIFICATION_ID, notification)

3. 发送广播 Intent

通过sendBroadcast()发送广播,由注册了对应过滤器的BroadcastReceiver接收。

示例:发送自定义广播

// 发送广播
val intent = Intent("com.example.app.ACTION_CUSTOM_BROADCAST")
// 限制广播仅本应用接收(Android 8.0+ 推荐)
intent.setPackage(packageName)
sendBroadcast(intent)
<!-- 注册广播接收器(Manifest中) -->
<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="com.example.app.ACTION_CUSTOM_BROADCAST" />
    </intent-filter>
</receiver>
// 广播接收器实现
class MyReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if ("com.example.app.ACTION_CUSTOM_BROADCAST" == intent.action) {
            // 处理广播
        }
    }
}

六、注意事项

隐式Intent的安全性:Android 10(API 29)后,隐式启动Activity需指定包名(setPackage())或通过resolveActivity()检查是否有匹配组件,否则可能抛出异常:

val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))
if (intent.resolveActivity(packageManager) != null) { // 检查是否有匹配组件
    startActivity(intent)
} else {
    // 提示用户无可用应用
}

总结

Intent 是Android组件通信的“桥梁”,通过显式/隐式方式连接组件,支持数据传递和操作描述。掌握其核心属性(Action、Category、Data、Extra)、过滤器匹配规则,以及特殊用法(PendingIntent、Activity Result),是实现组件交互和跨应用功能的基础。合理使用Intent能大幅提升应用的灵活性和扩展性。

到此这篇关于Android Intent详解(最新推荐)的文章就介绍到这了,更多相关Android Intent内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文