转载请注明出处:http://blog.csdn.net/li0978/article/details/52085113
Intent在字面意思是指“意图”,在安卓开发中担任着启动某个组件和组件之间通信传递数据的重要角色。IntentFilter作为“意图”过滤器,其主要作用负责过滤掉组件无法响应和处理的Intent,只将自己关心的Intent接收进来进行处理,一个被启动的组件可以有多个IntentFilter,每个IntentFilter相互独立,使用时只要其中一个过滤器验证通过即可,除了广播可在代码中注册过滤器,其他组件必须AndroidManifest.xml文件中进行声明。Intent对象大致可包含Component、Action、Category、Data、Type、Extra和Flag这7种属性,IntentFilter包含Action,Category,Data这三种属性。“意图”又分为显式意图和隐式意图。
显式Intent
显式Intent是指从表面上明确看出启动某个组件,包括包名和类名。另外强调,从安卓5.0以后启动service必须采用显式Intent方式来启动。
1.可采用intent七个属性中的Component属性,需要接受一个ComponentName类,里面有三个构造函数,其本质都是一样,指定包名和类名来确定一个组件。
Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.example.apptest","com.example.apptest.SecondActivity");
intent.setComponent(componentName);
startActivity(intent);
注意后边的类名,一定要把整个路径写全。
2.可采用Intent的setClass、setClassName等方法也能确定启动某个组件,和Component用法一样。
其实上边的方式如果在同一个app下都可简化成:
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
隐式Intent
凡是不能从表面明确看出到底启动的是哪个组件,都属于隐式Intent,配合IntentFilter一起使用。
1.Action,Category属性与IntentFilter配置。前边已经说过,IntentFilter中有三个属性,其中Action、Category其实就是一个普通的字符串,Action代表该Intent所有完成的一个“动作”,Category则用于为Action增加额外的附加类信息。通常两个是结合着使用的。
Intent intent = new Intent();
intent.setAction("com.example.apptest.goto");
startActivity(intent);
上边隐式启动另一个Activity,其实默认隐藏了intent.addCategory("android.intent.category.DEFAULT")这个句。所以AndroidManifest.xml文件中进行声明:
<intent-filter>
<action android:name="com.example.apptest.goto"/>
<category android:name = "android.intent.category.DEFAULT" />
</intent-filter>
一个intent对象只能设置一个action,可以设置多个category,一个intentFilter可以设置多个action,多个category,并且至少要有一个<category android:name = "android.intent.category.DEFAULT" />属性。
2.Data,Type属性与IntentFilter配置。Data属性通常用于向Action属性提供操作的数据,Data接受的是一个Uri对象,Uri格式包含四个部分:scheme、host、port、path,例如:“run://www.example.com:8080/index”,其中的scheme就是“run”,host就是"www.example.com",port就是"8080",path就是“/index”。Data和Tyep属性再添加的时候很特别,如果intent先设置了Data属性将覆盖Type属性(过滤器将不会过滤type属性),如果intent先设置了Type属性将覆盖Data属性(过滤器中将不会过滤data属性),如果两个都想设置,则应该调用intent的setDataAndType()方法。
Intent intent = new Intent();
intent.setAction("com.example.apptest.goto");
//intent.setType("run/gege");
//intent.setData(Uri.parse("http://www.example.com:8080/index"));
intent.setDataAndType(Uri.parse("http://www.example.com:8080/index"),"run/gege");
startActivity(intent);
在过滤器里设置type属性是包含在data属性里面的:
<intent-filter>
<action android:name="com.example.apptest.goto"/>
<category android:name = "android.intent.category.DEFAULT" />
<data android:mimeType="run/gege"
android:scheme="http"
android:host="www.example.com"
android:port="8080"
android:path="/index"/>
</intent-filter>
特殊说明:如果在过滤器中没有指定android:host属性,那么后边的android:port,android:path即使intent指明了也不会起作用的。
intent使用
目前我们所接触的intent能够启动三种组件:Activity,Service,BroadcastRecever。除了常规项目开发中显式或者隐式的启动本应用的一个组件外,intent还常常用来启动系统组件,另外intent还可设置Extra属性用于在多个组件之间进行数据传值和数据交换,还可设置Flag属性用于控制组件启动方式和一些动态指令。
Android内部提供了大量标准的Action和Category常量。其中用于启动Activity的标准Aciton及对应的字符串如下表所示:
其中用于启动Activity的标准Category及对应的字符串如下表所示:
以下是intent调用系统组件使用例子:
1.安装已经存在的apk
String filePath="mnt/sdcard/abc.apk";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + filePath),"application/vnd.android.package-archive");
startActivity(intent);
2.卸载某个应用
String packageName="org.adw.launcher2" <span style="font-family: Arial, Helvetica, sans-serif;">//包名,指定该应用</span>
Uri packageUri = Uri.parse("package:"+packageName);
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageUri);
startActivity(uninstallIntent);
3.查看某个应用的信息
Uri uri=Uri.parse("package:"+packageName);//包名,指定该应用
Intent intent=new Intent("android.settings.APPLICATION_DETAILS_SETTINGS", uri);
startActivity(intent);
4.浏览某个网址
Uri uri = Uri.parse("http://xxxxxxxxxxxxxxxxxxxxxxxx");
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity"); //用系统浏览器打开网页
startActivity(intent);
5.跳到系统设置界面
Intent intent=new Intent();
intent.setClassName("com.android.settings","com.android.settings.Settings");
startActivity(intent);
6.回到桌面
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
7.跳到系统拨号界面
Intent intent= new Intent(Intent.ACTION_DIAL);
intent.setClassName("com.android.contacts","com.android.contacts.DialtactsActivity");
startActivity(intent);
8.跳到系统通话记录界面
Intent intent =new Intent();
intent.setAction("android.intent.action.CALL_BUTTON");
startActivity(intent);
9.跳到系统拨号界面拨打电话
Uri uri = Uri.parse("tel:xxxxxx");
Intent intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);
10.直接拨打电话
Intent intentPhone = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
startActivity(intentPhone);
11.跳到系统联系人界面
Intent intent = new Intent();
intent.setClassName("com.android.contacts","com.android.contacts.activities.PeopleActivity");
startActivity(intent);
12.跳到系统搜索界面
Intent intent=new Intent();
intent.setClassName("com.android.quicksearchbox", "com.android.quicksearchbox.SearchActivity");
startActivity(intent);
13.跳到短信收件箱界面
Intent intent = new Intent();
intent.setClassName("com.android.mms","com.android.mms.ui.ConversationList");
startActivity(intent);
14.跳到编辑短信界面
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("vnd.android-dir/mms-sms");
startActivity(intent);
Intent中的各种FLAG:
1.FLAG_ACTIVITY_BROUGHT_TO_FRONT
如果通过该Flag启动的Activity已经存在,下次再次启动,将只是把该Activity带到前台。假如A启动B时设置该标签,B又启动C,C又启动B(正常启动),最终栈内的实例是A,C,B.
2.FLAG_ACTIVITY_CLEAR_TOP
相当于启动模式的singleTask。假设启动B时设置此标记,例如栈中现在是A,B,C,D那么再次启动B后的结果是A,B.
3.FLAG_ACTIVITY_NEW_TASK
启动一个新的栈来存储启动这个activity。
4.FLAG_ACTIVITY_NO_ANIMATION
启动Activity时不使用过渡动画
5.FLAG_ACTIVITY_NO_HISTORY
被启动的Activity将不会记录在栈的历史中,假设启动D设置了此标记,例如之前栈中有A,B,C,现在C启动D,然后在由D启动E,那么此时栈中存在的实例有A,B,C,E.
6.FLAG_ACTIVITY_REORDER_TO_FRONT
假如当前栈中已经存在所启动的Activity, 例如当前栈内有A,B,C.此时由 C通过该标记启动B,那么最终栈内的顺序是A,C,B.
7.FLAG_ACTIVITY_SINGLE_TOP
相当于启动模式的singleTop。假设启动B时设置此标记,例如栈中现在是A,B,那么再次启动B后的结果还是A,B.,假如栈中现在是A,B,C,启动B,则是A,B,C,B.
至于其他FLAG并不常用,真正用到时请翻墙查阅官方intent的Api:
https://developer.android.com/reference/android/content/Intent.html