使用Intent来启动活动

——–阅读《第一行代码》整理———

Intent 是什么?

Intent用于在Android程序中各个组件之间的交互,不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传输数据。一般Intent被用于启动活动,启动服务,发送广播等等

首先先看看怎么启动活动

假设有FirstActivity和SecondActivity两个活动已经创建注册好了

在FirstActivity中,有一个Button,对应id为button_1

我们想在FirstActivity中点击Button就可以进入SecondActivity中

1. 显式Intent

我们现在修改FirstActivity中,Button的点击响应事件

@Override
protected void onCreate (Bundle savedInstanceState) {
    ……
    Button button1 = (Button) findViewById (R.id.button_1) ;
    button1.setOnClickListener (new OnClickListener() {
        @Override
        public void onClick (View v) {
            Intent intent = new Intent (FirstActivity.this , SecondActivity.class) ;
            startActivity (intent) ;
        }
    }) ;
}

这是Intent的其中一个构造函数
Intent (Context packageContext , Class <?> cls) ;
参数:
1. 第一个参数Context是启动活动的上下文
2. 第二个参数Class则是想要启动的目标活动
所以这里,我们的意图很明显

Intent intent = new Intent (FirstActivity.this , SecondActivity.class);

新建一个名字为intent的Intent对象,然后是从FirstActivity开始,启动SecondActivity

startActivity (intent) ;

通过startActivity ( )来执行这个Intent,传入构建好的intent
正因为这种Intent的意图十分明显,所以称作显式Intent

2. 隐式Intent

比起显式Intent,隐式Intent则更为含蓄,它通过一系列更加抽象的action和category,交由系统去分析这个Intent,从而找到对应的活动

Step 1:

通过在AndroidManifest.xml中配置SecondActivity,添加指定当前活动能够响应的action和category

……
<application
    ……
    >
    ……
    
    <activity
        android:name = ".SecondActivity"
        >
        <intent-filter>
            <action android:name = "com.example.activitytest.ACTION_START" />
            <category android:name = "android.intent.category.DEFAULT" />
        intent-filter>
    activity>
application>

标签中指明了当前活动可以响应的action是com.example.activitytest.ACTION_START;标签中则包含了一些附加信息,更加精确地指明了当前活动能够响应的Intent还可能带有的category。只有和中的内容可以同时匹配Intent中指定的action和category,这个活动才可以响应这个Intent

Step 2:

在FirstActivity.java中,设置Intent

@Override
protected void onCreate (Bundle savedInstanceState) {
    ……
    Button button1 = (Button)findViewById (R.id.button_1) ;
    button1.setOnClickListener (new OnClickListener() {
        @Override
        public void onClick (View v) {
            Intent intent = new Intent ("com.example.activitytest.ACTION_START") ;
            startActivity (intent) ;
        }
    }) ;
}

可以看出,我们直接传入action,intent可以响应这个action。奇怪的是,说好的category去哪了?原来,android.intent.category.DEFAULT是一种默认的category,在startActivity( )中会自动添加这个
但是:
如果我们修改category为其他的该怎么响应呢?
例如,category修改为或者添加下面代码:

name = "com.example.activitytest.MY_CATEGORY" />

那么我们便需要为intent添加多一个category:

Intent intent = new Intent =("com.example.activitytest.ACTION_START") ;
intent.addCategory ("com.example.activitytest.MY_CATEGORY") ;
startActivity (intent) ;

这样,便可以匹配到了
从这里我们可以看出,一个Intent只可以指定一个action,但是却可以指定多个category。

3. 更多隐式Intent的用法

a. 可以启动其他程序内的活动

例子:在FirstActivity中,点击Button可以打开一个网页,例如百度

实现方法有两个:要么自己实现一个浏览器(并不可能这么去做),要么调用系统浏览器来打开

显然,调用系统浏览器更加方便

修改FirstActivity.java中的Button点击部分的代码

@Override
protected void onCreate (Bundle savedInstanceState) {
    ……
    Button button1 = (Button) findViewById (R.id.button_1) ;
    button1.setOnClickListener (new OnClickListener () {
        @Override
        public void onClick (View v) {
            Intent intent = new Intent (Intent.ACTION_VIEW) ;
            intent.setData (Uri.parse("http://www.baidu.com")) ;
            startActivity (intent) ;
        }
    }) ;
}

效果是:点击Button之后,就会调用系统浏览器来打开百度这个网页
我们来关注这三行代码:

Intent intent = new Intent (Intent.ACTION_VIEW) ;
intent.setData (Uri.parse("http://www.baidu.com")) ;
startActivity (intent) ;

首先,指定了Intent的action是Intent.ACTION_VIEW。这是一个Android内置的动作。它的值为”android.intent.action.VIEW”。这个比较通用。它会根据数据类型来打开相应的活动
然后,我们使用Uri的parse( )方法,将传入的网址字符串转换为一个Uri对象,然后作为参数,调用Intent的setData( )方法,将这个Uri对象传递进去

关于Uri对象(以下这段在网上搜到的)

通用资源标志符(Universal Resource Identifier, 简称”URI”)。

Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。

在Android平台,URI主要分三个部分:scheme, authority and path。

其中authority又分为host和port。

格式如下:scheme://host:port/path

举个实际的例子:

content://com.example.project:200/folder/subfolder/etc
\-----/  \------------------/ \--/\----------------------/
scheme           host          port         path
         \-----------------------/
                  authority  

b. 更加精确地指定当前活动能够响应什么类型的数据

在活动注册文件中,在响应活动的<intent-filter>标签中再配置一个<data>标签

android:scheme:用于指定数据的协议部分,例如:http

android:host:指定数据的主机名部分,例如:www.baidu.com

android:port:指定数据的端口部分,紧随在主机名之后

android:path:用于指定主机名和端口之后的部分

android:mimeType:用于指定可以处理的数据类型

例子:让这个Android软件可以响应关于打开网页的请求

假设有项目中又创建了第三个活动ThirdActivity,则在它的注册页面代码为:

<activity
    android:name = ".ThirdActivity"
    >
    <intent-filter>
        <action android:name = "android.intent.action.VIEW" />
        <category android:name = "android.intent.category.DEFAULT" />
        <data android:scheme = "http" />
    intent-filter>
activity>

效果:这样,这个活动可以和浏览器一样响应关于网页的请求

同样的,也可以指定其他很多的协议,不一定是http协议,例如:

geo:显示地理位置

tel:拨打电话

例子:

button.setOnClickListener (new OnClickListener () {
    @Override
    public void onClick (View v) {
        Intent intent = new Intent (Intent.ACTION_VIEW) ;
        intent.setData (Uri.parse ("tel:10086")) ;
        startActivity (intent) ;
    }
}) ;

这样点击这个Button就可以调出拨号界面,并自动填充号码为10086

你可能感兴趣的:(Android)