Android Training - 和其他程序交互(1) - 发送用户请求给另外一个程序
Android很重要的一个特征就是,一个程序可以发送用户请求给其他程序去执行特定的动作。例如,如果你想在地图上显示你的公司地址,你不需要建立一个显示地图的activity,你可以使用intent创建一个显示地图的请求,Android系统会开启一个程序显示地图上这个地址。
像第一个教程:Android Training - 建立你的第一个应用程序所说的,你必须使用intent操纵你的activity。通常在程序内部都使用显式的intent,它定义你想启动的组件的明确类名,但是,如果你想在其他程序执行一个动作,比如“显示地图”,你必须使用一个隐式的intent。
这个课程展示了怎么为一个特定动作创建一个隐式的intent,怎么使用它去启动一个activity,然后在其他程序中执行这个特定的动作。
创建一个隐式Intent隐式Intent不是声明组件的类名去启动组件,而是声明一个执行的动作。这些动作指定了你想做的事情,例如,view, edit, send, get。通常也包含和动作关联的数据,比如你想显示的地址,你想发送的电子邮件内容。依靠你创建的intent,数据可能是一个Uri,或者其他类型,或者intent根本不需要任何数据。
如果你的数据是Uri,这有一种简单的Intent()构造函数,你可以使用构造函数定义动作和数据。
例如,下面的代码展示了怎么创建一个intent,使用Uri数据指定电话号码,初始化一个电话呼叫动作:
Uri number = Uri.parse("tel:5551234");Intent callIntent = new Intent(Intent.ACTION_DIAL, number);当程序使用startActivity()调用这个intent时,通话程序取得这个号码开始一个呼叫。
// 基于地址的定位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 param is zoom levelIntent mapIntent = new Intent(Intent.ACTION_VIEW, location);显示网页:
Uri webpage = Uri.parse("http://www.android.com");Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);隐式的intent也支持其他类型的“额外”数据,例如一个字符串。你可以使用putExtra()函数添加一个或者多个额外数据。
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数组附加多类型的数据创建一个事件日程表:
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");提示:这个时间日程表只支持API级别14或者更高版本。提示:尽可能详细的指定你的intent很重要。例如,如果你想使用ACTION_VIEW显示一个图片,你需要定义MIME类型为image/*。防止程序触发intent时显示其他类型的数据。
PackageManager packageManager = getPackageManager()
;List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);boolean isIntentSafe = activities.size() > 0;
如果isIntentSafe为true,那么至少有一个程序可以接收这个intent。如果为false,那么没有任何程序可以处理这个intent。startActivity(intent);
// 创建intentUri location = Uri.parse("geo:0,0?q=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; // 安全开始if (isIntentSafe) { startActivity(mapIntent);}
显示一个程序选择器当你使用startActivity开始一个activity时,如果有多个程序符合这个intent,用户可以选择一个程序作为默认程序(见上图,有一个复选框在对话框的下面)。可以每次都使用相同的程序运行,对用户来说是很友好的体验,例如,打开网页(使用一个浏览器)或者拍照(使用喜欢的摄像头)时。不管怎样,如果一个动作适合多程序运行,用户可能也需要每次选择不同的程序 -- 例如一个“分享”动作,用户可能有很多可以执行分享的程序 -- 你应该明确的显示一个选择对话框,让用户每次都可以选择他们想要的程序(不能选择一个默认项)。Intent intent = new Intent(Intent.ACTION_SEND);...// 从字符串资源取得标题String title = getResources().getText(R.string.chooser_title);// 创建并开始选择器Intent chooser = Intent.createChooser(intent, title);startActivity(chooser);传递intent和对话框标题给createChooser()函数,显示一个程序列表对话框。