在 Android 中,两个 APK(应用程序)之间的切换通常是通过 Intent 来实现的。以下是一些常见的方法和注意事项,帮助你实现两个 APK 之间的切换。
一、启动目标 APK 的主 Activity
1、setPackage 方法
使用 Intent 的 setPackage 方法可启动另一个 APK 的主界面(通常是默认的启动 Activity)。
/**
* 通过包名打开目标 APK 的主 Activity
*/
fun startActivityByPackage() {
//目标 APK 的包名
val packageName = "com.example.twoapkswitch"
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_LAUNCHER)
intent.setPackage(packageName)
startActivity(intent)
}
2、getLaunchIntentForPackage 方法
getLaunchIntentForPackage 可通过包名启动另一个 APK 的主界面(通常是默认的启动 Activity)。其中 PackageManager 是 Android 系统中用于管理应用包信息的工具。
在调用 startActivity 之前,必须检查返回的 Intent 是否为空。如果目标 APK 未安装,或者其 AndroidManifest.xml 中没有定义启动 Activity(即没有设置 android.intent.category.LAUNCHER),则返回的 Intent 会是 null。
如果目标 APK 的启动 Activity 需要特定权限,可能需要在调用方 APK 中声明相应的权限
/**
* 通过 getLaunchIntentForPackage 启动目标 APK 的主 Activity
* 目标 APK 的启动 Activity 必须在 AndroidManifest.xml 中 设置 android.intent.category.LAUNCHER
* 如果目标 APK 的启动 Activity 需要特定权限,可能需要在调用方 APK 中声明相应的权限
*/
fun startActivityByLaunchIntent() {
//目标 APK 的包名
val packageName = "com.example.twoapkswitch"
// 获取目标 APK 的启动 Intent
val intent = packageManager.getLaunchIntentForPackage(packageName)
// 空判断,如果目标 APK 未安装,或者其 AndroidManifest.xml 中没有定义启动 Activity
// (即没有设置 android.intent.category.LAUNCHER),则返回的 Intent 会是 null
intent?.let {
it.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
startActivity(it)
}
}
二、启动目标 APK 的特定 Activity
如果需要启动另一个 APK 中的某个特定 Activity,可以使用 setComponent 或 setClassName 方法。
1、setClassName 方法
/**
* 可以通过指定目标 APK 的 packageName 和目标 Activity 的 className 来启动另一个 APK 中的特定 Activity
*/
fun startActivityByClassName() {
//目标 APK 的包名
val packageName = "com.example.twoapkswitch"
// 目标 Activity 的完整路径
val className = "com.example.twoapkswitch.MainActivity"
val intent = Intent()
intent.setClassName(packageName, className)
startActivity(intent)
}
2、setComponent 方法
/**
* 通过 ComponentName 来指定目标 APK 和 Activity
* 目标 APK 的 Activity 必须在 AndroidManifest.xml 中声明为可导出(exported),并且需要设置合适的权限
*/
fun startActivityByComponentName() {
//目标 APK 的包名
val packageName = "com.example.twoapkswitch"
// 目标 Activity 的完整路径
val className = "com.example.twoapkswitch.MainActivity"
val intent = Intent()
intent.component = ComponentName(packageName, className)
//如果目标 Activity 需要接收数据,可以通过 putExtra 方法传递数据
intent.putExtra("key", "value")
startActivity(intent)
}
三、注意事项
1、目标 Activity 的配置
目标 APK 中的 Activity 必须在 AndroidManifest.xml 文件中声明为可导出(exported),并且需要设置合适的权限。
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2、权限问题
如果目标 APK 的 Activity 没有设置为可导出,或者需要特定的权限,可能需要在调用方 APK 的 AndroidManifest.xml 中声明相应的权限。
<uses-permission android:name="android.permission.INTERNET"/>
3、传递数据
如果需要向目标 Activity 传递数据,可以通过 putExtra 方法。
//目标 APK 的包名
val packageName = "com.example.twoapkswitch"
// 目标 Activity 的完整路径
val className = "com.example.twoapkswitch.MainActivity"
val intent = Intent()
intent.component = ComponentName(packageName, className)
//如果目标 Activity 需要接收数据,可以通过 putExtra 方法传递数据
intent.putExtra("key", "value")
startActivity(intent)