现在的位置: 首页 > 综合 > 正文

Android 应用程序之间的跳转

2018年03月20日 ⁄ 综合 ⁄ 共 4625字 ⁄ 字号 评论关闭
文章目录

http://wiki.eoe.cn/page/Sending_the_User_to_Another_App

 

原文链接:http://developer.android.com/intl/zh-CN/training/basics/intents/sending.html

作者:handsomedylan

Sending the User to Another App

Android最重要的特性之一就是:一个应用可以基于不同的 action,把用户推送到其他应用中去。比如说,如果你想在你的应用中显示一张带有商店地址的地图,你并不需要在自己的应用中去实现一个显示地图的Activity,而是可以通过Intent来发出一个请求来显示这个商店的地址,Android系统会自动帮你打开一个合适的应用。

正如在第一节课——创建你的第一个应用——里学到的,在你的应用中,你必须使用Intents来在你应用里的Activity之间游走。通常你都需要一个显式的Intent,即包含有确切类名信息的Intent.但是当你想要从一个独立应用中去完成一个action,比如打开一个地图,那么你必须使用隐式的Intent. 这节课向你展示,如何创建一个隐式的intent来完成一个特定的action,以及如何使用它来启动一个activity并且在别的应用里实现该action。

创建一个隐式的Intent


创建一个隐式的Intent并不声明要启动的组件的类名,而是声明要执行的一个动作(action),这个action详述了你想要做的事,比如观看,编辑,发送或是获取一些数据。Intent也经常在action里附加相关的数据,比如你想访问的地址,或是你发送邮件的内容。根据你想创建的intent,数据可能是一个Uri或是其它数据类型,也可能不包含任何数据。

如果你的数据是一个Uri,那么你可以很调用一个很简单的Intent()构造函数来定义action和数据。

例如,以下是如何创建一个Intent来打电话,在这里我们用Uri数据来表示电话号码。

1
2
Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

当你的应用通过startActivity来使用该intent时,电话应用程序就会以指定号码启动。

以下是一些其它的intent以及他们的action和Uri数据对:

  • * 访问一个地图:
1
2
3
4
5
// 基于地址的地图上的点
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
//或者基于经纬度
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z参数为缩放级别
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
  • * 访问一个网页:
1
2
Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

其它的隐式intent需要"附加的"其它类型的数据,比如string,你可以通过不同的putExtra()方法来增加一个或多个附加数据。

默认情况下,系统通过intent附加的Uri数据来决定适合的MIME类型,如果你的intent里并没有Uri,那么你需要使用setType()来明确intent相关的数据类型。而确定MIME类型更加明确了哪一类activity才是最应该接受该intent的。

以下是包含附加数据的intent:

  • * 发送带附件的email:
1
2
3
4
5
6
7
8
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// 这个intent不含URI, 所以声明了"text/plain" MIME类型
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // 收件人
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
//你也可以通过传递一组Uri来附加多个数据
  • * 创建一个月历事件。
1
2
3
4
5
6
7
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent.putExtra(Events.TITLE, "Ninja class");
calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

注意 :这个创建月历事件的intent,仅可在API14及以上的版本中才可使用。

注意 :把你的Intent定义的尽可能明确是什么重要的,比如说,如果你想要通ACTION_VIEW来显示一张图片,你应该明确MIME类型为image/* .这样就可以防止误启动别的支持该action的可以显示别的数据类型的应用,比如map应用。

Verify There is an App to Receive the Intent-确保有一个应用接收了Intent


尽管Android平台确保特定的intent会被解析到一个内建的应用程序(比如电话,短信,日历),你仍然需要在使用intent前进行一下确认。

小心: 如果你发起一个在设备上无法被任何应用程序处理的intent,那么你的程序就会崩溃。

为了确认有一个activity能响应该intent,可以使用queryIntentActivities()来获取一个能处理该intent的activity列表,如果返回的列表非空,那么你就可以安全的使用这个intent了。例如:

1
2
3
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;

如果 isIntentSafe为真,那么至少有一个程序会响应该intent,反之,则没有。

** 注意 :** 你应该在程序一开始时就进行该项检查,从而在用户尝试使用该intent之前移除这个功能。如果你知道一个特定的应用程序可以处理这个intent,那么你也可以提共一个链接来让用户下载该应用程序(查看如何在GooglePlay上连接你的产品)

用Intent来启动一个Activity


一旦你创建了你的Intent并设置好了附加信息,就可以调用startActivity()来把它发送到系统中去,如果系统发现多个程序匹配该intent,那么它会显示一个对话框供用户挑选,如图1所示。如果只有一个,系统会直接启动它。

图 1.当多个应用匹配intent会弹出的选择对话框。

1
startActivity(intent);

以下是一个完整的例子,它向你展示了如何创建一个可以访问地图的的intent。先确定有一个可以处理该intent的程序,再启动它。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//创建intent
Uri location 1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
// 确定它可以被处理
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;

// 如果安全的话,启动一个activity
if (isIntentSafe) {
    startActivity(mapIntent);
}

显示一个应用程序选择框


当你调用startActivity()来传递Intent,而且有多个应用程序区配该intent时,用户可以选择一个默认选项(通过选中对话框底的一个checkbox)。这对于一个用户通常想用一个固定程序的action(比如浏览网页和拍照)来说,是很好的,但是对于一个用户更愿意去每次选择不同应用程序来执行的action而言,你需要显式的弹出一个选择对话框,并强制用户每次使用都做出选择。(用户无法选择默认程序)。

图 2. 当你用 createChooser()来强制显示匹配你intent的应用列表时,弹出的选择对话框。

为了显示选择器,调用createChooser()创建一个intent,并将其传给startActivity().比如:

1
2
3
4
5
6
7
8
Intent intent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text. This says something like "Share this photo with"
String title = getResources().getText(R.string.chooser_title);
// 创建并打开一个选择器
Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);

以上把intent传入createChooser()方法,从而显示了一个应用程序选择对话框,并将提供的文字作为对话框标题。

 

 

抱歉!评论已关闭.