Android - 和其他APP交互 - 把用户带到其他app
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交互 - 获得activity的返回值
Android - 和其他APP交互 - 把用户带到其他app的更多相关文章
- Android - 和其他APP交互 - 获得activity的返回值
启用另一个activity不一定是单向的.也可以启用另一个activity并且获得返回值.要获得返回值的话,调用startActivityForResult()(而不是startActivity()) ...
- Android - 和其他APP交互
一个Android app通常有好几个activity.每个activity显示一个可以让用户执行特殊操作(例如看地图,照相等)的界面.要让用户从一个activity切换到另一个activity,ap ...
- Android - 和其他APP交互 - 让其他app启动你的activity
前面的两篇文章主要讲了一个方面:从app中启动其他app.但是如果你的app可以处理对其他app有用的操作,你的app也应该响应其他app的操作请求.例如,如果你创建了一个社交app可以分享信息和图片 ...
- Android开发5:应用程序窗口小部件App Widgets的实现
前言 本次主要是实现一个Android应用,实现静态广播.动态广播两种改变 widget内容的方法,即在上篇博文中实验的基础上进行修改,所以此次实验的重点是AppWidget小部件的实现啦~ 首先,我 ...
- Android 5.0 Default SMS App以及运营商授权SMS App
已同步更新至个人blog:http://dxjia.cn/2015/08/android-5-default-sms-app/ 题外话:博友们有没有好用的写博客客户端推荐啊,cnblogs推荐的win ...
- Android 实现切换主题皮肤功能(类似于众多app中的 夜间模式,主题包等)
首先来个最简单的一键切换主题功能,就做个白天和晚上的主题好了. 先看我们的styles文件: <resources> <!-- Base application theme. --& ...
- Android官方技术文档翻译——Gradle 插件用户指南(4)
最近赶项目,白天基本没时间,只有晚上在家的时候才能看一看.昨天晚上只翻译完了第四章,今天就只发第四章吧. 本文译自Android官方技术文档<Gradle Plugin User Guide&g ...
- [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 [ ...
- 如何用Axure快速制作APP交互原型
对于产品经理来说,熟练使用一些常用软件是一项十分必要的技能.其中,作为一个专业的快速原型设计工具,Axure RP无疑在产品人心中拥有一个难以撼动的地位.但就要PS一样,虽然足够专业,但同样也会存在使 ...
随机推荐
- CentOS Kernel Source Install
http://linuxmoz.com/centos-kernel-source-install/
- Android开源项目pulltorefresh分析与简单使用
在Android开发中有时我们须要訪问网络实时刷新数据.比方QQ好友在线状态最新信息,QQ空间须要显示很多其它的好友动态信息,EOE论坛client显示很多其它的文章帖子信息等.android-pul ...
- hdu3899(树形dp)
题意:给一树,每个结点有人数,边有权值,表示经过这条边所需时间, 问取某个结点作为开会地点,所有人全部到达此结点最少所需总时间? 分析:val[u]表示以u为根节点的总人数,num[u]表示以u为根节 ...
- 使用NFS安装oracle软件
昨天.使用openfiler创建nas存储系统,安装oracle软件,在所有正面最好,要创建一个数据库时报ora错,原来使用nfs安装oracle数据库,mount选项有特殊要求,如以下.以备查: R ...
- Mesos和kubernetes
Mesos和kubernetes http://dockone.io/article/956我坚定地认为,下一年里,它们的使用增长会更快,因此是时候回顾总结,为2016年做好准备了.本文我想讨论Mes ...
- js检测浏览器中是否安装了flash播放插件
这两天工作中需要在网页中嵌入flash小游戏,我使用的是swfobject.js version:1.5.其他方面都很好,唯独版本检测这里一直没有搞通,后来实在无奈之下,改用js来检测浏览器的flas ...
- 第二期“晋IT”分享成长沙龙
本期主题:微信.打造品牌个体 报名方式:关注微信.回复"我要成长" "晋IT"沙龙费用:全程免费 "晋IT"沙龙文化:共通 共融 合作共赢 ...
- Unity多玩家网络游戏开发教程1章Unity带有网络功能
Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件.专门提供了对网络功能的支持. 可是.大部分开发人员第一次接触到的还是Unity自带的网络功能.也就是大家常 ...
- 期望dp专题
一直不明白为什么概率是正推,期望是逆推. 现在题目做多了,慢慢好像有点明白了 poj2096 收集bug, 有n个种类的bug,和s个子系统. 每找到一个bug需要一天. 要我我们求找到n个种类的 ...
- vps自己搭建VPN(转)
1.购买一个VPS: https://www.pzea.com/North-America-openvz-vps.html 2.下载putty软件,进行vpn安装: http://www.chiark ...