Intent意图

 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。我们来看下面这个图就知道了

Intent意图_第1张图片

如果Activity1需要和Activity2进行联系,二者不需要直接联系,而是通过Intent作为桥梁。通俗来讲,Intnet类似于中介、媒婆的角色。

对于向这三种组件发送intent有不同的机制:

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的相关属性:

   Intent由以下各个组成部分:
  component(组件):目的组件
  action(动作):用来表现意图的行动
  category(类别):用来表现动作的类别
  data(数据):表示与动作要操纵的数据
  type(数据类型):对于data范例的描写
  extras(扩展信息):扩展信息
  Flags(标志位):期望这个意图的运行模式

 Intent类型分为显式Intent(直接类型),隐式(间接类型)。官方建议使用隐式Intent。 Component属性明确指定Intent的目标组件  的类名称。(属于直接Intent)

 相比与显示Intent,隐式Intent则含蓄了许多,他并不明确指出我们想要启动哪一个活动,而是指一系列为抽象的action和category的信息,然后交由系统去分析这个Intent,并帮助我们找出最合适的活动去启动。

Activity和Intent Filter的匹配过程:

Intent意图_第2张图片

1.Component(组件)目标组件:

 Component属性明确指定Intent的目标组件的类名称.(直接属于Intent)

 如果Component这个属性有指定的话, 将直接使用它指定的组件。指定了这个属性以后,Intent的其他所有的属性都可以选择。

例如:

 Intent intent2=new Intent();
 ComponentName componentName=new ComponentName(CurrentActivity.this,TargetActivity.class);
 intent2.setComponent(componentName);
 startActivity(intent2);

 1.通过Intent传递数据:

//发送数据  
Intent intent = new Intent(OneActivity.this, TwoActivity.class);
                intent.putExtra("intent", tvIntent.getText());
                startActivity(intent);
//取出数据
String intent1 = intent.getStringExtra("intent");
tvExhibitionMode.setText(intent1);

 

 通过startActivityForResult()返回数据值

 /**
   * 第一个页面  注意:返回数据时候需要有一个返回码
   */
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();


2.action(动作):用来表现意图的行为


当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想“做”三个俯卧撑;我要“写” 一封情书,等等。在Intent中,Action就是描述做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK等, 基本涵盖了常用动作。加的动作越多,越精确。
Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其 节点指定一个 Action列表用于标识 Activity 所能接受的“动作”

3.category(类别):用来表现动作的类别



   

   


//Action 和category通常是放在一起用的

代码解释:

    上面代码HomeActivity可以匹配到MY_ACTION这个动作,此时其他的Activity通过这个action的条件查找,直到找到和他条件符合他。

注意:如果没有指定action,就必须默认使的DEFAULT()

也就是说:只有中的内容同时能够匹配上Intent中指定的action和category时,这个活动才能响应Intent。如果使用的是DEFAULT这种默认的category,在稍后调用startActivity()方法的时候会自动将这个category添加到Intent中。


//启动另一个Activity,(通过action属性进行查找)
Intent intent = new Intent();
//设置动作(实际action属性就是一个字符串标记而已)
intent.setAction("com.xx.intent.MY_ACTION"); 
startActivity(intent);

既然在Intent中增加了一个category,那么我们要在清单文件中去声明这个category,不然程序将无法运行。代码如下:


      
             
             
              
                  

此时,点击MainActicity中的按钮,就会跳到HomeActivity中去。

总结如下:

自定义类别: 在Intent添加类别可以添加多个类别,那就要求被匹配的组件必须同时满足这多个类别,才能匹配成功。
操作Activity的时候,如果没有类别,须加上默认类别

4.data(数据):表示与动作要操作的数据

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); 

    5.type(数据类型):对于data范例的描写

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); 

6.extras(扩展信息):扩展信息

是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个
动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

7、Flags(标志位):期望这个意图的运行模式

一个程序启动后系统会为这个程序分配一个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);

8.系统常用的Intent

//打开指定网页
        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);

 

你可能感兴趣的:(android)