Android之Intent

Intent

Intent的简介

Intent是一种运行时绑定(run-time binding)机制,它能在程序运行过程中连接两个不同的组件,一般用于启动不同的组件同时完成不同组件间的数据传递,Android的三大基本组件Activity,Service和Broadcast Receiver都是通过Intent机制激活的。

通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来完成请求。比如,有一个Activity希望打开网页浏览器查看某一网页的内容,那么这个Activity只需要发出action为WEB_SEARCH_ACTION的intent给Android,Android就会根据intent请求的内容,查询各组件注册时声明的Intent Filter里对应的action,直到找到网页浏览器的Activity来浏览网页。

Intent的构造方法

1、Intent() 空构造函数
2、Intent(Intent o) 拷贝构造函数
3、Intent(String action) 指定action类型的构造函数
4、Intent(String action, Uri uri) 指定Action类型和Uri的构造函数,URI主要是结合程序之间的数据共享ContentProvider(Android另一大组件,主要功能是完成不同组件间的数据共享)
5、Intent(Context packageContext, Class < ?> cls) 传入组件的构造函数,也就是最常用的
6、Intent(String action, Uri uri, Context packageContext, Class< ?> cls) 前两种结合体

Uri uri = Uri.parse("http://www.google.com"); 
Intent it  = new Intent(Intent.ACTION_VIEW,uri); 
startActivity(it); 

使用第四种构造函数,执行此代码的时候,系统就会在程序主配置文件AndroidMainfest.xml中寻找intent-filter中action:name=”android.intent.action.ACTION_VIEW”对应的Activity,如果对应为多个activity具有< action android:name=”android.intent.action.ACTION_VIEW” />此时就会弹出一个dailog让用户选择跳转到的目的Activity。

Intent的参数

要在不同的activity之间传递数据,就要在intent中包含相应的内容,一般来说数据中最基本的应该包括:

Action:

用来指明要实施的动作是什么,比如说ACTION_CALL,ACTION_EDIT等,常用的还有:

ACTION功能
ACTION_CALLactivity中启动一个电话
ACTION_SENDTOactivity中发送短信
ACTION_SENDactivity中发送彩信
ACTION_EDITactivity中显示用户编辑的数据
ACTION_WEB_SEARCHactivity中从google搜索内容
ACTION_VIEWactivity中查看某指定uri
ACTION_GET_CONTENTactivity中获取上下文内容
ACTION_PICKactivity中选出指定uri数据
ACTION_DELETEactivity中卸载apk
ACTION_PACKAGE_ADDEDactivity中安装apk
ACTION_MAINactivity中作为Task中第一个Activity启动
ACTION_SYNCactivity中同步手机与数据服务器上的数据
ACTION_BATTERY_LOWbroadcast receiver中电池电量过低警告
ACTION_HEADSET_PLUGbroadcast receiver中插拔耳机警告
ACTION_SCREEN_ONbroadcast receiver中屏幕变亮警告
ACTION_TIMEZONE_CHANGEDbroadcast receiver中改变时区警告
Data:

intent执行的具体的数据,一般由一个Uri来指定,比如Uri uri = Uri.parse(http://www.google.com),表示intent访问数据为google网站。

Type:

intent执行数据的类型,可以显示指定,也可以隐式推导;

比如Intent i = new Intent(Intent.ACTION_VIEW,uri),如果在程序中显示指定intent.setType(“vnd.android-dir/mms-sms”),那么它能显示的识别并发送该短信;如果没有指定,手机的Intent在分发过程中,会根据”smsto:0800000123”的scheme判断出该数据类型为sms,从而发送短信。不要忘记在Brower的Manifest.xml中的IntenFilter指定action=ACTION_VIEW。

显式指定Intent的数据类型为MIME(多用途互联网邮件扩展,Multipurpose Internet Mail Extensions)。
MIME类型有2种形式:

1.1 单个记录的格式:vnd.android.cursor.item/vnd.yourcompanyname.contenttype,如:content://com.example.transportationprovider/trains/122(一条列车信息的uri)的MIME类型是vnd.android.cursor.item/vnd.example.rail

1.2 多个记录的格式:vnd.android.cursor.dir/vnd.yourcompanyname.contenttype,如:content://com.example.transportationprovider/trains(所有列车信息)的MIME类型是vnd.android.cursor.dir/vnd.example.rail

MIME功能
application/vnd.android.package-archive.apk
text/plain.conf/.cpp/.c/.h/.java/.log/.prop/.rc/.sh/.txt/.xml
application/pdf.pdf
application/vnd.ms-works.wps
application/vnd.ms-powerpoint.ppt
application/msword.doc
image/png”.png
image/bmp.bmp
image/gif.gif
image/jpeg.jpeg/.jpg
application/zip.zip
application/x-rar-compressed.rar
application/x-tar.tar
application/x-gtar.gtar
application/x-gzip.gz
application/x-compressed.tgz
application/x-compress.z
application/java-archive.jar
application/octet-stream.exe/.bin/.class
text/html.htm/.html
application/x-javascript.js
video/3gpp.3gp
video/x-msvideo.avi
video/mpeg.mpe/.mpeg/.mpg
video/mp4.mp4/.mpg4
video/quicktime.mov
video/vnd.mpegurl.m4u
audio/x-pn-realaudio.rmvb
audio/x-wav.wav
audio/x-ms-wma.wma
audio/x-ms-wmv.wmv
audio/x-mpeg.mp2/.mp3
audio/mp4a-latm.m4a/.m4b/.m4p
audio/x-mpegurl.m3u
audio/mpeg.mpga
audio/ogg.ogg
application/vnd.ms-outlook.msg
application/rtf.rtf
vnd.android-dir/mms-sms发送短信sms
vnd.android.cursor.item/phone获取通信录
//主要是获取通讯录的内容
Intent intent = new Intent();                 
intent.setAction(Intent.ACTION_GET_CONTENT);// 设置Intent Action属性                  
intent.setType("vnd.android.cursor.item/phone");// 设置Intent Type 属性,显示声明Type   
startActivity(intent); // 启动Activity
Category:

一个字符串,包含了关于处理该intent的组件的种类的信息。一个intent对象可以有任意个category,intent类定义了许多category常数。

category常量功能
CATEGORY_BROWSABLE目标activity可以安全地调用浏览器显示链接,例如浏览图像或发送电子邮件等
CATEGORY_GADGET此activity可以被嵌入在另一个主机设备上的activity里
CATEGORY_HOME显示设备开启或者按下Home键后的首页界面
CATEGORY_LAUNCHER此activity是一个task的初始化activity并且在启动应用中的top-level队列中
CATEGORY_PREFERENCE目标activity是一个preference panel
// 主要实现跳转到Home界面
Intent intent = new Intent();                 
intent.setAction(Intent.ACTION_MAIN);// 添加Action属性                
intent.addCategory(Intent.CATEGORY_HOME);// 添加Category属性              
startActivity(intent);// 启动Activity  
category常用方法功能
addCategory()为该intent增加一个category
removeCategory()删除该intent的一个category
getCategories()获取该intent所有的category
Component:

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

Extras:

附加信息,例如ACTION_TIMEZONE_CHANGED的intent有一个”time-zone”附加信息来指明新的时区,而ACTION_HEADSET_PLUG有一个“state”附加信息来指示耳机是被插入还是被拔出。intent对象有一系列put…()和set…()方法来设定和获取附加信息。 这些方法和Bundle对象很像。事实上附加信息可以使用putExtras()和getExtras()作为Bundle来读和写。

//用Bundle传递数据   
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("add_one", a);// 通过intent的put,set方法传递数据
intent.putExtra("add_two", b);

Bundle bundle=new Bundle(); // 通过Bundle对象传递数据
bundle.putString("name", "This is from MainActivity!"); 
intent.putExtras(bundle); 
startActivity(intent);

//获得数据 
Bundle bundle=getIntent().getExtras(); 
String name=bundle.getString("name");

intent的使用方式

显式Intent

指定了component属性的Intent(调用setComponent(ComponentName)或者setClass(Context, Class)来指定)。通过指定具体的组件类,通知应用启动对应的组件。

setComponent

//**主要用来启动第三方程序**
Intent intent = new Intent();
ComponentName cn = new ComponentName("com.yl.app", "com.yl.app.updateService");// 用来打开其他应用程序中的Activity或Service
intent.setComponent(cn);
startService(intent);
//**打开应用商店下载升级**
Intent intent = new Intent();//将当前应用名称发送到应用商店
intent.putExtra("appName", relyAppName)
intent.putExtra("packageName", relyPackageName);
intent.putExtra("versionCode", relyVersionCode);

ComponentName component = new ComponentName("com.google.appstore", "com.google.appstore.MainActivity");//打开应用商店更新当前应用
intent.setComponent(component);
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.addFlags(270532608);//新栈中打开
context.startActivity(intent);

setClass

//**主要是在一个同程序中从一个activity跳转到另一个activity**
Intent intent = new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);// 用来打开同一个应用程序中的Activity或Service
startService(intent);
隐式Intent

没有指定comonent属性的Intent,这些Intent需要包含足够的信息,这样系统才能根据这些信息,在所有的可用组件中,找到满足此Intent的组件。

intent的解析

对于显式Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些隐式Intent,通过解析将 Intent映射给可以处理此Intent的Activity、Service或者Broadcast Receiver。

Intent解析机制

Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有< intent-filter>及其中定义的Intent,通过PackageManager(注:PackageManager能够得到当前设备上所安装的
application package的信息)来查找能处理这个Intent的component。

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

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

1.2 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。

1.3 如果Intent中的数据不是content:类型的URI,而且Intent也没有明确指定type,将根据Intent中数据的scheme(比如 http:或者mailto:)进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。

1.4 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。

intent的数据传递

intent传递普通数据:
// 直接使用intent的putExtra方法传递普通类型数据
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("name", "yl");
intent.putExtra("age", 21);
startActivity(intent);
// 使用bundle封装普通类型数据
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name", "yl");
bundle.putInt("age",21);
intent.putExtras(bundle);
startActivity(intent);
intent传递复杂数据:
// 使用bundle封装实现了Serializable接口的复杂数据
Intent intent = new Intent(MainActivity.this,SecondActivity.class);  
Bundle bundle = new Bundle();  
bundle.putSerializable("Person_Ser",mPerson);  //mPerson实现Serializable接口
intent.putExtras(bundle);          
startActivity(intent);  
// 使用bundle封装实现了Parcelable接口的复杂数据
Intent intent = new Intent(MainActivity.this,SecondActivity.class);  
Bundle bundle = new Bundle();  
bundle.putParcelable("Book_Par", mBook);  // mBook实现Parcelable接口
intent.putExtras(bundle);  
startActivity(intent); 

Serializable和Parcelable区别:

Serializable是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。Serializable序列化不保存静态变量,但可以使用Transient关键字对部分字段不进行序列化,也可以覆盖writeObject、readObject方法以实现序列化过程自定义。

Parcelable是为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,这种传输智能在程序内。Parcelable是通过IBinder通信的消息的载体。

Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化。

intent传递数据在3大组件中的使用:

Android的三个基本组件Activity,Service和Broadcast Receiver都是通过Intent机制激活的,不同类型的组件有不同的传递Intent方式:

Activity

context.startActivity()或者context.startActivityForResult()

Service

context.startService()或者context.bindService()

Broadcast Receiver

context.sendBroadcast()、context.sendOrderBroadcast()、context.sendStickBroadcast()

Intent一旦发出,Android都会准确找到相匹配的一个或多个Activity,Service或者BroadcastReceiver作响应。所以,不同类型的Intent消息不会出现重叠,即Broadcast的Intent消息只会发送给BroadcastReceiver,而决不会发送给Activity或者Service。

intent的常用示例

// 1.拨打电话 
Uri uri = Uri.parse("tel:xxxxxx"); 
Intent it = new Intent(Intent.ACTION_DIAL, uri);   
startActivity(it); 

Uri uri = Uri.parse("tel.xxxxxx");
Intent it =new Intent(Intent.ACTION_CALL,uri);//要使用ACTION_CALL必须加入<uses-permission id="Android.permission.CALL_PHONE"/>
startActivity(it); 
// 2.发送短信 
Uri uri = Uri.parse("smsto:0800000123");  
//uri = Uri.fromParts("smsto", number, null));  
Intent it = new Intent(Intent.ACTION_SENDTO, uri);    
it.putExtra("sms_body", "The SMS text");    
startActivity(it); 
//3.调用系统发短信程序 
Intent it = new Intent(Intent.ACTION_VIEW);    
it.putExtra("sms_body", "The SMS text");    
it.setType("vnd.android-dir/mms-sms");    
startActivity(it); 
// 4.发送彩信 
Uri uri = Uri.parse("content://media/external/images/media/23");    
Intent it = new Intent(Intent.ACTION_SEND);    
it.putExtra("sms_body", "some text");    
it.putExtra(Intent.EXTRA_STREAM, uri);    
it.setType("image/png");    
startActivity(it);
// 5.发送Email 
Uri uri = Uri.parse("mailto:xxx@abc.com"); 
Intent it = new Intent(Intent.ACTION_SENDTO, uri); 
startActivity(it);

Intent it = new Intent(Intent.ACTION_SEND);    
it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");    
it.putExtra(Intent.EXTRA_TEXT, "The email body text");    
it.setType("text/plain");  
startActivity(Intent.createChooser(it, "Choose Email Client"));

Intent it=new Intent(Intent.ACTION_SEND);      
String[] tos={"me@abc.com"};      
String[] ccs={"you@abc.com"};      
it.putExtra(Intent.EXTRA_EMAIL, tos);      
it.putExtra(Intent.EXTRA_CC, ccs);      
it.putExtra(Intent.EXTRA_TEXT, "The email body text");      
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");      
it.setType("message/rfc822");      
startActivity(Intent.createChooser(it, "Choose Email Client"));    

Intent it = new Intent(Intent.ACTION_SEND);    
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");    
it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");    
sendIntent.setType("audio/mp3");    
startActivity(Intent.createChooser(it, "Choose Email Client")); 
// 6.网络搜索
Intent intent = new Intent(); 
intent.setAction(Intent.ACTION_WEB_SEARCH);
intent.putExtra("SearchString","Android之Intent");
startActivity(intent); 
// 7.打开google 
Uri uri = Uri.parse("http://www.google.com"); 
Intent it = new Intent(Intent.ACTION_VIEW,uri); 
startActivity(it); 
// 8.显示地图 
Uri uri = Uri.parse("geo:38.899533,-77.036476"); 
Intent it = new Intent(Intent.Action_VIEW,uri); 
startActivity(it); 
// 9.路径规划 
Uri uri = Uri.parse("http://maps.google.com/maps?f=dsaddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 
Intent it = new Intent(Intent.ACTION_VIEW,uri); 
startActivity(it); 
// 10.播放多媒体   
Intent it = new Intent(Intent.ACTION_VIEW); 
Uri uri = Uri.parse("file:///sdcard/song.mp3");//读取SD上的音频文件 
it.setDataAndType(uri, "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); 
// 11.卸载apk 
Uri uninstallUri = Uri.fromParts("package", "strPackageName", null); 
Intent it = new Intent(Intent.ACTION_DELETE, uninstallUri); 
startActivity(it);
// 12.安装apk 
Uri installUri = Uri.fromParts("package", "strPackageName", null); 
Intent it = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri); 
startActivity(it);
// 13. 打开照相机 
Intent i = new Intent(Intent.ACTION_CAMERA_BUTTON, null); 
this.sendBroadcast(i); //点击拍照键

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //拍照并保存
long time = Calendar.getInstance().getTimeInMillis();
Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/picture", time + ".jpg")); 
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, ACTIVITY_GET_CAMERA_IMAGE);//ACTIVITY_GET_CAMERA_IMAGE = 10  
// 14.从gallery选取图片 
Intent intent = new Intent(); 
intent.setType("image/*"); 
intent.setAction(Intent.ACTION_GET_CONTENT); 
startActivityForResult(intent, 11); 
// 15. 打开录音机 
Intent mIntent = new Intent(Media.RECORD_SOUND_ACTION); 
startActivity(mIntent); 
// 16.显示应用详细列表       
Uri uri = Uri.parse("market://details?id=app_id");//where app_id is the application ID, find the ID by clicking on your application on Market home page, and notice the ID from the address bar
// Uri uri = Uri.parse("market://details?id=<packagename>");刚才找app_id未果,结果发现用packagename也可  
Intent it = new Intent(Intent.ACTION_VIEW, uri);         
startActivity(it);      
// 17.寻找应用       
Uri uri = Uri.parse("market://search?q=pname:pkg_name");//where pkg_name is the full package path for an application     
Intent it = new Intent(Intent.ACTION_VIEW, uri);         
startActivity(it);   
// 18.打开联系人列表 
Intent it = new Intent(); 
it.setAction(Intent.ACTION_GET_CONTENT); 
it.setType("vnd.android.cursor.item/phone"); 
startActivityForResult(it, REQUEST_TEXT); //REQUEST_TEXT =12

Intent it = new Intent(); 
Uri uri = Uri.parse("content://contacts/people"); 
Intent it = new Intent(Intent.ACTION_PICK, uri); 
startActivityForResult(it, REQUEST_TEXT); //REQUEST_TEXT =12
// 19.调用系统编辑添加联系人(高版本SDK有效):
Intent it = new Intent(Intent.ACTION_INSERT_OR_EDIT);
it.setType("vnd.android.cursor.item/contact");
//it.setType(Contacts.CONTENT_ITEM_TYPE);
it.putExtra("name","myName");
it.putExtra(android.provider.Contacts.Intents.Insert.COMPANY,  "organization");
it.putExtra(android.provider.Contacts.Intents.Insert.EMAIL,"email");
it.putExtra(android.provider.Contacts.Intents.Insert.PHONE,"homePhone");
it.putExtra(android.provider.Contacts.Intents.Insert.SECONDARY_PHONE,"mobilePhone");
it.putExtra(android.provider.Contacts.Intents.Insert.TERTIARY_PHONE,"workPhone");
it.putExtra(android.provider.Contacts.Intents.Insert.JOB_TITLE,"title");
startActivity(it);
// 20.调用系统编辑添加联系人(全有效):
Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
intent.setType(People.CONTENT_ITEM_TYPE);
intent.putExtra(Contacts.Intents.Insert.NAME, "My Name");
intent.putExtra(Contacts.Intents.Insert.PHONE, "+1234567890");     
intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE, Contacts.PhonesColumns.TYPE_MOBILE);
intent.putExtra(Contacts.Intents.Insert.EMAIL, "com@com.com");
intent.putExtra(Contacts.Intents.Insert.EMAIL_TYPE, Contacts.ContactMethodsColumns.TYPE_WORK);
startActivity(intent);
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值