【发布时间】:2010-10-06 11:46:06
【问题描述】:
我想从我的 Android 应用程序中启动已安装的软件包。我认为使用意图是可能的,但我没有找到这样做的方法。有链接吗,在哪里可以找到资料?
【问题讨论】:
-
如果我从第一个应用程序打开第二个应用程序然后直接单击第二个应用程序的图标会发生什么情况,我会得到两个应用程序实例,这是不受欢迎的。如何管理它??
标签: java android kotlin android-intent
我想从我的 Android 应用程序中启动已安装的软件包。我认为使用意图是可能的,但我没有找到这样做的方法。有链接吗,在哪里可以找到资料?
【问题讨论】:
标签: java android kotlin android-intent
如果您不知道主要活动,则可以使用包名来启动应用程序。
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) {
startActivity(launchIntent);//null pointer check in case package name was not found
}
【讨论】:
CATEGORY_INFO 类别中查找主要活动,然后在 CATEGORY_LAUNCHER 类别中查找主要活动。如果都没有找到,则返回 null。"
我找到了解决方案。在应用程序的清单文件中,我找到了包名称:com.package.address 和我要启动的主要活动的名称:MainActivity 以下代码启动此应用程序:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
【讨论】:
我知道这已经得到解答,但我是这样实现的:
Intent intent = getPackageManager().getLaunchIntentForPackage("com.package.name");
if (intent != null) {
// We found the activity now start the activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else {
// Bring user to the market or let them choose an app?
intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("market://details?id=" + "com.package.name"));
startActivity(intent);
}
更好的是,方法如下:
public void startNewActivity(Context context, String packageName) {
Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
if (intent != null) {
// We found the activity now start the activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
// Bring user to the market or let them choose an app?
intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("market://details?id=" + packageName));
context.startActivity(intent);
}
}
删除重复代码:
public void startNewActivity(Context context, String packageName) {
Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
if (intent == null) {
// Bring user to the market or let them choose an app?
intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=" + packageName));
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
【讨论】:
根据评论进行编辑
在某些版本中——如 cmets 中所建议的——抛出的异常可能不同。
因此下面的解决方案稍作修改
Intent launchIntent = null;
try{
launchIntent = getPackageManager().getLaunchIntentForPackage("applicationId");
} catch (Exception ignored) {}
if(launchIntent == null){
startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
} else {
startActivity(launchIntent);
}
原答案
虽然回答得很好,但有一个非常简单的实现可以处理未安装应用程序的情况。我是这样做的
try{
startActivity(getPackageManager().getLaunchIntentForPackage("applicationId"));
} catch (PackageManager.NameNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
}
将“applicationId”替换为您要打开的包,例如com.google.maps等
【讨论】:
PackageManager.getLaunchIntentForPackage(...) 方法返回 null。它不会抛出PackageManager.NameNotFoundException。见here。
startActivity(null),它抛出了 NullPointerException 而不是 PackageManager.NameNotFoundException。
startActivity(Intent intent) 方法被赋予一个空Intent 时,它的预期行为是什么?是什么让你这么说? Android 开发者的documentation 只声明它会抛出一个ActivityNotFoundException。
从 API 30 (Android 11) 开始,您可以使用 launchIntentForPackage 接收 nullpointerexception
val launchIntent: Intent? = activity.packageManager.getLaunchIntentForPackage("com.google.android.gm")
startActivity(launchIntent)
为避免这种情况,您需要将所需的包添加到清单中
<queries>
<package android:name="com.google.android.gm" />
</queries>
这是文档 https://developer.android.com/training/package-visibility
还有中篇 https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9
【讨论】:
根据文档,可以使用Intent.setClassName 启动应用程序的活动。
一个例子:
val activityName = "com.google.android.apps.muzei.MuzeiActivity" // target activity name
val packageName = "net.nurik.roman.muzei" // target package's name
val intent = Intent().setClassName(packageName, activityName)
startActivity(intent)
要在当前应用之外打开它,请在启动 Intent 之前添加此标志。
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
相关回答here
【讨论】:
这将涵盖所有场景
1.获取包的意图
2.如果intent为null,将用户重定向到playstore
3.如果打开 playstore 出现问题,则在默认浏览器上打开。
var intent = activity!!.packageManager.getLaunchIntentForPackage("com.google.android.youtube")
if (intent == null) {
if (intent == null) {
intent = try {
Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.youtube"))
} catch (e: Exception) {
Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.youtube"))
}
}
startActivity(intent)
对于 Android 11(API 级别 30)或更高版本,在 AndroidManifest.xml 中,
<queries>
<package android:name="com.google.android.youtube" />
<package android:name="com.example.app" />
</queries>
或者我们可以允许所有包(不推荐)
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
参考文献
【讨论】:
如果未安装包,请传递包名称和要显示的消息 ;-)
void openApp(String appPackageName,String message){
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(appPackageName);
if (launchIntent != null) {
startActivity(launchIntent);
} else {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
【讨论】:
在科特林中
fun openApplicationOrMarket(packageName: String) {
var intent = requireContext().packageManager.getLaunchIntentForPackage(packageName)
if (intent == null) {
intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("market://details?id=$packageName")
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(intent)
}
【讨论】:
// in onCreate method
String appName = "Gmail";
String packageName = "com.google.android.gm";
openApp(context, appName, packageName);
public static void openApp(Context context, String appName, String packageName) {
if (isAppInstalled(context, packageName))
if (isAppEnabled(context, packageName))
context.startActivity(context.getPackageManager().getLaunchIntentForPackage(packageName));
else Toast.makeText(context, appName + " app is not enabled.", Toast.LENGTH_SHORT).show();
else Toast.makeText(context, appName + " app is not installed.", Toast.LENGTH_SHORT).show();
}
private static boolean isAppInstalled(Context context, String packageName) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException ignored) {
}
return false;
}
private static boolean isAppEnabled(Context context, String packageName) {
boolean appStatus = false;
try {
ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName, 0);
if (ai != null) {
appStatus = ai.enabled;
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return appStatus;
}
【讨论】:
试试下面的代码:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("package_name", "Class_name"));
if (intent.resolveActivity(getPackageManager()) != null)
{
startActivity(intent);
}
【讨论】:
private fun openOtherApp() {
val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
startActivity(sendIntent)
finishAffinity()
}
【讨论】:
// check for the app if it exist in the phone it will lunch it otherwise, it will search for the app in google play app in the phone and to avoid any crash, if no google play app installed in the phone, it will search for the app in the google play store using the browser :
public void onLunchAnotherApp() {
final String appPackageName = getApplicationContext().getPackageName();
Intent intent = getPackageManager().getLaunchIntentForPackage(appPackageName);
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else {
onGoToAnotherInAppStore(intent, appPackageName);
}
}
public void onGoToAnotherInAppStore(Intent intent, String appPackageName) {
try {
intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("market://details?id=" + appPackageName));
startActivity(intent);
} catch (android.content.ActivityNotFoundException anfe) {
intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("http://play.google.com/store/apps/details?id=" + appPackageName));
startActivity(intent);
}
}
【讨论】:
这是我的示例,如果有人发现它有用,则从我的应用程序启动条码/二维码扫描仪
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage("com.google.zxing.client.android");
try
{
startActivityForResult(intent, SCAN_REQUEST_CODE);
}
catch (ActivityNotFoundException e)
{
//implement prompt dialog asking user to download the package
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(this);
downloadDialog.setTitle(stringTitle);
downloadDialog.setMessage(stringMessage);
downloadDialog.setPositiveButton("yes",
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialogInterface, int i)
{
Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try
{
myActivity.this.startActivity(intent);
}
catch (ActivityNotFoundException e)
{
Dialogs.this.showAlert("ERROR", "Google Play Market not found!");
}
}
});
downloadDialog.setNegativeButton("no",
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int i)
{
dialog.dismiss();
}
});
downloadDialog.show();
}
【讨论】:
启动新活动的步骤如下:
1.获取包的意图
2.如果intent为null,将用户重定向到playstore
3.如果intent不是null打开activity
public void launchNewActivity(Context context, String packageName) {
Intent intent = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.CUPCAKE) {
intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
}
if (intent == null) {
try {
intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("market://details?id=" + packageName));
context.startActivity(intent);
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + packageName)));
}
} else {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
【讨论】:
如果您想打开另一个应用程序的特定活动,我们可以使用它。
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try
{
startActivity(intent)
}catch(ActivityNotFoundException e){
Toast.makeText(context,"Activity Not Found",Toast.LENGTH_SHORT).show()
}
如果您必须需要其他应用程序,您可以显示一个对话框,而不是显示 Toast。使用对话框,您可以将用户带到 Play-Store 以下载所需的应用程序。
【讨论】:
com.android.settings.fuelgauge.PowerUsageSummary 只是com.android.settings.Settings$PowerUsageSummaryActivity 的activity-alias,它是removed in Android Pie,所以我进行了编辑以使这个答案适合Pie。请注意,它也与旧版本兼容,请参阅 2011 年 11 月 10 日的 AOSP 提交 af9252849fd94c1f2859c56a4010900ea38a607e 等
如果您知道已安装的包所响应的数据和操作,您只需在启动之前将这些信息添加到您的意图实例。
如果您有权访问其他应用的 AndroidManifest,则可以在其中查看所有需要的信息。
【讨论】:
由于最近 kotlin 变得非常流行,我认为在 Kotlin 中也提供一个简单的解决方案是合适的。
var launchIntent: Intent? = null
try {
launchIntent = packageManager.getLaunchIntentForPackage("applicationId")
} catch (ignored: Exception) {
}
if (launchIntent == null) {
startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")))
} else {
startActivity(launchIntent)
}
【讨论】:
在 Kotlin 中,使用此代码从您当前的活动中启动另一个应用程序
var intent = packageManager.getLaunchIntentForPackage("com.bankid.bus")
//var intent = this.packageManager.getLaunchIntentForPackage("com.bankid.bus")
if (intent != null) {
// We found the activity now start the activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
} else {
// Bring user to the market or let them choose an app?
intent = Intent(Intent.ACTION_VIEW)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.data = Uri.parse("market://details?id=" + "com.bankid.bus")
startActivity(intent)
}
对于 android 版本 10+,您还需要在 AndroidManifest.xml 文件中添加标签,否则 getLaunchIntentForPackage() 将返回 null 即
<queries> <package android:name="com.bankid.bus" /> </queries>
【讨论】: