1.通过Intent传递数据(打开Activity)
2.Action动作
3.Categorg类别
4.data数据
5.type数据类型
6.Extras扩展信息数据
7.Flags标志位Activity的启动模式
8.常用的系统Intent
Intent组件虽然不是四大组件,但确是连接四大组件的桥梁,学习好这个知识也是非常重要.
android提供了Intent机制来协助应用间的交互和通讯,或者采用更准确的说法是,Intent不仅可用于应用之间,也可以用于应用内部的activity,service和broadcast receiver之间的交互。Intent这个单词的本意是:"目的,意图,意向"。
activity、service和broadcast receiver之间是通过Intent进行通信的,而另外一个组件Content Provider本身就是一种通信机制,
不需要通过Intent。我们来看下面这个图就知道了
如果Activity1需要和Activity2进行联系,二者不需要直接联系,而是通过Intent作为桥梁。通俗来讲,Intnet类似于中介、媒婆的角色。
1.使用Context.startActivity()或 Activity.startActivityForResult(),传入一个intent来启动一个activity。
2 将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service。
3.将intent对象传给 Context.bindService()来绑定一个service。
4.将intent对象传给 Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方 法,则它们被传给 broadcast receiver。
Intent由以下各个组成部分:
component(组件):目的组件
action(动作):用来表现意图的行动
category(类别):用来表现动作的类别
data(数据):表示与动作要操纵的数据
type(数据类型):对于data范例的描写
extras(扩展信息):扩展信息
Flags(标志位):期望这个意图的运行模式
Intent类型分为显式Intent(直接类型),隐式(间接类型)。官方建议使用隐式Intent。 Component属性明确指定Intent的目标组件 的类名称。(属于直接Intent)
相比与显示Intent,隐式Intent则含蓄了许多,他并不明确指出我们想要启动哪一个活动,而是指一系列为抽象的action和category的信息,然后交由系统去分析这个Intent,并帮助我们找出最合适的活动去启动。
Activity和Intent Filter的匹配过程:
1.Component(组件)目标组件:
Component属性明确指定Intent的目标组件的类名称.(直接属于Intent)
如果Component这个属性有指定的话, 将直接使用它指定的组件。指定了这个属性以后,Intent的其他所有的属性都可以选择。
例如:
Intent intent2=new Intent();
ComponentName componentName=new ComponentName(CurrentActivity.this,TargetActivity.class);
intent2.setComponent(componentName);
startActivity(intent2);
//发送数据
Intent intent = new Intent(OneActivity.this, TwoActivity.class);
intent.putExtra("intent", tvIntent.getText());
startActivity(intent);
//取出数据
String intent1 = intent.getStringExtra("intent");
tvExhibitionMode.setText(intent1);
/**
* 第一个页面 注意:返回数据时候需要有一个返回码
*/
Intent intent2=new Intent(TwoActivity.this,ThreeActivity.class);
startActivityForResult(intent2,100);
/**
*第一个页面 匹配到返回码并且带回数据
*
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==RESULT_OK){
String result=data.getStringExtra("result");
Log.d("第二个页面", "onActivityResult: ----------获取第二个页面返回来的数据--------------"+result);
}
}
/**
* 返回的数据设置 需要注意的是:返回码要一致
*/
Intent intent2=getIntent();
intent2.putExtra("result","返回的结果");
setResult(100,intent2);
finish();
当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想“做”三个俯卧撑;我要“写” 一封情书,等等。在Intent中,Action就是描述做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK等, 基本涵盖了常用动作。加的动作越多,越精确。
Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其
//Action 和category通常是放在一起用的
代码解释:
上面代码HomeActivity可以匹配到MY_ACTION这个动作,此时其他的Activity通过这个action的条件查找,直到找到和他条件符合他。
注意:如果没有指定action,就必须默认使的DEFAULT(
也就是说:只有
//启动另一个Activity,(通过action属性进行查找)
Intent intent = new Intent();
//设置动作(实际action属性就是一个字符串标记而已)
intent.setAction("com.xx.intent.MY_ACTION");
startActivity(intent);
此时,点击MainActicity中的按钮,就会跳到HomeActivity中去。
总结如下:
自定义类别: 在Intent添加类别可以添加多个类别,那就要求被匹配的组件必须同时满足这多个类别,才能匹配成功。
操作Activity的时候,如果没有类别,须加上默认类别
Data属性是android要访问的数据,和action和category声明方式相同,也在
Data是用一个uri对象来表示的,uri代表数据的地址,属于一种标识符。通常情况下,我们使用action+data属性的组合来描述一个意图:做什么
使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的功能共享成为了可能。比如应用程序中需要展示一个网页,没有必要自己去实现一个浏览器(事实上也不太可能),而是只需要条用系统的浏览器来打开这个网页就行了。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri data = Uri.parse("http://www.baidu.com");
intent.setData(data);
startActivity(intent);
Type属性用于明确指定Data属性的数据类型或MIME类型,但是通常来说,当Intent不指定Data属性时,Type属性才会起作 用,否则Android系统将会根据Data属性值来分析数据的类型,所以无需指定Type属性。
data和type属性一般只需要一个,通过setData方法会把type属性设置为null,相反设置setType方法会把data设置为null,如果 想 要两个属性同时设置,要使用Intent.setDataAndType()方法。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri data = Uri.parse("file:///storage/sdcard0/平凡之路.mp3");
//设置data+type属性
intent.setDataAndType(data, "audio/mp3"); //方法:Intent android.content.Intent.setDataAndType(Uri data, String type)
startActivity(intent);
是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个
动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。
一个程序启动后系统会为这个程序分配一个task供其使用,另外同一个task里面可以拥有不同应用程序的activity。那么,同一个程序能不能拥有多个task?这就涉及到加载activity的启动模式,这个需要单独讲一下。
一、Activity和Task(栈)的关系
Task就像一个容器,而Activity就相当与填充这个容器的东西,第一个东西(Activity)则会处于最下面,最后添加的东西(Activity)则会在最低端。从Task中取出东西(Activity)则是从最顶端取出,也就是说最先取出的是最后添加的东西(Activity),一次类推,最后取出的是第一次添加的Activity,而Activity在Task中的顺序是可以控制的,那则在Activity跳转时用到Intent Flag
二、界面跳转和服务的启动都会用到Intent,现在介绍Intent Flag是关于Activity的跳转
Intent intent = new Intent(this,xxx.class);
//如果activity在task存在,拿到最顶端,不会启动新的Activity
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
//如果activity在task存在,将Activity之上的所有Activity结束掉
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//默认的跳转类型,将Activity放到一个新的Task中
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//如果Activity已经运行到了Task,再次跳转不会在运行这个Activity
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//打开指定网页
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://mp.csdn.net/postedit/84573605"));
startActivity(intent);
//打开拨号页面
Intent intent2 = new Intent(Intent.ACTION_DIAL);
intent2.setData(Uri.parse("tel:10010"));
startActivity(intent2);
//直接拨打指定电话号码
//注意:
Intent intent3 = new Intent(Intent.ACTION_CALL);
intent3.setData(Uri.parse("tel:10010"));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
return;
}
startActivity(intent3);
//打开发短信页面:action+type
Intent intent4 = new Intent(Intent.ACTION_VIEW);
intent.setType("vnd.android-dir/mms-sms");
intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
startActivity(intent);
//打开发短信的界面(指定电话号码):action+data
Intent intent5 = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("smsto:10010"));
intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
startActivity(intent);
//播放指定路径音乐
Intent intent6 = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///storage/sdcard0/平凡之路.mp3");//路径也可以写成:"/storage/sdcard0/平凡之路.mp3"
intent.setDataAndType(uri, "audio/mp3"); //方法:Intent android.content.Intent.setDataAndType(Uri data, String type)
startActivity(intent);
//卸载某个应用程序,根据包名来识别
Intent intent7 = new Intent(Intent.ACTION_DELETE);
Uri data = Uri.parse("package:com.example.smyh006intent01");
intent.setData(data);
startActivity(intent);
//安装某个应用程序,根据apk的文件名来识别
Intent intent8 = new Intent(Intent.ACTION_VIEW);
//路径不能写成"file:///storage/sdcard0/···"
Uri data1 = Uri.fromFile(new File("/storage/sdcard0/AndroidTest/smyh006_Intent01.apk"));
intent.setDataAndType(data1, "application/vnd.android.package-archive"); //Type的字符串为固定内容
startActivity(intent);