【Android笔记】关于Intent

        • 一、Intent的七大属性
        • 二、显式Intent
        • 二、隐式Intent
            • 1、隐式Intent(一)——action
            • 2、隐式Intent(二)——action
            • 3、隐式Intent(三)——action
            • 4、隐式Intent(四)——category
            • 5、隐式Intent(五)——data
            • 6、隐式Intent(六)——data


说明:Intent是“意图”的意思,Intent通过指明当前组件想要执行的动作,让系统知道我们的“意图”之后,完成的一系列操作,除此之外,Intent还可以在不同组件之间传递数据。Intent一般可被用于启动活动(Activity(startActivity(intent)))、启动服务(Service(startService(intent)))以及发送广播(Broadcast(sendBroadcast(intent)))等场景,本篇笔记主要记载Intent启动活动的知识。
Intent大致可以分为两种:显式Intent隐式Intent


一、Intent的七大属性

①ComponentName(组件):目的组件
②Action(动作):用来表现意图的行动
③Category(类别):用来表现动作的类别
④Data(数据):表示与动作要操纵的数据
⑤Type(数据类型):对于data范例的描写
⑥Extra(扩展信息):扩展信息
⑦Flags(标志位):期望这个意图的运行模式

按照分类可以分为以下三种:
1.用于启动:ComponetName(显式)、Action(隐式)、Category(隐式)。
2.用于传递数据:Data(隐式)、Type(隐式)、Extra(显式、隐式)。
3.用于规定启动模式:Flags.
有关七大属性讲解详见《Intent七大属性》


二、显式Intent

Intent有多个构造函数的重载,其中一个是:
Intent(Context packageContext,Class cls)
第一个参数Context要求提供一个启动活动的上下文;
第二个参数Class指定想要启动的活动目标.
通过这个构造函数就可以构建出Intent的“意图”,最后调用startActivity()方法就可以启动目标活动了。

在MainActivity中重写onClick()方法:

@Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.start_aty2:
                Intent intent = new Intent(MainActivity.this,Aty2.class);
                startActivity(intent);
        }
    }

或者:

@Override
    public void onClick(View view) {
        Intent intent = new Intent();
        switch (view.getId()){
            case R.id.start_aty2:
                intent.setClass(MainActivity.this,Aty2.class);
                //或者调用setComponent方法说明“意图”,启动活动
                //intent.setComponent(new ComponentName(MainActivity.this,Aty2.class));
                startActivity(intent);
        }
    }

效果图:
【Android笔记】关于Intent_第1张图片 【Android笔记】关于Intent_第2张图片

通过查看源码,可以发现ComponentName还有其他三种构造函数的重载
【Android笔记】关于Intent_第3张图片
所以我们也可以通过包名来说明“意图”,启动其他活动。
有关用法可以参考:《[Android基础]Intent用法的二三事(上)》


二、隐式Intent

隐式Intent并不明确指出我们想要启动哪一个活动,而是通过指定一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的活动去启动。
通过隐式配置的Activity可以跨应用被启动。
如果不想被别的应用启动,可以在activity配置中加上:android:exported="false"(默认为true)

1、隐式Intent(一)——action

(1)首先我们需要给aty3配置intent-filter,指定当前活动能够响应的action和category,打开AndroidManifest.xml,添加如下代码:
【Android笔记】关于Intent_第4张图片

配置action名字的规则通常为:包名.intent.action.类名字

(2)在MainActivity的onClick()方法中:

case R.id.start_aty3:
                intent.setAction("com.example.aboutintent.intent.action");
                startActivity(intent);

或者:

case R.id.start_aty3:
                Intent intent = new Intent("com.example.aboutintent.intent.action");
                startActivity(intent);

效果图:
【Android笔记】关于Intent_第5张图片 【Android笔记】关于Intent_第6张图片

这是最简单的隐式Intent,指明action且该action名字只属于该Activity,即可启动活动。

action的匹配规则:
(1)对于设置了action的Activity来说,如果要隐式启动该Activity,就必须匹配到它的action
(2)每个Activity可以设置多个action,但是匹配的时候只能匹配其中一种。

系统也有一些自带的action属性值供我们参考:

属性值 作用
ACTION_MAIN 程序入口,每个APP必须至少有一个Activity包含一个此类型的Action说明。
ACTION_DIAL 打开系统默认的拨号程序,如果Data中设置了电话号码,则自动在拨号程序中输入此号码。
ACTION_CALL 直接拨打Data设置好的号码
ACTION_VIEW 根据不同的Data类型,显示不同的数据
ACTION_SEND 由用户指定发送方式进行数据发送操作
2、隐式Intent(二)——action

当两个activity配置的action是一样的时候,那么系统会启动哪个活动呢?
(1)配置intent-filter
【Android笔记】关于Intent_第7张图片

(2)在MainActivity中不变

效果图:
【Android笔记】关于Intent_第8张图片 【Android笔记】关于Intent_第9张图片

因此,不同的Activity配置同一个action值时,使用Intent通过action去启动Activity时,Android通过过滤器对action进行匹配筛选,就会得到多个Activity。

3、隐式Intent(三)——action

前面我们已经说过通过隐式Intent我们可以跨应用启动活动。
(1)首先我们在同一个项目中新建一个module——app1
(2)在app1的入口活动中添加按钮控件,并加入响应事件:

findViewById(R.id.app1_start_aty3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.aboutintent.intent.action");
                startActivity(intent);
            }
        });

(3)运行app1
效果图:
【Android笔记】关于Intent_第10张图片 【Android笔记】关于Intent_第11张图片

(4)假如我们给aty3配置:android:exported="false",即
【Android笔记】关于Intent_第12张图片
再次运行app1并启动aty3会发生什么呢?
效果图:
【Android笔记】关于Intent_第13张图片
会发生报错,我们看一下打印日志:
【Android笔记】关于Intent_第14张图片
可以看出app1没有aty3的访问权。
当然我们可以通过try{}catch{}解决这个问题:

findViewById(R.id.app1_start_aty3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    Intent intent = new Intent("com.example.aboutintent.intent.action");
                    startActivity(intent);
                }catch (Exception e){
                    Toast.makeText(MainActivity.this,"没有访问权限",Toast.LENGTH_SHORT).show();
                }
            }
        });

效果图:
【Android笔记】关于Intent_第15张图片
(当然,这只是我这个小菜鸡的菜鸡解决方法,如果还有其他解决方法,也可以交流一哈)

4、隐式Intent(四)——category

category的匹配规则:
category也是一个用户自定义的字符串,但和action不一样的是,它可以在intent中通过intent.addCategory设置多个category的值。

(1)假设我们给aty3配置多一个category:
【Android笔记】关于Intent_第16张图片
(2)然后在MainActivity中的onCreat()方法加上:
【Android笔记】关于Intent_第17张图片
那么还会不会出现上面展示两种活动让你选择的情况呢?
明显是不会了。
因此,在匹配时,通过过滤器寻找到的Activity必须包含intent设置的所有category的值。

注意:CATEGORY_DEFAULT是隐式启动一个Activity必不可少的一个属性值。使用隐式启动Activity,我们都应该主动加上CATEGORY_DEFAULT这个属性值。(app入口Activity除外)

5、隐式Intent(五)——data

我们知道,使用隐式Intent还可以启动其他程序的活动,除了上面我们自己创建的app1,还可以启动百度、系统自带的拨号程序什么的,这可以实现Android多个应用程序的功能共享。比如说你的应用程序中需要展示一个网页,这时你没有必要自己去实现一个浏览器,而是只需要调用系统自带的浏览器来打开这个网页就可以了。
(1)启动百度:

case R.id.start_baidu:
                intent.setAction(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("http://www.baidu.com"));
                startActivity(intent);
                break;

这里我们首先指定了Intent的action是Intent.ACTION_VIEW,这是Android系统内置的动作,其常量值为android.intent.action.VIEW。然后通过Uri.parse()方法,讲一个网址字符串解析成一个Uri对象,再调用Intent的setData()方法将这个Uri对象传递进去。
效果图:
【Android笔记】关于Intent_第18张图片 【Android笔记】关于Intent_第19张图片

(2)启动拨号面板:

case R.id.start_dial:
                intent.setAction(Intent.ACTION_DIAL);
                intent.setData(Uri.parse("tel:10086"));
                startActivity(intent);
                break;

【Android笔记】关于Intent_第20张图片 【Android笔记】关于Intent_第21张图片

6、隐式Intent(六)——data

我们给aty3配置data属性并加上,再次点击隐式启动百度按钮,看看会发生什么?
【Android笔记】关于Intent_第22张图片

可以看出系统自动弹出了一个列表,显示了目前能够响应这个Intent的所有程序。因为我们在标签中通过android:scheme指定了数据的协议必须是http协议,这样Aty3就和浏览器一样。能够响应一个打开网页的Intent了。
需要注意的是:虽然我们声明了Aty3是可以响应打开网页的Intent,但实际上这个活动并没有加载并显示网页的功能,所以真正的项目中尽量不要出现这种有可能误导用户的行为,不然用户体验极差。

参考来自:http://blog.csdn.net/tahlia_/article/details/78020003
http://blog.csdn.net/iblade/article/details/50478701

你可能感兴趣的:(Android,笔记,笔记整理,Android)