显式Intent
在构造Intent时,写死需要跳转的Activity对应的class。
val intent = Intent(this@MainActivity, SecondActivity::class.java)
startActivity(intent)
隐式Intent
不明确指定想要跳转哪个Activity,而是指定了一系列的action和category信息,交由系统找出合适的Activity去启动。
Demo
- 给SecondActicity加上intent-filter,分别加上action和category。
<activity
android:name=".SecondActivity"
android:exported="true">
<intent-filter>
<action android:name=".second" /> <!-- 此处为用户自定义的字符串 !-->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- 在MainActivity跳转时:
val intent = Intent(".second")
startActivity(intent)
添加category
一个Intent中只能指定一个action,但可以指定多个category。
val intent = Intent(".second")
intent.addCategory( ".myCategory" )
startActivity(intent)
此时跳转失败,因为SecondActivity的category是"android.intent.category.DEFAULT",无法找到匹配的category。
如果在SecondActivity中添加该category,即可正常跳转。
<activity
android:name=".SecondActivity"
android:exported="true">
<intent-filter>
<action android:name=".second" /> <!-- 此处为用户自定义的字符串 -->esa
<category android:name="android.intent.category.DEFAULT" />
<category android:name=".myCategory" />
</intent-filter>
</activity>
打开内置应用——浏览器
使用浏览器打开网址:
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.baidu.com")
startActivity(intent)
让自己的Activity支持打开https的链接:
<activity
android:name=".SecondActivity"
android:exported="true">
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name = "android.intent.action.VIEW" />
<category android:name = "android.intent.category.DEFAULT" />
<data android:scheme = "https" />
</intent-filter>
</activity>
此时再通过刚才的intent打开Activity时,就会有一个弹窗提醒所有可以打开url链接的app:
打开内置应用——拨号盘
val intent = Intent(Intent.ACTION_DIAL)
intent.data = Uri.parse("tel:10086")
startActivity(intent)
Activity跳转时携带数据
向下一个Activity传数据
// 将数据写到intent中(MainActivity)
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("int", 1)
intent.putExtra("bool", false)
intent.putExtra("string", "test")
startActivity(intent)
// 从intent中读数据(SecondActivity)
val intData = intent.getIntExtra("int", 0)
val boolData = intent.getBooleanExtra("bool", false)
val stringData = intent.getStringExtra("string")
Log.d("tag", "$intData, $boolData, $stringData ") // 1, false, test
返回数据给上一个Activity
// MainAcitivity,注册回调
class MainActivity : AppCompatActivity() {
// 需在onCreate之前注册!!!
private val requestLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
// 当获取到ACtivity返回的数据后的回调
if (it.resultCode == RESULT_OK) {
val intent = it.data as Intent
val data = intent.getIntExtra("int", 0)
Log.d("tag", "get result: $data") // get result: 1111
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.button.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
requestLauncher.launch(intent)
}
}
}
// SecondActivity,将数据返回给上一个Activity
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivitySecondBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.button2.setOnClickListener{
val response = Intent().apply {
putExtra("int", 1111)
}
setResult(RESULT_OK, response)
finish()
}
}
}
RegisterForActivityResult介绍_chenrenxiang的博客-CSDN博客
IntentFilter的匹配规则
- 一个Activity可以有多个IntentFilter,一个Intent只要能匹配任何一组IntentFilter,即可成功启动对应的Activity。
- 一个IntentFilter中的action、category和data必须同时满足匹配规则,才算匹配成功。
- IntentFilter中可以设置action、category和data三种过滤信息,每一种信息都可以有多个。
action的匹配规则
- Intent中没有指定action:匹配失败。
- Intent中指定了action:一个IntentFilter中只要能找到该action就算匹配成功。
- action匹配时区分大小写。
category的匹配规则
- Intent中可以不加category:系统会默认添加一个默认的category
android.intent.category.DEFAULT,此时任何IntentFilter都可以匹配成功(IntentFilter中须添加android.intent.category.DEFAULT)。
- Intent中添加了一个或多个category:IntentFilter必须匹配所有的category才算匹配成功。
data的匹配规则
- 与action类似,如果IntentFilter中定义了data,那么Intent中必须也要定义可匹配的data。
data的数据结构
data由两部分组成:
-
mimeType:媒体类型(图片、文本、视频等不同的媒体格式)
image/jpegaudio/mpeg4-genericvideo/*
- URI:资源地址,结构如下:
<schema>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
- 过滤规则实例:
Demo1
<intent-filter>
<action android:name=".test"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*"/>
</intent-filter>
这种规则指定了媒体类型为所有类型的图片,要想匹配这种规则,Intent必须满足:
- mimeType为
image/*
- URI可以不指定,因为有默认值content和file
为了匹配上述规则,一个intent示例如下:
intent = Intent(".test")
intent.setDataAndType(Uri.parse("file://abc"), "image/png")
// 不可单独使用setData和setType,因为会清除对方的值
Demo2
<intent-filter>
<action android:name=".test"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/mpeg" android:scheme="http"/>
<data android:mimeType="audio/mpeg" android:scheme="ftp"/>
</intent-filter>
为了匹配该规则,几个intent示例如下:
intent = Intent(".test")
intent.setDataAndType(Uri.parse("ftp://abc"), "video/mpeg")
// 或者
intent.setDataAndType(Uri.parse("http://abc"), "video/mpeg")
// 或者
intent.setDataAndType(Uri.parse("http://abc"), "audio/mpeg")