Android笔记六.深入理解Intent和IntentFilter(二)

深入理解Intent和IntentFiler(二)
    在上一篇文章中,我们比较详细学习了"Intent"的相关知识,现在将学习如何设置Intent对象的这些属性以及如何使用他们来启动组件。Intent对象是一组信息,我们可以通过设置其Action、Data、Category属性来指定启动哪个组件并完成什么样的动作(包含动作所需的数据)。
    "意图"分为显示intent和隐式intent。所谓显示intent,指的是Intent已经明确了它将要启动哪个组件-通过指定Intent对象的Component属性实现;而隐式intent,指的是Intent不能确定它将要启动哪个组件(没有指定Component属性)-通过AndroidManifest.xml文件中的Intent Filter来对组件进行筛选来确定启动的组件。
一、显"intent"
    "意图",顾名思义,就是指Intent已经明确以我们可了它将要启动哪个组件。由于一个组件类可以通过其所在的包名和类名唯一的确定,所以通过intent的Component属性来实现。Intent的Component属性需要接受一个ComponentName对象,其构造函数传入了该组件的包名、类名。
1."intent"开发基本思路
(1)创建一个ComponentName对象,用于为"意图"指定组件包名、类名
ComponentName comp=new ComponentName(ComponentAttr.this,SecondaryActivity.class);
(2)创建一个Intent对象,并为该对象设置Component属性
Intent intent=new Intent();
intent.setComponent(comp);
注意:通过使用Intent不同的构造函数,(1)、(2)步骤可以合并为:
    Intent intent=new Intent(ComponentAttr.this,SecondaryActivity.class);
(3)启动一个类名SecondaryActivity的Activity组件
startActivity(intent);
或者 startActivityForResult(intent,requestCode);    //关闭启动的Activity会返回结果
(4)实现被启动的组件SecondaryActivity类(继承于Activity)
(5)在AndroidManifest.xml添加一个<Activity></Activity>元素,但是无需配置<intent-filter>元素
  <!-- 被intent启动的activity -->
        <activity
            android:name=".SecondaryActivity"
            android:label="第二个Activity界面" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="action.CRAZYIT_ACTION"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

博主笔记1:除了上述Intent的setComponent方法,我们还可以利用setClass来指定需要启动的具体组件
Intent intent=new Intent();
intent.setClass(ComponentAttr.this,SecondaryActivity.class);
startActivity(intent);

二、隐式intent
    隐式intent,顾名思义,就是没有指明intent到底要启动哪个组件。显式intent可以通过设置其Component属性实现,而隐式intent就通过Intent Filter来实现。具体的说就是,我们事先设置好"意图"启动组件的相关信息(intent属性),然后再在其他组件的AndroidManifest.xml文件设置好相应的intent属性。当组件发出"意图"时,Android系统通过查找工程文件AndroidManifest.xml(或者系统级组件)其他组件的<intent-filter/>相关信息来进行匹配,筛选得到满足"意图"条件的组件。
1.使用Action属性开发基本思路
       Intent是组件之间的通信的载体,组件的通信可以分为应用内部组件之间的通信和应用间的通信。Intent的Action、Category属性都是一个普通的字符串,其中Action代表Intent索要完成的一个"抽象"动作,Category属性用于为Action增加附加的类别信息。
(1)应用内部组件通信-自定义字符串 方式
public final String CUSTOME_ACTION="intent.action.CUSTOME_JIANG";//字符串可以任意
Intent intent=new Intent();        //创建一个Intent对象
intent.setAction(ActionAttr.CUSTOME_ACTION); //注意:ActionAttr为我们创建的类
startActivity(intent);    //启动一个Activity
(2)与其他应用程序通信-使用系统预定action常量
Intent intent=new Intent();
intent.setAction(Intent.ACTION_CALL); //其中ACTION_CALL为Intent类的静态成员变量,可以类直接调用
startActivity(intent);
2.使用Action、Category属性开发基本思路
(1)应用内部组件通信-自定义字符串 方式
public final String CUSTOME_ACTION="intent.action.CUSTOME_JIANG";//字符串可以任意
public final String CUSTOME_CATEGORY="intent.action.CUSTOME_CATEGORY";//字符串可以任意
Intent intent=new Intent();        //创建一个Intent对象
intent.setAction(ActionAttr.CUSTOME_ACTION); //注意:ActionAttr为我们创建的类
intent.addCategory(ActionAttr.CUSTOME_CATEGORY); 
startActivity(intent);    //启动一个Activity
(2)使用系统预定action、category常量-以下代码实现当点击某个按钮时,通过Intent对象实现返回HOME桌面。
Intent intent=new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);//返回Home桌面 
startActivity(intent);    //启动一个Activity
注意:这里无需设置AndroidManifest.xml
如果是实现应用内部组件的通信,除了上述(1)(2)步骤,我们还需要完成步:
(3)实现需要启动的Activity,如SecondaryActivity.java,ThirdActivity.java,使其继承于Activity;
(4)在工程AndroidManifest.xml添加<activity></activity>元素,并添加<intent-filter/>相关信息
<activity 
android:name=".SecondaryActivity"
android:label="第二个Activity界面" >
<intent-filter>
<action android:name="intent.action.JIANG_ACTION" />
<category android:name="intent.action.JIANG_CATEGORY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity> 
<activity 
android:name=".ThirdActivity"
android:label="第三个Activity界面" >
<intent-filter>
<action android:name="intent.action.JIANG_ACTION" />
<category android:name="intent.action.JIANG_CATEGORY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity> 

博主笔记2:实际上,我们在开发包含"意图"的应用程序中,Action属性和Category属性是配合使用的。因为,Android系统会给主动Activity在AndroidManifest.xml中默认一个Action属性和Category属性,即:
 <intent-filter>
                <action android:name="android.intent.action.MAIN" />                        //应用程序入口
                <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
另外,还需要注意几点:
1.Action常量等属性。如ACTION_CALL是在设置intent时使用,其对应的字符串"android.intent.action.CALL"在AndroidManifest.xml"中使用;
2.当使用Action属性等的系统预定义常量,与其他应用通信时,只需要在本应用的AndroidManifest.xml添加相应的权限即可。
3.一个Activity中只能且必须定义一个Action属性和一个Category属性,其中,Category属性系统会分配其默认常量"CATEGORY_DEFAULT"

3.源代码
    该实例主要完成2个功能:
(1)实现一个按钮,使用Action属性和Category属性启动一个Activity;
(2)实现一个按钮,用于返回HOME界面
(1).FirstActivity.java:主Activity
package com.example.android_intent_2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActionCateAttr extends Activity {
 //自定义一个action常量org.crazyit.
 public final static String CRAZYIT_ACTION="intent.action.JIANG_ACTION";
 public final static String CRAZYIT_CATEGORY="intent.action.JIANG_CATEGORY";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.first);
  Button btn=(Button)findViewById(R.id.button);
  btn.setOnClickListener(new OnClickListener(){
   @Override
   public void onClick(View v) {
    //创建一个Intent对象
    Intent intent=new Intent();
    intent.setAction(ActionCateAttr.CRAZYIT_ACTION);                 //设置action属性
    intent.addCategory(ActionCateAttr.CRAZYIT_CATEGORY);    //设置category属性
    startActivity(intent);
   }});//为btn注册一个事件监听器对象

  /*返回桌面按钮*/
  Button btn1=(Button)findViewById(R.id.home);
  btn1.setOnClickListener(new OnClickListener(){
   @Override
   public void onClick(View v) {
    //创建一个Intent对象
    Intent intent=new Intent();
    intent.setAction(Intent.ACTION_MAIN);	//设置action属性
    intent.addCategory(Intent.CATEGORY_HOME);//设置category属性
    startActivity(intent);
   }});//为btn注册一个事件监听器对象
 }
}
(2).AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android_intent_2"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="14" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".ActionCateAttr"
            android:label="第一个Activity界面" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       
        <activity
            android:name=".SecondaryActivity"
            android:label="第二个Activity界面" >
            <intent-filter>
                <action android:name="intent.action.JIANG_ACTION" />
                <category android:name="intent.action.JIANG_CATEGORY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
       
        <activity
            android:name=".ThirdActivity"
            android:label="第三个Activity界面" >
            <intent-filter>
                <action android:name="intent.action.JIANG_ACTION" />
                <category android:name="intent.action.JIANG_CATEGORY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>
(3)在工程中,添加SecondaryActivity.java,ThirdActivity.java继承于Activity.

(4)效果

3.使用Data、Type属性开发基本思路
    Action属性为Intent对象描述了一个"动作",那么Data属性就为Intent对象的Action属性提供了操作的数据。Type属性用于指定该Data所指定Uri对应的MIME类型,这种类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串即可。这里需要注意的是,Type属性和Data属性一般会出现相互覆盖的情况,如果希望Intent既有Data属性也有Type属性,必须通过setDataAndType()方法来实现。这里需要注意的是,Data属性只接受一个Uri对象,一个Uri对象通常通过如下形式的字符串来表示:
    Uri字符串格式:scheme://host:port/path 举例: content://com.android.contacts/contacts/1或tel://18819463209
    这里有两种情况,一是启动系统级应用程序;二是,启动应用内部组件。前者无需配置AndroidManifest.xml中的<data../>元素,只需添加相应权限即可;后者,需要配置AndroidManifest.xml中的<data/>元素内容。其中,为组件声明Data、Type属性都通过<data../>元素,格式如下:
    <data android:mimeType=""        //用于声明该组件所能匹配的Intent的Type属性
            android:scheme=""             //协议
             android:host=""                 //用于声明该组件所能匹配的Intent的Data属性host部分(主机)
             android:port=""                 //串口
             android:path=""                //资源路径
            android:pathPrefix=""        //Data属性的前缀
            android:pathPattern=""/>    //Data属性的path字符串模板
情况一、启动系统级应用组件
(1)实现一个Intent对象,并启动组件
Intent intent=new Intent();                         //创建一个Intent对象
String data="content://com.android.contacts/contacts/1";
Uri uri=Uri.parse(data);                            //将字符串转换为Uri
intent.setAction(Intent.ACTION_VIEW);  //设置Intent对象Action属性
intent.setData(uri);                                   //设置Intent对象Data属性
startActivity(intent); 
或者
Intent intent=new Intent();
intent.setAction(Intent.ACTION_VIEW); 
intent.setData(Uri.parse("content://com.android.contacts/contacts/1"));
startActivity(intent); 
(2)在AndroidManifest.xml中添加相应的权限
在Android中读取电话信息时,要注意加入
<use-permission android:name="android.permission.READ_CONTACTS"/>
在android中使用BroadcastReceiver时
<use-permission android:name="android.permission.RECEIVE_SMS"/>
在android中使用有关的文件下载功能时,要使用到的
<use-permission android:name="android.permission.INTERNET"/>
<use-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
(3)源代码
    该应用程序实现三个按钮实现三个功能:打开网页、编辑联系人、拨打电话
firstActivity.java
package com.android.android_intent_4; 
import android.support.v7.app.ActionBarActivity; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
public class MainActivity extends ActionBarActivity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
/*第一个按键功能:打开网页*/ 
Button btn1=(Button)findViewById(R.id.button1);	
btn1.setOnClickListener(new OnClickListener(){	//为按钮1注册一个事件监听器对象 

@Override 
public void onClick(View v) { 
//1.创建Intent 
Intent intent=new Intent(); 
//2.设置action、data属性 
String data="http://www.baidu.com"; 
Uri uri=Uri.parse(data);	 //将字符串转化为Uri-通用资源标识 
intent.setAction(Intent.ACTION_VIEW);	//设置intent属性为系统预定义的Intent.ACTION_VIEW 
intent.setData(uri);	 //为intent设置数据属性,用于传递数据 
//3.启动Activity 
startActivity(intent); 
}}); 

/*第二个按键功能:编辑标识为1的联系人*/ 
Button btn2=(Button)findViewById(R.id.button2);	
btn2.setOnClickListener(new OnClickListener(){	//为按钮1注册一个事件监听器对象 

@Override 
public void onClick(View v) { 
//1.创建Intent 
Intent intent=new Intent(); 
//2.设置action、data属性 
intent.setAction(Intent.ACTION_EDIT);	 //设置intent属性为系统预定义的Intent.ACTION_VIEW 
intent.setData(Uri.parse("content://com.android.contacts/contacts/1"));	//为intent设置数据属性,根据指定的字符解析出Uri对象 
//3.启动Activity 
startActivity(intent); 
}}); 

/*第三个按键功能:拨打电话18819465188*/ 
Button btn3=(Button)findViewById(R.id.button3);	
btn3.setOnClickListener(new OnClickListener(){	//为按钮1注册一个事件监听器对象 
@Override 
public void onClick(View v) { 
//1.创建Intent 
Intent intent=new Intent(); 
//2.设置action、data属性 
intent.setAction(Intent.ACTION_DIAL);	 //设置intent属性为系统预定义的Intent.ACTION_VIEW 
intent.setData(Uri.parse("tel:18819465188"));	//根据指定的字符解析出Uri对象 
//3.启动Activity 
startActivity(intent); 
}}); 
} 

} 
效果如下图:

情况二、启动应用内部组件
(1)实现一个Intent对象,并启动组件
Intent intent=new Intent();                         //创建一个Intent对象
String data="lee://www.fkjava.org:8888/mypath";
Uri uri=Uri.parse(data);                            //将字符串转换为Uri
intent.setAction(Intent.ACTION_VIEW); 
intent.setData(uri);                                   //设置Intent对象Data属性
startActivity(intent); 
或者
Intent intent=new Intent();
intent.setAction(Intent.ACTION_VIEW); 
intent.setData(Uri.parse("lee://www.fkjava.org:8888/mypath"));
startActivity(intent); 
(2)AndroidManifest.xml中设置<data../>元素中的相关内容即可
  <data android:mimeType=""
             android:host=""
             android:port=""
             android:path=""
            android:pathPrefix=""
            android:pathPattern=""/>
(3)实现其他Activity

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。