Android的重要功能之一就是app可以根据要执行的操作让用户启动另外一个app。例如,app有一个商业地址然后想要在地图上显示,并不需要在app中加一个显示地图的activity,可以直接用Intent创建一个要显示地址的请求,Android系统会启动一个可以显示地图的app。

就像以前讲到的,可以使用Intent在app中的activity之间切换。基本上是使用的明确的Intent,也就是明确定义了要启动的组件的类名。然而,当要启动另外一个app来执行操作时,比如展示地图,就要使用模糊的Intent了。

这里将要介绍如何为特定的操作创建模糊的Intent,和如何使用它来启动其他app中的activity来执行操作。

创建一个模糊的Intent

模糊的Intent不会声明要启动的组件的类名,但是声明要执行的操作。这个操作指定了要做的事情,比如展示,编辑,发送或者获得一些东西。Intent通常包含了操作相关的数据,比如要展示的地址,要发送的email的内容。根据创建的Intent,数据可能是Uri,或者很多其他类型的数据,或者根本就不需要数据。

如果数据是Uri,有一个简单的Intent()构造函数可以定义操作和数据。

例如,这里就是如何创建一个Intent来用代表电话号码的Uri作为数据来启动拨打电话:

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

当app通过调用startActivity()调用Intent时,电话app就会用给的电话号码发起一个电话。

这里有一些其他的Intent和它们的操作还有Uri数据:

  • 显示地图:

 // 地址对应的地图上的点
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);
  • 显示网页:

 Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

另外一些模糊Intent需要其他额外的其他类型的数据,比如字符串。可以使用putExtra()方法来添加其他数据。

默认情况,系统会根据Uri包含的数据决定Intent需要的合适的MIME类型。如果Intent中不包含Uri,通常应该用setType()来指定Intent相关的数据类型。设置MIME类型在后面可以指定哪种activity会接收这个Intent。

这里有一些加了额外数据来指定特殊操作的intent:

  • 发送带附件的邮件

 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"}); // 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"));
// 也可以通过传递Uri的ArrayList来添加多条数据
  • 创建日历事件

 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只在API等级14或更高版本中支持

注意:定义Intent要越明确越好。比如,如果用ACTION_VIEWintent来显示一张图片,应该指定MIME类型为image/*。这样可以防止显示其他类型的数据(比如显示地图)的app被intent调用了。

检测是否有app来接收intent

虽然Android平台保证一些确定的intent会被内置的App(比如电话,email或者日历)处理,但是在调用intent之前也应该加上确认步骤。

注意:如果调用了一个intent,然后设备上没有能处理这个intent的app,程序会崩溃。

要检测是否有可以响应intent的activity的话,调用queryIntentActivities()来获得可以处理Intent的activity列表。如果返回的列表不为空,就可以安全的使用Intent了,例如:

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

如果isIntentSafe为true,那么至少有一个app可以响应intent。如果为false,那么没有app能响应intent。

注意:在activity第一次启动时就应该做这个检测,这样是为了防止在用户打算用intent时你需要屏蔽这个功能。如果明确的知道有一个app可以处理这个intent,也可以提供一个链接让用户来下载app(查看link to your product on Google Play)。

用Intent来启动一个Activity

在创建Intent然后设置附加信息后,调用startActivity()来把它发送给系统。如果系统发现超过一个activity可以处理这个Intent,会显示一个对话框让用户选择用哪个app,如图1所展示的。如果只有一个activity可以处理这个intent,系统会立刻启动它。

 startActivity(intent);

图1.超过一个app可以处理intent时的对话框示例

这里是一个创建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);
}

显示一个app选择器

当用户通过传递Intent给startActivity()来启动一个activity,并且有超过一个app可以响应这个intent。用户可以选择一个默认的使用的app(通过勾选一个对话框下面的复选框;见图1)。当用户每次都要用同一个app时这是个很好的方法,比如打开网页(用户通常只喜欢一种浏览器)或者照相(用户一般只喜欢一种相机)。但是,如果这个动作可以被多个app处理并且用户可能每次都会选择不一样的ap,比如分享功能,用户可能会很多个app来分享,很明显需要显示一个选择对话框,它可以强迫用户每次都选择哪个app来执行操作(用户不能选择默认的app来执行这个操作)。

图2.用createChooser()来保证用户每次都要从列表种选择app的例子

要显示选择器,创建用createChooser()创建一个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().getText(R.string.chooser_title);
// Create and start the chooser
Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);

它显示了能响应传递给createChooser()的intent的app列表对话框并且使用了提供的字符串作为对话框的标题。

上一篇:Android - 和其他APP交互

下一篇:Android - 和其他APP交互 - 获得activity的返回值

Android - 和其他APP交互 - 把用户带到其他app的更多相关文章

  1. Android - 和其他APP交互 - 获得activity的返回值

    启用另一个activity不一定是单向的.也可以启用另一个activity并且获得返回值.要获得返回值的话,调用startActivityForResult()(而不是startActivity()) ...

  2. Android - 和其他APP交互

    一个Android app通常有好几个activity.每个activity显示一个可以让用户执行特殊操作(例如看地图,照相等)的界面.要让用户从一个activity切换到另一个activity,ap ...

  3. Android - 和其他APP交互 - 让其他app启动你的activity

    前面的两篇文章主要讲了一个方面:从app中启动其他app.但是如果你的app可以处理对其他app有用的操作,你的app也应该响应其他app的操作请求.例如,如果你创建了一个社交app可以分享信息和图片 ...

  4. Android开发5:应用程序窗口小部件App Widgets的实现

    前言 本次主要是实现一个Android应用,实现静态广播.动态广播两种改变 widget内容的方法,即在上篇博文中实验的基础上进行修改,所以此次实验的重点是AppWidget小部件的实现啦~ 首先,我 ...

  5. Android 5.0 Default SMS App以及运营商授权SMS App

    已同步更新至个人blog:http://dxjia.cn/2015/08/android-5-default-sms-app/ 题外话:博友们有没有好用的写博客客户端推荐啊,cnblogs推荐的win ...

  6. Android 实现切换主题皮肤功能(类似于众多app中的 夜间模式,主题包等)

    首先来个最简单的一键切换主题功能,就做个白天和晚上的主题好了. 先看我们的styles文件: <resources> <!-- Base application theme. --& ...

  7. Android官方技术文档翻译——Gradle 插件用户指南(4)

    最近赶项目,白天基本没时间,只有晚上在家的时候才能看一看.昨天晚上只翻译完了第四章,今天就只发第四章吧. 本文译自Android官方技术文档<Gradle Plugin User Guide&g ...

  8. [Unity][安卓]Unity和Android Studio 3.0 交互通讯(1)Android Studio 3.0 设置

    [安卓]Android Studio 3.0 JDK安卓环境配置(2017.10) http://blog.csdn.net/bulademian/article/details/78387052 [ ...

  9. 如何用Axure快速制作APP交互原型

    对于产品经理来说,熟练使用一些常用软件是一项十分必要的技能.其中,作为一个专业的快速原型设计工具,Axure RP无疑在产品人心中拥有一个难以撼动的地位.但就要PS一样,虽然足够专业,但同样也会存在使 ...

随机推荐

  1. [ACM] poj 1258 Agri-Net (最小生成树)

    Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37131   Accepted: 14998 Descri ...

  2. hdu1260(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1260 分析:简单dp,dp[i]=min(dp[i-1]+a[i],dp[i-2]); #includ ...

  3. SE 2014年4月13日

    要求自治系统之间建立BGP邻居关系,AS 100 中由于配置疏忽R5上忘记启用BGP,从而导致了黑洞问题出现.从而需要网络工程师们就现状问题进行分析,并且使用相应技术进行完善,使得AS 400 和AS ...

  4. C++ STL源代码学习之算法篇

    ///因为篇幅太长,因此,删去了非常多接口,仅仅分析了内部实现,算法对迭代器的要求也被删去 /// search. template <class _ForwardIter1, class _F ...

  5. 如何添加地图控件到Windows Phone 8的页面中

    原文 如何添加地图控件到Windows Phone 8的页面中 本主题介绍了各种方法来添加一个地图控件到Windows Phone 8的项目.该地图控件在Windows Phone的SDK 8.0的库 ...

  6. Oracle本地管理对照数据字典管理表空间

    Locally vs. Dictionary Managed Tablespaces 整理自:http://www.orafaq.com/node/3. When Oracleallocates sp ...

  7. Windows phone 8 学习笔记(2) 数据文件操作

    原文:Windows phone 8 学习笔记(2) 数据文件操作 Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方 ...

  8. 【Oracle】物理体系结构

     一.ORACLE 物理体系结构 原理结构图 各部分解释: PGA: 私有内存区,仅供当前发起用户使用. 三个作用 用户登录后的session信息会保存在PGA. 运行排序.假设内存不够,orac ...

  9. Javascript语言精粹之String常用方法分析

    Javascript语言精粹之String常用方法分析 1. String常用方法分析 1.1 String.prototype.slice() slice(start,end)方法复制string的 ...

  10. HTTP请求响应过程 与HTTPS区别

    原文:HTTP请求响应过程 与HTTPS区别 HTTP协议学习笔记,基础,干货 HTTP协议 HTTP协议主要应用是在服务器和客户端之间,客户端接受超文本. 服务器按照一定规则,发送到客户端(一般是浏 ...