配色: 字号:
android中intent用法
2016-10-12 | 阅:  转:  |  分享 
  
Intent(意图)主要是解决Android应用的各项组件之间的通讯。



Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,

将Intent传递给调用的组件,并完成组件的调用。



因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。



例如,在一个联系人维护的应用中,当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上,

点击某个联系人后,希望能够跳出此联系人的详细信息屏幕(假设对应的Activity为detailActivity)



为了实现这个目的,listActivity需要构造一个Intent,这个Intent用于告诉系统,我们要做"查看"动作,

此动作对应的查看对象是"某联系人",然后调用startActivity(Intentintent),将构造的Intent传入,

系统会根据此Intent中的描述,到ManiFest中找到满足此Intent要求的Activity,系统会调用找到的Activity,

即为detailActivity,最终传入Intent,detailActivity则会根据此Intent中的描述,执行相应的操作。

一、抽象描述要描述什么



在Android参考文档中,对Intent的定义是执行某操作的一个抽象描述(确实很抽象)。

我们先来看看这里的抽象描述,到底描述了什么。



首先,是要执行的动作(action)的一个简要描述,如VIEW_ACTION(查看)、EDIT_ACTION(修改)等

,Android为我们定义了一套标准动作:



MAIN_ACTION



VIEW_ACTION



EDIT_ACTION



PICK_ACTION



GET_CONTENT_ACTION



DIAL_ACTION



CALL_ACTION



SENDTO_ACTION



ANSWER_ACTION



INSERT_ACTION



DELETE_ACTION



RUN_ACTION



LOGIN_ACTION



CLEAR_CREDENTIALS_ACTION



SYNC_ACTION



PICK_ACTIVITY_ACTION



WEB_SEARCH_ACTION



此外,我们还可以根据应用的需要,定义我们自己的动作,

并可定义相应的Activity来处理我们的自定义动作。



其次,是执行动作要操作的数据(data),Android中采用指向数据的一个URI来表示,

如在联系人应用中,一个指向某联系人的URI可能为:content://contacts/1。



这种URI表示,通过ContentURI这个类来描述,具体可以参考android.net.ContentURI类的文档。



以联系人应用为例,以下是一些action/data对,及其它们要表达的意图:



VIEW_ACTIONcontent://contacts/1--显示标识符为"1"的联系人的详细信息



EDIT_ACTIONcontent://contacts/1--编辑标识符为"1"的联系人的详细信息



VIEW_ACTIONcontent://contacts/--显示所有联系人的列表



PICK_ACTIONcontent://contacts/--显示所有联系人的列表,并且允许用户在列表中选择一个联系人,

然后把这个联系人返回给父activity。例如:电子邮件客户端可以使用这个Intent,

要求用户在联系人列表中选择一个联系人



另外,除了action和data这两个重要属性外,还有一些附加属性:



category(类别),被执行动作的附加信息。例如LAUNCHER_CATEGORY表示Intent的接受者应该在Launcher中作为顶级应用出现;

而ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个,这些动作可以在同一块数据上执行。



type(数据类型),显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,

但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。



component(组件),指定Intent的的目标组件的类名称。通常Android会根据Intent中包含的其它属性的信息,

比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果component这个属

性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有

属性都是可选的。



extras(附加信息),是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要

执行"发送电子邮件"这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。



总之,action、data/type、category和extras一起形成了一种语言。



这种语言使系统能够理解诸如"查看某联系人的详细信息"之类的短语。随着应用不断的加入到系统中,

它们可以添加新的action、data/type、category来扩展这种语言。应用也可以提供自己的Activity来

处理已经存在的这样的"短语",从而改变这些"短语"的行为。



折叠编辑本段二、Android如何解析Intent



在应用中,我们可以以两种形式来使用Intent:



直接Intent:指定了component属性的Intent(调用setComponent(ComponentName)或者setClass(Context,Class)来指定)。

通过指定具体的组件类,通知应用启动对应的组件。



间接Intent:没有指定component属性的Intent。这些Intent需要包含足够的信息,这样系统才能根据这些信息,在在所有的

可用组件中,确定满足此Intent的组件。



对于直接Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些间接Intent,通过解析,

将Intent映射给可以处理此Intent的Activity、IntentReceiver或Service。



Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配

的Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:



如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;如果

Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,

否则不能匹配。



如果Intent中的数据不是content:类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme

(比如http:或者mailto:)进行匹配。同上,Intent的scheme必须出现在目标组件的scheme列表中。



如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:

LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。



折叠编辑本段三、Intent的显示调用和隐式调用



显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,

因此,显示Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。



隐式Intent恰恰相反,它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息。



在显示Intent消息中,决定目标组件的唯一要素就是组件名称,因此,如果你的Intent中已经明确定义了目标组件的名称,

那么你就完全不用再定义其他Intent内容。



而对于隐式Intent则不同,由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图

最匹配的组件。



(Intent定义:Intent是一种在不同组件之间传递的请求消息,是应用程序发出的请求和意图。作为一个完整的消息传递机制,

Intent不仅需要发送端,还需要接收端。



显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent。



隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent。



说明:Android系统使用IntentFilter来寻找与隐式Intent相关的对象。



显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,

因此,显示Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。



隐式Intent恰恰相反,它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息。



在显式Intent消息中,决定目标组件的唯一要素就是组件名称,因此,如果你的Intent中已经明确定义了目标组件的名称,

那么你就完全不用再定义其他Intent内容。



而对于隐式Intent则不同,由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图最

匹配的组件。



Android系统寻找与Intent请求意图最匹配的组件具体的选择方法是:Android将Intent的请求内容和一个叫做IntentFilter

的过滤器比较,IntentFilter中包含系统中所有可能的待选组件。



如果IntentFilter中某一组件匹配隐式Intent请求的内容,那么Android就选择该组件作为该隐式Intent的目标组件。



Android如何知道应用程序能够处理某种类型的Intent请求呢?这需要应用程序在Android-Manifest.xml中声明自己所含组件

的过滤器(即可以匹配哪些Intent请求)。



一个没有声明Intent-Filter的组件只能响应指明自己名字的显示Intent请求,而无法响应隐式Intent请求。



而一个声明了IntentFilter的组件既可以响应显示Intent请求,也可以响应隐式Intent请求。在通过和IntentFilter比较来

解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准:



Action



Data



Category



而Extra和Flag在解析收到Intent时是并不起作用的。

文档1:

[代码]调用拨号程序

1//给移动客服10086拨打电话

2Uriuri=Uri.parse("tel:10086");

3Intentintent=newIntent(Intent.ACTION_DIAL,uri);

4startActivity(intent);

[代码]发送短信或彩信

01//给10086发送内容为“Hello”的短信

02Uriuri=Uri.parse("smsto:10086");

03Intentintent=newIntent(Intent.ACTION_SENDTO,uri);

04intent.putExtra("sms_body","Hello");

05startActivity(intent);

06//发送彩信(相当于发送带附件的短信)

07Intentintent=newIntent(Intent.ACTION_SEND);

08intent.putExtra("sms_body","Hello");

09Uriuri=Uri.parse("content://media/external/images/media/23");

10intent.putExtra(Intent.EXTRA_STREAM,uri);

11intent.setType("image/png");

12startActivity(intent);[代码]通过浏览器打开网页

1//打开Google主页

2Uriuri=Uri.parse("http://www.google.com");

3Intentintent=newIntent(Intent.ACTION_VIEW,uri);

4startActivity(intent);[代码]发送电子邮件

01//给someone@domain.com发邮件

02Uriuri=Uri.parse("mailto:someone@domain.com");

03Intentintent=newIntent(Intent.ACTION_SENDTO,uri);

04startActivity(intent);

05//给someone@domain.com发邮件发送内容为“Hello”的邮件

06Intentintent=newIntent(Intent.ACTION_SEND);

07intent.putExtra(Intent.EXTRA_EMAIL,"someone@domain.com");

08intent.putExtra(Intent.EXTRA_SUBJECT,"Subject");

09intent.putExtra(Intent.EXTRA_TEXT,"Hello");

10intent.setType("text/plain");

11startActivity(intent);

12//给多人发邮件

13Intentintent=newIntent(Intent.ACTION_SEND);

14String[]tos={"1@abc.com","2@abc.com"};//收件人

15String[]ccs={"3@abc.com","4@abc.com"};//抄送

16String[]bccs={"5@abc.com","6@abc.com"};//密送

17intent.putExtra(Intent.EXTRA_EMAIL,tos);

18intent.putExtra(Intent.EXTRA_CC,ccs);

19intent.putExtra(Intent.EXTRA_BCC,bccs);

20intent.putExtra(Intent.EXTRA_SUBJECT,"Subject");

21intent.putExtra(Intent.EXTRA_TEXT,"Hello");

22intent.setType("message/rfc822");

23startActivity(intent);[代码]显示地图与路径规划

1//打开Google地图中国北京位置(北纬39.9,东经116.3)

2Uriuri=Uri.parse("geo:39.9,116.3");

3Intentintent=newIntent(Intent.ACTION_VIEW,uri);

4startActivity(intent);

5//路径规划:从北京某地(北纬39.9,东经116.3)到上海某地(北纬31.2,东经121.4)

6Uriuri=Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9116.3&daddr=31.2121.4");

7Intentintent=newIntent(Intent.ACTION_VIEW,uri);

8startActivity(intent);[代码]播放多媒体

1Intentintent=newIntent(Intent.ACTION_VIEW);

2Uriuri=Uri.parse("file:///sdcard/foo.mp3");

3intent.setDataAndType(uri,"audio/mp3");

4startActivity(intent);

5Uriuri=

6Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"1");

7Intentintent=newIntent(Intent.ACTION_VIEW,uri);

8startActivity(intent);[代码]拍照

1//打开拍照程序

2Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE);

3startActivityForResult(intent,0);

4//取出照片数据

5Bundleextras=intent.getExtras();

6Bitmapbitmap=(Bitmap)extras.get("data");[代码]获取并剪切图片

01//获取并剪切图片

02Intentintent=newIntent(Intent.ACTION_GET_CONTENT);

03intent.setType("image/");

04intent.putExtra("crop","true");//开启剪切

05intent.putExtra("aspectX",1);//剪切的宽高比为1:2

06intent.putExtra("aspectY",2);

07intent.putExtra("outputX",20);//保存图片的宽和高

08intent.putExtra("outputY",40);

09intent.putExtra("output",Uri.fromFile(newFile("/mnt/sdcard/temp")));//保存路径

10intent.putExtra("outputFormat","JPEG");//返回格式

11startActivityForResult(intent,0);

12//剪切特定图片

13Intentintent=newIntent("com.android.camera.action.CROP");

14intent.setClassName("com.android.camera","com.android.camera.CropImage");

15intent.setData(Uri.fromFile(newFile("/mnt/sdcard/temp")));

16intent.putExtra("outputX",1);//剪切的宽高比为1:2

17intent.putExtra("outputY",2);

18intent.putExtra("aspectX",20);//保存图片的宽和高

19intent.putExtra("aspectY",40);

20intent.putExtra("scale",true);

21intent.putExtra("noFaceDetection",true);

22intent.putExtra("output",Uri.parse("file:///mnt/sdcard/temp"));

23startActivityForResult(intent,0);

[代码]打开GoogleMarket

1//打开GoogleMarket直接进入该程序的详细页面

2Uriuri=Uri.parse("market://details?id="+"com.demo.app");

3Intentintent=newIntent(Intent.ACTION_VIEW,uri);

4startActivity(intent);

[代码]安装和卸载程序

1Uriuri=Uri.fromParts("package","com.demo.app",null);

2Intentintent=newIntent(Intent.ACTION_DELETE,uri);

3startActivity(intent);

[代码]进入设置界面viewsourceprint?

1//进入无线网络设置界面(其它可以举一反三)

2Intentintent=newIntent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);

3startActivityForResult(intent,0);

文档2:

1.从google搜索内容

Intentintent=newIntent();

intent.setAction(Intent.ACTION_WEB_SEARCH);

intent.putExtra(SearchManager.QUERY,"searchString")

startActivity(intent);

2.浏览网页

Uriuri=Uri.parse("http://www.google.com");

Intentit=newIntent(Intent.ACTION_VIEW,uri);

startActivity(it);

3.显示地图

Uriuri=Uri.parse("geo:38.899533,-77.036476");

Intentit=newIntent(Intent.Action_VIEW,uri);

startActivity(it);

4.路径规划

Uriuri=Uri.parse("http://maps.google.com/maps?f=dsaddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");

Intentit=newIntent(Intent.ACTION_VIEW,URI);

startActivity(it);

5.拨打电话

Uriuri=Uri.parse("tel:xxxxxx");

Intentit=newIntent(Intent.ACTION_DIAL,uri);

startActivity(it);

6.调用发短信的程序

Intentit=newIntent(Intent.ACTION_VIEW);

it.putExtra("sms_body","TheSMStext");

it.setType("vnd.android-dir/mms-sms");

startActivity(it);

7.发送短信

Uriuri=Uri.parse("smsto:0800000123");

Intentit=newIntent(Intent.ACTION_SENDTO,uri);

it.putExtra("sms_body","TheSMStext");

startActivity(it);

Stringbody="thisissmsdemo";

Intentmmsintent=newIntent(Intent.ACTION_SENDTO,Uri.fromParts("smsto",number,null));

mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY,body);

mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE,true);

mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT,true);

startActivity(mmsintent);

8.发送彩信

Uriuri=Uri.parse("content://media/external/images/media/23");

Intentit=newIntent(Intent.ACTION_SEND);

it.putExtra("sms_body","sometext");

it.putExtra(Intent.EXTRA_STREAM,uri);

it.setType("image/png");

startActivity(it);

StringBuildersb=newStringBuilder();

sb.append("file://");

sb.append(fd.getAbsoluteFile());

Intentintent=newIntent(Intent.ACTION_SENDTO,Uri.fromParts("mmsto",number,null));

//Belowextradatasarealloptional.

intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_SUBJECT,subject);

intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY,body);

intent.putExtra(Messaging.KEY_ACTION_SENDTO_CONTENT_URI,sb.toString());

intent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE,composeMode);

intent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT,exitOnSent);

startActivity(intent);

9.发送Email

Uriuri=Uri.parse("mailto:xxx@abc.com");

Intentit=newIntent(Intent.ACTION_SENDTO,uri);

startActivity(it);

Intentit=newIntent(Intent.ACTION_SEND);

it.putExtra(Intent.EXTRA_EMAIL,"me@abc.com");

刚才找appid未果,结果发现用packagename也可以

Uriuri=Uri.parse("market://details?id=");

这个简单多了17寻找应用

Uriuri=Uri.parse("market://search?q=pname:pkg_name");

Intentit=newIntent(Intent.ACTION_VIEW,uri);

startActivity(it);

//wherepkg_nameisthefullpackagepathforanapplication

18打开联系人列表

<1>

Intenti=newIntent();

i.setAction(Intent.ACTION_GET_CONTENT);

i.setType("vnd.android.cursor.item/phone");

startActivityForResult(i,REQUEST_TEXT);

<2>

Uriuri=Uri.parse("content://contacts/people");

Intentit=newIntent(Intent.ACTION_PICK,uri);

startActivityForResult(it,REQUEST_TEXT);
献花(0)
+1
(本文系simpleStar首藏)