android Intent详解

一、关于intent
  Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。
二、intent使用场景
1、应用程序内部的使用
(1)、调用系统功能,部分功能需要一些权限
// 调用浏览器  
Uri webViewUri = Uri.parse("http://blog.csdn.net/zuolongsnail");   
Intent intent = new Intent(Intent.ACTION_VIEW, webViewUri); 

// 调用地图  
Uri mapUri = Uri.parse("geo:100,100");  
Intent intent = new Intent(Intent.ACTION_VIEW, mapUri);  
  
// 播放mp3  
Uri playUri = Uri.parse("file:///sdcard/test.mp3");  
Intent intent = new Intent(Intent.ACTION_VIEW, playUri);  
intent.setDataAndType(playUri, "audio/mp3");  
  
// 调用拨打电话  
Uri dialUri = Uri.parse("tel:10086");  
Intent intent = new Intent(Intent.ACTION_DIAL, dialUri);  
// 直接拨打电话,需要加上权限  
Uri callUri = Uri.parse("tel:10086");  
Intent intent = new Intent(Intent.ACTION_CALL, callUri);  
  
// 调用发邮件(这里要事先配置好的系统Email,否则是调不出发邮件界面的)  
Uri emailUri = Uri.parse("mailto:[email protected]");  
Intent intent = new Intent(Intent.ACTION_SENDTO, emailUri);  
// 直接发邮件  
Intent intent = new Intent(Intent.ACTION_SEND);  
String[] tos = { "[email protected]" };  
String[] ccs = { "[email protected]" };  
intent.putExtra(Intent.EXTRA_EMAIL, tos);  
intent.putExtra(Intent.EXTRA_CC, ccs);  
intent.putExtra(Intent.EXTRA_TEXT, "the email text");  
intent.putExtra(Intent.EXTRA_SUBJECT, "subject");  
intent.setType("text/plain");  
Intent.createChooser(intent, "Choose Email Client");  
  
// 发短信  
Intent intent = new Intent(Intent.ACTION_VIEW);  
intent.putExtra("sms_body", "the sms text");  
intent.setType("vnd.android-dir/mms-sms");  
// 直接发短信  
Uri smsToUri = Uri.parse("smsto:10086");  
Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);  
intent.putExtra("sms_body", "the sms text");  
// 发彩信  
Uri mmsUri = Uri.parse("content://media/external/images/media/23");  
Intent intent = new Intent(Intent.ACTION_SEND);  
intent.putExtra("sms_body", "the sms text");  
intent.putExtra(Intent.EXTRA_STREAM, mmsUri);  
intent.setType("image/png");  
  
// 卸载应用  
Uri uninstallUri = Uri.fromParts("package", "com.app.test", null);  
Intent intent = new Intent(Intent.ACTION_DELETE, uninstallUri);  
// 安装应用  
Intent intent = new Intent(Intent.ACTION_VIEW);  
intent.setDataAndType(Uri.fromFile(new File("/sdcard/test.apk"), "application/vnd.android.package-archive");  
  
// 在Android Market中查找应用  
Uri uri = Uri.parse("market://search?q=愤怒的小鸟");           
Intent intent = new Intent(Intent.ACTION_VIEW, uri);


(2)、启动activity,Broadcast,Service
//启动activity
startActivity(intent);
startActivityForResult(intent,0);//此方法多传一个int型参数,可以使用onactivityForResult放大结合使用
//启动Broadcast
sendBroadcasts( )
sendOrderedBroadcasts( )
sendStickyBroadcasts( )
//启动service
startService( )
bindService( )


二、intent属性
(1)action属性
Action属性的值为一个字符串,它代表了系统中已经定义了一系列常用的动作。通过setAction()方法或在清单文件AndroidManifest.xml中设置。默认为:DEFAULT。
Action属性有如下一些:
 ACTION_MAIN:Android Application的入口,每个Android应用必须且只能包含一个此类型的Action声明。 
    ACTION_VIEW:系统根据不同的Data类型,通过已注册的对应Application显示数据。
    ACTION_EDIT:系统根据不同的Data类型,通过已注册的对应Application编辑示数据。 
    ACTION_DIAL:打开系统默认的拨号程序,如果Data中设置了电话号码,则自动在拨号程序中输入此号码。 
    ACTION_CALL:直接呼叫Data中所带的号码。 
    ACTION_ANSWER:接听来电。 
    ACTION_SEND:由用户指定发送方式进行数据发送操作。
    ACTION_SENDTO:系统根据不同的Data类型,通过已注册的对应Application进行数据发送操作。 
    ACTION_BOOT_COMPLETED:Android系统在启动完毕后发出带有此Action的广播(Broadcast)。 
    ACTION_TIME_CHANGED:Android系统的时间发生改变后发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_ADDED:Android系统安装了新的Application之后发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_CHANGED:Android系统中已存在的Application发生改变之后(如应用更新操作)发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_REMOVED:卸载了Android系统已存在的Application之后发出带有此Action的广播(Broadcast)。


(2)Data属性
Data通常是URI格式定义的操作数据。例如:tel:// 。通过setData()方法设置。
 tel://:号码数据格式,后跟电话号码。 
    mailto://:邮件数据格式,后跟邮件收件人地址。
    smsto://:短息数据格式,后跟短信接收号码。
    content://:内容数据格式,后跟需要读取的内容。 
    file://:文件数据格式,后跟文件路径。
    market://search?q=pname:pkgname:市场数据格式,在Google Market里搜索包名为pkgname的应用。
            geo://latitude,longitude:经纬数据格式,在地图上显示经纬度指定的位置。
(3)Category属性
Category属性用于指定当前动作(Action)被执行的环境。通过addCategory()方法或在清单文件AndroidManifest.xml中设置。默认为:CATEGORY_DEFAULT。
  CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。 
    CATEGORY_HOME:设置该组件为Home Activity。
    CATEGORY_PREFERENCE:设置该组件为Preference。 
    CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。 
    CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。 
    CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。
(4)Extras属性
Extras属性主要用于传递目标组件所需要的额外的数据。通过putExtras()方法设置。
EXTRA_BCC:存放邮件密送人地址的字符串数组。 
    EXTRA_CC:存放邮件抄送人地址的字符串数组。
    EXTRA_EMAIL:存放邮件地址的字符串数组。 
    EXTRA_SUBJECT:存放邮件主题字符串。 
    EXTRA_TEXT:存放邮件内容。 
    EXTRA_KEY_EVENT:以KeyEvent对象方式存放触发Intent的按键。  
    EXTRA_PHONE_NUMBER:存放调用ACTION_CALL时的电话号码。  

(5)Type属性 
Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。

(6)Compent属性 

Intent的Compent属性指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。

 
三、关于intent的intent-filter

在intent-filter中指定data属性:要求接收的Intent中的data必须符合intent-filter中指定的data属性,这样达到反向限定Intent的作用。

例如:在AndroidManifest.xml 中进行如下设置:
 
     
           
           
   
 
 

那么启动该Activity的Intent必须进行如下设置:
Intent intent = new Intent();  
Uri uri =  Uri.parse("file://com.android.test:520/mnt/sdcard");  
intent.setData(uri); 

举例说明:
URI   file://com.android.jony.test:520/mnt/sdcard
scheme-->file:
host-->com.android.jony.test
port-->520
path-->mnt/sdcard
其中host和port为URI的authority,如果没有指定host,port将被忽略
data的各属性并不是独立的,data的各属性构成了URI的整个组成部分。要使authority(host和port)有意义,必须指定scheme;要使path有意义,必须使scheme和authority(host和port)有意义。
URI和intent-filter匹配:
Intent中URI和intent-filter进行比较的时候只会进行部分的比较:
(1)当intent-filter中只设置了scheme,只会比较URI的scheme部分;
(2)当intent-filter中只设置了scheme和authority,那么只会匹配URI中的scheme和authority;
(3)当intent-filter中设置了scheme、authority和path,那么只会匹配URI中的scheme、authority、path;(path可以使用通配符进行匹配)
(4)当intent-filter中设置了mimeType,还会进行数据类型的匹配。


总结:
(1)在AndroidMainfest.xml 中对每一个Activity都做了说明——intent-filter,intent-filter声明了需要接收怎样的Intent,当发送的Intent和intent-filter中定义的相符合,就会启动相应的Activity;
(2)当有多个Activity符合发送的Intent时,Android系统会列出所有满足Intent的Activity,用户可以通过选择进行相关的操作;
(3)在一个Activity的intent-filter中可以有多个action、多个category、多个data,这样可以有多种组合与Intent进行匹配。注意:如果在一个Activity中有多个Intent进行匹配的时候,建议使用多个intent-filter与Intent进行匹配。猜测:这样应该可以提高Intent的匹配速度。
(4)data属性,这是一个进行反向限制Intent的操作,要求Intent的data必须是intent-filter中声明的数据之一(应为在一个intent-filter中可以设置多个data)。注意:如果要启动目标Activity,但是指定的data数据类型与Activity中data数据类型不匹配,将会造成ActivityNotFoundException异常。

四、intent传参
intent的传参方式有和多种,最基本的单个类型的传参
intent.putExtra("","");//存
intent.getStringExtra("");//取
或者使用bundle
Bundle bundle = new Bundle();
        bundle.putString("","");
        intent.putExtras(bundle);//存

Bundle bundle = getIntent().getExtras();
        bundle.get("xxx");//取

传递List和List
intent.putStringArrayListExtra(key, list);//存
intent.putStringArrayListExtra(key, list);//取
传递类对象
类对象如果想通过intent传递,必须先要让该类实现Serializable和Parcelable接口进行实例化
实现Serializable 不需要别的改变,
实现Parcelable接口需要实现三个方法:


writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中。
声明:writeToParcel (Parcel dest, int flags)。
)describeContents方法。直接返回0就可以。
)静态的Parcelable.Creator接口,本接口有两个方法:

createFromParcel(Parcel in) 实现从in中创建出类的实例的功能。
newArray(int size) 创建一个类型为T,长度为size的数组, returnnew T[size];即可。本方法是供外部类反序列化本类数组使用。

例如
public class User implements Serializable {
    private int id;
    private  String userName;
    public User() {
    }
    public User(int id, String userName) {
        this.id = id;
        this.userName = userName;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}
public class User implements Parcelable {
    private int id;
    private  String userName;
    public User() {
    }
    public User(int id, String userName) {
        this.id = id;
        this.userName = userName;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }

    public static final Parcelable.Creator CREATOR = new Creator() {
        @Override
        public User createFromParcel(Parcel source) {
            User parcelableUser = new User();
            parcelableUser.userName = source.readString();
            parcelableUser.id = source.readInt();
            return parcelableUser;
        }
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(userName);
        dest.writeInt(id);
    }
}

使用两种方式传递的语法分别为:
bundle.putSerializable(key,object);
bundle.putParcelable(key,object);
使用两种方式接收的语法分别为:
object=(Object) getIntent().getSerializableExtra(key);
object=(Object) getIntent().getParcelableExtra(key);


以上就是总结了一些平时开发中常用到的intent的内容。

你可能感兴趣的:(android开发,android,intent)