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. 诺贝尔物理学奖公布:LED灯将点亮了整个21世纪

    很多其它精彩.破晓博客:点击打开链接 7日.在瑞典首都斯德哥尔摩,瑞典皇家科学院常任秘书诺尔马克(左二)宣布2014年诺贝尔物理学奖得主.新华社发 ■人物 中村修二 勇于追讨酬劳的科学家 被誉为&qu ...

  2. C++操作符operator的另一种用法

    http://blog.csdn.net/memewry/article/details/7833314 参考地址 今天在程序员面试宝典上看到这样一道题目:  A C++ developer want ...

  3. hdu5046(重复覆盖+二分)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5046 题意:要在n个城市里建造不超过k个机场覆盖所有城市,问机场城市之间最大距离最小为多少. 分析:二 ...

  4. 福利 城市名的python list

    ["上海","北京","北京市","朝阳","朝阳区","海淀","元 ...

  5. leetcode - Pascal&#39;s Triangle

    Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Retu ...

  6. Java8高中并发

    Java8中学并发 本文翻译自:http://jaxenter.com/lean-concurrency-in-java-8-49924.html 转载请注明出处:http://blog.csdn.n ...

  7. Mutex(测量)

    游标共享怎样使用Mutex kks 使用mutex以便保护对于下述基于parent cursor父游标和子游标child cursor的一系列操作 对于父游标parent cursor的操作: 基于发 ...

  8. Debian7.6安装过程中遇到的问题

    一 sudo命令不能用 1 使用su切换到root用户,命令: su 2 使用名:vim /etc/sudoers加入sudoer用户,命令: vim /etc/sudoers 找到root=(ALL ...

  9. CF 553A 组合DP

    http://codeforces.com/problemset/problem/553/A A. Kyoya and Colored Balls time limit per test 2 seco ...

  10. Redis安装及简单測试

    摘要: Redis是眼下业界很受到欢迎的一个内存数据库,一般用作系统的中间缓存系统,用以提升总体商业系统的吞吐量和响应速度.本文将简要介绍安装的主要过程以及给出一个简要的測试代码. 1.  系统环境和 ...