首页 > 代码库 > Intent详解

Intent详解

Intent的作用:使你的程序通过Intent调用相应的组件。


 

Intent(意图)的概念:表示我们要执行的某个操作。例如:查看某联系人的详细资料,发邮件给某人并传送一个文件,打电话给某人说某事。

 

Intent通过下面的属性来描述以上的某个意图:

1、Action(动作):用来表示意图的动作,如:查看,发邮件,打电话

2、category(类别):用来表示动作的类别。

3、data(数据):表示与动作要操作的数据。如:查看 联系人

4、type(数据类型):对data类型的描述。

5、extras(附件信息):附件信息。如:详细资料,一个文件,某事。

6、component(目标组件):目标组件。

 

android内置的Intent的各属性见google文档或http://book.51cto.com/art/200908/142683.htm

 

Intent的生成和各属性设置:见API

 

工作原理:你的程序向Android发送一个Inent请求,Android会根据Intent的内容在注册的IntentFilter中选择适当的组件来响应。比如,有一个Activity希望打开网页浏览器查看某一网页的内容,那么这个Activity只需要发出WEB_SEARCH_ACTION请求给Android,Android会根据Intent的请求内容,查询各组件注册时声明的IntentFilter,找到网页浏览器Activity来浏览网页。

详细过程如下:

1、调用者生成Intent对象,并设置相关属性。生成的Intent分为以下两种:

     显示Intent:对于明确指出了目标组件名称的Intent(调用setComponent或setClass来指定)。

     隐式Intent:对于没有明确指出目标组件名称的Intent。于隐式Intent,由于没有明确的目标组件名称,所以必须包含足够的属性信息,他们是:Action,Data,Category。再由Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。

2、向Android提交Intent请求:

     根据要调用的组件不同,请求方式不同:startActivity(Intent),startServer(Intent),sendBroadcast(Intent)。

3、Android对Intnt进行解析,选择相应的组件进行相应。这里可以选择多个组件进行相应。

     对于显示Intent,已经明确定义了目标组件的名称,直接调用目标组件响应即可。

     对于隐形Intnt,具体的选择方法是:Android将Intent的属性和一个叫做IntentFilter的过滤器比较,IntentFilter中包含系统中所有可能的待选组件。如果IntentFilter中某一组件匹配隐式Intent请求的内容,那么Android就选择该组件作为该隐式Intent的目标组件。

4、注册目标组件,配置IntentFilter。

     是目标组件在Android-Manifest.xml中声明自己所含组件的过滤器(即可以匹配哪些Intent请求)。一个没有声明Intent-Filter的组件只能响应指明自己名字的显式Intent请求,而无法响应隐式Intent请求。而一个声明了IntentFilter的组件既可以响应显式Intent请求,也可以响应隐式Intent请求。在通过和IntentFilter比较来解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准。Action,Data,Category。而Extra和Flag在解析收到Intent时是并不起作用的。

      应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent请求,可以声明一个甚至多个IntentFilter。每个IntentFilter描述该组件所能响应Intent请求的能力——组件希望接收什么类型的请求行为,什么类型的请求数据。比如之前请求网页浏览器这个例子中,网页浏览器程序的IntentFilter就应该声明它所希望接收的Intent Action是WEB_SEARCH_ACTION,以及与之相关的请求数据是网页地址URI格式。

如何为组件声明自己的IntentFilter? 常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的IntentFilter。

前面我们提到,隐式Intent和IntentFilter进行比较时的三要素是Intent的Action、Data以及Category。实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目标组件。接下来我们讲解这三方面检查的具体规则。

      1.动作测试

      <intent-filter>元素中可以包括子元素<action>,比如:     

[xhtml] view plaincopy

  1. <intent-filter>   

  2. <action android:name="com.example.project.SHOW_CURRENT" />   

  3. <action android:name="com.example.project.SHOW_RECENT" />   

  4. <action android:name="com.example.project.SHOW_PENDING" />   

  5. </intent-filter>   

 

 

一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配。

如果Intent请求的Action和<intent-filter>中个某一条<action>匹配,那么该Intent就通
过了这条<intent-filter>的动作测试。

如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。

(1) 如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent-filter>匹配。

(2) 反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个Intent请求就将顺利地通过<intent-filter>的行为测试。

 

 

 

2.类别测试

<intent-filter>元素可以包含<category>子元素,比如:

[xhtml] view plaincopy

  1. <intent-filter . . . >   

  2. <category android:name="android.Intent.Category.DEFAULT" />   

  3. <category android:name="android.Intent.Category.BROWSABLE" />   

  4. </intent-filter>   

 

只有当Intent请求中所有的Category与组件中某一个IntentFilter的<category>完全匹配时,才会让该Intent请求通过测试,IntentFilter中多余的<category>声明并不会导致匹配失败。一个没有指定任何类别测试的IntentFilter仅仅只会匹配没有设置类别的Intent请求。

 

3.数据测试

数据在<intent-filter>中的描述如下:

[xhtml] view plaincopy

  1. <intent-filter . . . >   

  2. <data android:type="video/mpeg" android:scheme="http" . . . />   

  3. <data android:type="audio/mpeg" android:scheme="http" . . . />   

  4. </intent-filter>   

 

<data>元素指定了希望接受的Intent请求的数据URI和数据类型,URI被分成三部分来进行匹配:scheme、authority和path。其中,用setData()设定的Intent请求的URI数据类型和scheme必须与IntentFilter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要相匹配才会通过测试。

 

 

 

    

    显式Intent直接用组件的名称定义目标组件,这种方式很直接。显式Intent多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。隐式Intent恰恰相反,由于开发人员往往并不清楚别的应用程序的组件名称,它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息。


Intent用法实例

1.无参数Activity跳转

Intent it = new Intent(Activity.Main.this, Activity2.class);

startActivity(it);   

 

2.向下一个 Activity传递数据(使用Bundle和Intent.putExtras)

Intent it = new Intent(Activity.Main.this, Activity2.class);

Bundle bundle=new Bundle();

bundle.putString("name", "This is from MainActivity!");

it.putExtras(bundle);       // it.putExtra(“test”, "shuju”);

startActivity(it);            // startActivityForResult(it,REQUEST_CODE);

 

对于数据的获取可以采用:

Bundle bundle=getIntent().getExtras();

String name=bundle.getString("name");

 

3.向上一个Activity返回结果(使 用setResult,针对startActivityForResult(it,REQUEST_CODE)启动的Activity)

        Intent intent=getIntent();

        Bundle bundle2=new Bundle();

        bundle2.putString("name", "This is from ShowMsg!");

        intent.putExtras(bundle2);

        setResult(RESULT_OK, intent);

4. 回调上一个Activity的结果处理函数(onActivityResult)

@Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        // TODO Auto-generated method stub

        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode==REQUEST_CODE){

            if(resultCode==RESULT_CANCELED)

                  setTitle("cancle");

            else if (resultCode==RESULT_OK) {

                 String temp=null;

                 Bundle bundle=data.getExtras();

                 if(bundle!=null)   temp=bundle.getString("name");

                 setTitle(temp);

            }

        }

    }

一些Intent用法 实例

显示网页

   1. Uri uri = Uri.parse("http://google.com");  

   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  

   3. startActivity(it);

显示地图

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

   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);   

   3. startActivity(it);   

   4. //其他 geo URI 範例  

   5. //geo:latitude,longitude  

   6. //geo:latitude,longitude?z=zoom  

   7. //geo:0,0?q=my+street+address  

   8. //geo:0,0?q=business+near+city  

   9. //google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom

路径规划

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

   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  

   3. startActivity(it);  

   4. //where startLat, startLng, endLat, endLng are a long with 6 decimals like: 50.123456 

打电话

   1. //叫出拨号程序 

   2. Uri uri = Uri.parse("tel:0800000123");  

   3. Intent it = new Intent(Intent.ACTION_DIAL, uri);  

   4. startActivity(it);  

   1. //直接打电话出去  

   2. Uri uri = Uri.parse("tel:0800000123");  

   3. Intent it = new Intent(Intent.ACTION_CALL, uri);  

   4. startActivity(it);  

   5. //用這個,要在 AndroidManifest.xml 中,加上  

   6. //<uses-permission id="android.permission.CALL_PHONE" /> 

传送SMS/MMS

   1. //调用短信程序 

   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  

   3. it.putExtra("sms_body", "The SMS text");   

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

   5. startActivity(it); 

   1. //传送消息 

   2. Uri uri = Uri.parse("smsto://0800000123");  

   3. Intent it = new Intent(Intent.ACTION_SENDTO, uri);  

   4. it.putExtra("sms_body", "The SMS text");  

   5. startActivity(it); 

   1. //传送 MMS  

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

   3. Intent it = new Intent(Intent.ACTION_SEND);   

   4. it.putExtra("sms_body", "some text");   

   5. it.putExtra(Intent.EXTRA_STREAM, uri);  

   6. it.setType("image/png");   

   7. startActivity(it); 

传送 Email

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

   2. Intent it = new Intent(Intent.ACTION_SENDTO, uri);  

   3. startActivity(it); 


   1. Intent it = new Intent(Intent.ACTION_SEND);  

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

   3. it.putExtra(Intent.EXTRA_TEXT, "The email body text");  

   4. it.setType("text/plain");  

   5. startActivity(Intent.createChooser(it, "Choose Email Client")); 


   1. Intent it=new Intent(Intent.ACTION_SEND);    

   2. String[] tos={"me@abc.com"};    

   3. String[] ccs={"you@abc.com"};    

   4. it.putExtra(Intent.EXTRA_EMAIL, tos);    

   5. it.putExtra(Intent.EXTRA_CC, ccs);    

   6. it.putExtra(Intent.EXTRA_TEXT, "The email body text");    

   7. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");    

   8. it.setType("message/rfc822");    

   9. startActivity(Intent.createChooser(it, "Choose Email Client"));


   1. //传送附件

   2. Intent it = new Intent(Intent.ACTION_SEND);  

   3. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");  

   4. it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");  

   5. sendIntent.setType("audio/mp3");  

   6. startActivity(Intent.createChooser(it, "Choose Email Client"));

播放多媒体

       Uri uri = Uri.parse("file:///sdcard/song.mp3");  

       Intent it = new Intent(Intent.ACTION_VIEW, uri);  

       it.setType("audio/mp3");  

       startActivity(it); 

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

       Intent it = new Intent(Intent.ACTION_VIEW, uri);  

       startActivity(it);

Market 相关

1.        //寻找某个应用 

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

3.        Intent it = new Intent(Intent.ACTION_VIEW, uri);  

4.        startActivity(it);  

5.        //where pkg_name is the full package path for an application 

1.        //显示某个应用的相关信息 

2.        Uri uri = Uri.parse("market://details?id=app_id");  

3.        Intent it = new Intent(Intent.ACTION_VIEW, uri); 

4.        startActivity(it);  

5.        //where app_id is the application ID, find the ID   

6.        //by clicking on your application on Market home   

7.        //page, and notice the ID from the address bar

Uninstall 应用程序

1.        Uri uri = Uri.fromParts("package", strPackageName, null); 

2.        Intent it = new Intent(Intent.ACTION_DELETE, uri);   

3.        startActivity(it);