一个Android应用一般都有若干个activities。每个activity展示一个用户界面,用于执行特定的用户任务(例如浏览地图或者拍照)。为了让用户从一个activity跳到另一个activity。你的app必须使用一个 Intent
定义你的app想要做某事的“意图”。当你通过调用如 startActivity()
这样的方法传递一个Intent给系统时,系统使用Intent标识和开启合适的应用组件。使用intent甚至可以让你启动其他的app里的activity。
为了启动特定的组件(例如一个特定的Activity实例)intent可以是显示的,也可以是隐式的,为了启动任何可以处理该意图action(例如拍照)的组件。
本文告诉你如何使用Intent执行一些和其他的app交互的基本操作,例如启动另一个应用,从该app接受返回的结果,和响应来自于其他app的intent。
Lessons
Sending the User to Another App
如何产生隐式意图,启动能执行该action的其他的app
Getting a Result from an Activity
如何启动另一个activity,并从该activity获取返回结果
Allowing Other Apps to Start Your Activity
如何定义一个你的app接受的隐式意图的意图过滤器使得你的app里的activity开发给其他应用使用
Sending the User to Another App
Android最重要的特性之一就是基于“action”用户能从一个app跳到另一个app。例如,你的app有一个想要显示在地图的地址,你不必在你的app里创建一个显示地图的activity。你可以产生一个请求展示该地址的意图。然后,Android系统会启动一个能将该地址显示到地图上的app。
如Building Your First App里所解释的,你必须使用intent在你的app里的activity间切换。你一般通过显示意图(定义了你想要启动的组件的确切的类名)实现同一个app里的activity间的切换。然而,当你想要其他的app处理你的app的intent时,例如浏览一个地图,你必须使用隐式意图。
本文讲述如何产生特定操作的隐式意图,以及如何使用隐式意图启动其他的app里的activity来处理你的隐式意图。
Build an implicit Intent
隐式意图并不需要声明启动的组件类名,而是声明一个执行的动作(action)。该action描述了你想做的事情,例如,浏览、编辑、发送或者获取一些数据。intent也可以通过action来附加要传递的数据,例如你想要访问的地址、或者你想要发送的email信息。根据你想要创建的intent,数据可能是一个Uri,或者其他的数据类型,也可能不包含任何数据。
如果你的数据是是一个Uri,那么你可以简单的调用Intent()构造方法来定义action和数据。
例如,下面是如何定义一个intent来打电话,并用Uri来表示电话号码。
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);当你的应用调用startActivity()来启动该Intent时,电话应用程序就会向指定的电话号码打电话。
以下是一些其他的intent,和action和Uri映射对。
- 浏览地图
// Map point based on address Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); // Or map point based on latitude/longitude // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
- 访问一个Web网页
Uri webpage = Uri.parse("http://www.android.com"); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
其它的隐式意图需要“附加的”的其他的数据,比如字符串,你可以使用不同的putExtra()方法来添加一个或者多个“附加”数据。
默认地,系统通过添加到intent里的Uri数据类型累决定适合的MIME类型,如果你的Intent里没有Uri,你应该使用setType()方法来明确intent里的数据类型。更进一步设置MIME类型明确了哪一类的activity解释和处理该意图。
下面是一些intent的例子,通过添加额外的数据来明确期望的action:
- 发送带附件的邮件:
Intent emailIntent = new Intent(Intent.ACTION_SEND); // The intent does not have a URI, so declare the "text/plain" MIME type emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients 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")); // You can also attach multiple items by passing an ArrayList of Uris
- 产生日历事件:
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");
注:仅仅API14或者更高的API支持日历时间的intent。
注:把你的intent定义的尽可能明确是什么重要的。例如,如果你想要展示一个image,你可以使用ACTION_VIEW,同时你也应该指定MIME类型为 image/*
,这防止能浏览其他类型数据的app(例如地图应用)被该intent出发和调起。
Verify There is an App to Receive the Intent
虽然Anroid平台确保特定的intent会被内建app中(例如Phone、Email或者日历应用)的一个处理,你也应该总是在使用前确认有app能处理你的意图。
注意:如果你的发起一个intent,但android设备上没有可以处理你的intent的app,你的app将crash。
为了确保有一个activity能响应的意图,调用queryIntentActivities()方法获得一个能处理你的intent的activity列表。如果返回的list非空,你能安全地使用该intent。例如:
PackageManager packageManager = getPackageManager(); List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); boolean isIntentSafe = activities.size() > 0;如果isIntentSafe是true,那么至少一个app将响应该intent,如果为false,那么没有任何app处理该intent。
注:你应该在你的activity第一次启动时就执行该检查。以防you need to disable the feature that uses the intent before the user attempts to use it。如果你知道一个特点的app能处理该intent,你也能提供一个链接让用户去下载该app(参见如何 link to your product on Google Play)。
Start an Activity with the Intent
一旦你已产生了你的Intent并设置了额外的信息,你能调用startActivity()将该intent发送给系统。如果系统发现不止一个activity能处理该intent,系统将展示一个选择对话框来供用户选择一个app来处理,如图1.如果有仅仅一个activity能处理,系统立即的启动它。
如下是一个复杂点的例子,显示了如何产生一个intent来浏览地图,确保一个存在一个app处理该intent,然后开启它:
// Build the intent Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); // Verify it resolves PackageManager packageManager = getPackageManager(); List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0); boolean isIntentSafe = activities.size() > 0; // Start an activity if it's safe if (isIntentSafe) { startActivity(mapIntent); }
当你嗲用startActivity()方法来传递Intent,而且有许多应用匹配该Intent时,用户可以选择一个默认程序(通过选中如图1的对话框底的一个checkbox)来处理该意图。如果用户每次都想用同一个app来执行某个action时这是十分好的用户体验。
然而,如果一个action能被多个app执行,而用户每次都希望不同的app来执行——例如一个“share”操作用户可能需要一个分享item分享到不同的app——这时你需要明晰的展示一个选择对话框,如图2。该选择对话框迫使用户每次选择一个app来执行action(用户不能选择一个默认app来处理intent)。
为了显示chooser,使用createChooser()来产生Intent,作为参数传递该Intent给startActivity()。例如:
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().getString(R.string.chooser_title); // Create intent to show chooser Intent chooser = Intent.createChooser(intent, title); // Verify the intent will resolve to at least one activity if (intent.resolveActivity(getPackageManager()) != null) { startActivity(chooser); }
如上,把Intent传入createChooser()方法,从而显示了一个应用程序列表对话框,并将提供的文字作为对话框标题。
Getting a Result from an Activity
启动另一个activity不止一种方式。你也能启动一个Activity并接收一个返回结果。为了接收一个结果调用 startActivityForResult()
(而不是startActivity())。
例如,你的app能启动一个照相机应用,接收一个拍摄的照片作为返回结果。或者,你可能要启动一个联系人应用来选择一个联系人,你将接收联系人详情作为返回结果。
当然,响应的activity必须被设计为能返回一个结果。当activity能返回结果时,它通过另一个intent对象来发送返回结果。你的activity能在onActivityResult()回调方法里接收到该结果。
注:当你调用startActivityForResult()
时你能使用显示或者隐式意图。当使用你自己的activity接收结果数据时,你应该使用显式意图确保你的接收到期望的结果。
Start the Activity
当启动有返回结果的activity时,所用的intent并没有什么特别的。但是,你需要传递一个额外的整型参数给startActivityForResult()方法。
整型参数是一个请求码,用于标识你的请求。当你接收到结果意图时,回调提供相同的请求码以便你的app能合理的区分属于你的结果并确定如何处理该结果。
例如,如下显示一个如何开启选择联系人的activity:
static final int PICK_CONTACT_REQUEST = 1; // The request code ... private void pickContact() { Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts")); pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); }
Receive the Result
当后续的Activity执行完成并返回结果时,系统将调用前面的Activity的onActivityResult()方法。该方法包含三个参数:
- 你传递给
startActivityForResult()
的请求码。 - 第二个Activity指定的结果码。如果操作成功结果码将是RESULT_OK,如果由于某些原因用户退出或者操 作失败,其值是RESULT_CANCELED。
- 携带返回结果数据的Intent。
例如,如下显示了如何处理选择联系人intent的返回结果:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // Check which request we're responding to if (requestCode == PICK_CONTACT_REQUEST) { // Make sure the request was successful if (resultCode == RESULT_OK) { // The user picked a contact. // The Intent's data Uri identifies which contact was selected. // Do something with the contact here (bigger example below) } } }
该例子里,由Android的Contract或者People应用返回的结果Intent提供了一个内容Uri,该Uri标识了用户选择的联系人。
为了成功里处理结果,你必须理解结果意图的格式是什么。当返回的结果的activity是你的应用里自己写的activity时,很容易知道是什么格式。然而,Android平台里的app提供了属于自己的APIs,它们有自己特定结果数据。例如,People应用(在一些旧版本的Android平台上是Contact应用)始终返回标识选定联系人的内容Uri,相机应用返回一个Bitmap,该Bitmap放在附加的“data”里(参见类 Capturing Photos)。
Bouns:Read the contact data
上面的代码显示了如何从联系人应用中获取一个返回结果,但并没有涉及从返回结果中获取联系人的获取细节,因为这需要一些有关 content providers的更进一步的知识。然而,如果你是好奇的,下面是如何从返回的联系人结果数据中获取电话号码的代码:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // Check which request it is that we're responding to if (requestCode == PICK_CONTACT_REQUEST) { // Make sure the request was successful if (resultCode == RESULT_OK) { // Get the URI that points to the selected contact Uri contactUri = data.getData(); // We only need the NUMBER column, because there will be only one row in the result String[] projection = {Phone.NUMBER}; // Perform the query on the contact to get the NUMBER column // We don't need a selection or sort order (there's only one result for the given URI) // CAUTION: The query() method should be called from a separate thread to avoid blocking // your app's UI thread. (For simplicity of the sample, this code doesn't do that.) // Consider using CursorLoader to perform the query. Cursor cursor = getContentResolver() .query(contactUri, projection, null, null, null); cursor.moveToFirst(); // Retrieve the phone number from the NUMBER column int column = cursor.getColumnIndex(Phone.NUMBER); String number = cursor.getString(column); // Do something with the phone number... } } }注:Android2.3(API 9)之前,在
Contacts Provider
(如上所示)上执行查询时,要求你的app声明 READ_CONTACTS
权限(参见Security and Permissions)。然而,从Android2.3开始,Contract/People应用给你的app提供一个从Contract Provider读取信息的临时权限。但这个临时权限仅适用于所请求的特定联系人,除非你声明READ_CONTACTS权限,否则不能查询一个在那个intent Uri定义之外的联系人信息。
相关推荐
在Android开发中,应用程序通常由多个Activity组成,每个Activity对应一个用户界面,并负责完成特定的任务。例如,一个Activity可以专门用于显示地图,而另一个可能用于拍照功能。当需要在不同的Activity之间转换,...
《2016-Interacting Multiview Tracker》是一个针对多视图交互追踪技术的研究项目,由韩国国立釜山大学计算机视觉实验室(CVL@GIST)的团队开发。这个项目的主要目标是解决在多个视角下同时跟踪多个目标物体的问题,...
Arduino 101 houses an Intel Curie module which offers a better performance at a lower...Perfect for students, teachers, and hobbyists who need just enough information to get started with the Arduino 101.
**jQuery 与 DOM 交互详解** 在Web开发中,JavaScript是一种不可或缺的语言,它负责与用户进行交互并...在探索`jQuery-Interacting-with-DOM-master`这个压缩包中的文件时,你将有机会亲身体验到jQuery的强大之处。
《ISO IEC TR 23187:2020 Information technology - Cloud computing - Interacting with cloud service partners (CSNs)》是国际标准化组织(ISO)和国际电工委员会(IEC)联合发布的一份技术报告,旨在为云计算...
Now that more people spend more time interacting with mobile apps than with their desktop counterparts, you need to think about your iOS app’s performance the moment you write your first line of code...
【应用】★★★★★-manzana-.NET API for interacting with the Apple iPhone【应用】★★★★★-manzana-.NET API for interacting with the Apple iPhone 1.适合学生学习研究参考 2.适合个人学习研究参考 3.适合...
UNIT 2 - STRINGS, TUPLES, AND INTERACTING WITH THE USER Lesson 7 - Introducing string objects: sequences of characters Lesson 8 - Advanced string operations Lesson 9 - Simple error messages Lesson 10 ...
《manzana-.NET API for interacting with the Apple iPhone》是一个专为与苹果iPhone进行交互而设计的.NET API库。这个源码包对于那些希望在iOS平台上构建应用的开发者来说,是一份宝贵的资源,特别是对.NET框架有...
在所提供的文件信息中,包含了关于长程相互作用自旋链模型在物理研究领域中的热力学性质的研究内容。此模型的研究目的是通过微正则系综方法探讨其热力学性质,并构建系统全局相图以研究热力学相变。...
自述文件该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...
本文将深入探讨标题为“【应用】-manzana-.NET API for interacting with the Apple iPhone.7z”的压缩包,其中包含了一个名为“Manzana”的.NET库,它为开发者提供了一种与Apple iPhone进行交互的方式。 首先,...
【标题】"IOS应用源码之manzana-.NET API for interacting with the Apple iPhone" 提供了一种使用.NET框架与苹果iPhone进行交互的途径。manzana是一个.NET库,它为开发者提供了方便的API,使得在iOS应用开发过程中...
Nitrogen fixation of faba bean interacting with a non-legume in two contrasting intercropping systems,范分良,余常兵,A field experiment was carried out to quantify biological nitrogen fixation (BNF)...
染色质重塑酶INO80复合物的潜在靶基因-BCCIP,苏家明,隋毅,目前认为BRCA2/CDKN1A-相关蛋白BCCIP在肿瘤抑制过程中作为BRCA2的辅助因子发挥重要的作用。已知BCCIP在多种肿瘤中包括卵巢癌、肾癌和大肠�
"Getting Started with OSGi 2 Interacting with the Framework.pdf"接着介绍了如何与OSGi框架交互,包括启动、停止、更新和安装捆绑包。此外,还会讨论如何使用OSGi框架API来管理和控制服务生命周期。 "Getting ...
An interacting multiple model approach for state estimation with non-gaussian noise using a variational bayesian method
《苹果iPhone交互.NET API——Manzana库详解》 在当今移动开发领域,iOS系统以其稳定性和用户友好性获得了广大开发者和用户的喜爱。对于非Objective-C或Swift开发者来说,想要与苹果iPhone进行交互可能会遇到一些...
Interacting with a Database: The Server-Side Connecting to ASP.NET Connecting to ColdFusion Chapter 22. Advanced Ajax Database Interaction Bulk Updates Server-Side XML and JSON Part VI: ...
interacting with data This lecture covers the basics of core concepts in probability and statistics to be used in the course. These include random variables, continuous and discrete distributions, ...