Android学习——Intent

Android学习——Intent

1.什么是Intent

Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的activity,service和broadcast receiver之间的交互。Intent这个英语单词的本意是“目的、意向、意图"。

Intent是一种运行时绑定 (runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent, 你的程序可以向Android表达某种请求或者意愿.。Android会 根据意愿的内容选择适当的组件来响应。
在这里插入图片描述
对于向这三种组件发送Intent有不同的机制:

使用Context.startActivity() 或 Activity.startActivityForResult(),传入一个Intent来启动一个activity。

使用Асtіvіtу.ѕеtRеѕult(),传入一个Intent来从асtіvіtу中返回结果。

将Intent对象传给Context.startService()来启动一个 Service或者传消息给一个运行的Service。

将Intent对象传给Context.bindService()来绑定Service。

将Intent对象传给Context.sendBroadcast(), Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则他们给传给broadcast receiver。

2.Intent的相关属性

Intent由以下组成部分:

  1. component(组件):目的组件
  2. Action(动作):用来表现意图的行动
  3. category(类别):用来表现动作的类别(给动作加限制范围)
  4. data(数据):表示与动作要操纵的数据
  5. type(数据类型):对于data范例的描写(限制数据)
  6. extras(扩展信息):扩展信息
  7. Flags(标志位):期望这个意图的运行模式

Intent分为直接Intent和间接Intent

Activity中IntentFilter匹配过程
IntentFilter翻译成中文就是“意图过滤器”,主要用来过滤隐式意图。当用户进行一项操作的时候,Android系统会根据配置的 “意图过滤器” 来寻找可以响应该操作的组件,服务。
在这里插入图片描述

component(组件):目的组件

直接法:

 //直接查找法(通过组件名称)
    public void componentClick(View v){
    	//全写
//        Intent intent=new Intent();
//        ComponentName componentName=new ComponentName(this,Main2Activity.class);
//        intent.setComponent(componentName);
		//简写
       Intent intent=new Intent(this,Main2Activity.class);

       startActivity(intent);
    }

在这里插入图片描述在这里插入图片描述

Action(动作):用来表现意图的行动

当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想"做"三个俯卧撑;我要"看"一部电影等等。在Intent中, Action就是描述看、 做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK等,基本涵盖了常用动作。

Action是一个用户定义的字符串,用于描述一个Android应用程序组件,一个Intent Filter可以包含多个Action。在 AndroidManifest.xml的Activity定义时可以在其节点指定一个Action列表用于标识Activity所能接受的“动作”。

//间接法(通过Action属性)
    public void actionClick(View v){
        Intent intent=new Intent();
        intent.setAction("com.action.MY_ACTION");//匹配方,Action只能有一个
        startActivity(intent);
    }

简写

Intent intent=new Intent("com.action.MY_ACTION");

在清单文件中给Main3设置inten-filter

<activity
            android:name=".Main3Activity"
            android:label="@string/title_activity_main3">
            <intent-filter>
                <action android:name="com.action.MY_ACTION"></action>
                <category android:name="android.intent.category.DEFAULT"></category>//默认的类别,必须添加
            </intent-filter>
        </activity>

在这里插入图片描述在这里插入图片描述
给Main2也加上intent-filter

<activity
            android:name=".Main2Activity"
            android:label="@string/title_activity_main2" >
            <intent-filter>
                <action android:name="com.action.MY_ACTION"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>

则找到两个符合要求的,按优先级排序,优先级相同由用户进行选择。
在这里插入图片描述
设置优先级,给不想显示的activity的优先级设置为负数

<activity
	 android:name=".Main3Activity"
	  android:label="@string/title_activity_main3">
	  <intent-filter android:priority="-1">
	      <action android:name="com.action.MY_ACTION"></action>
	      <category android:name="android.intent.category.DEFAULT"></category>
	  </intent-filter>
	</activity>
	<activity
	  android:name=".Main2Activity"
	  android:label="@string/title_activity_main2" >
	  <intent-filter android:priority="2">
	      <action android:name="com.action.MY_ACTION"></action>
	      <category android:name="android.intent.category.DEFAULT"></category>
	  </intent-filter>
</activity>

在这里插入图片描述
ps:在被匹配方中可加多个action,只要找到对应的匹配项就可以。

category(类别):用来表现动作的类别(给动作加限制范围)

Category属性也是作为子元素来声明的。

<category android:name="com.category.MY_CATEGORY"></category>
/*
    * 间接法(通过Action属性和category属性)
    * 在Activity的清单文件配置中,必须使用默认的类别
    * android.intent.category.DEFAULT
    * */
    public void actionClick(View v){
//        Intent intent=new Intent("com.action.MY_ACTION");
        Intent intent=new Intent();
        intent.setAction("com.action.MY_ACTION");//Action最多只能有一个
        intent.addCategory("com.category.MY_CATEGORY");//类别可以添加多个
        startActivity(intent);
    }

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

Data属性是Android要访问的数据,和action和category声明方式相同,也是在中声明。

/*
    * data属性,一般与Action配合使用(此组合是最常见的使用方法)
    * */
    public void dataClick(View v){
        Intent intent=new Intent();
//        intent.setAction("com.action.MY_ACTION");
        intent.setAction(Intent.ACTION_VIEW);
        Uri data=Uri.parse("http://www.baidu.com");
        intent.setData(data);
        startActivity(intent);
    }

协议:android:scheme=""
路径:android:path=""
主机:android:host=""
端口:android:port=""
数据类型:android:mimeType=""

<intent-filter>
                <action android:name="com.action.MY_ACTION"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
                <data android:scheme="http" android:host="www.baidu.com"></data>
            </intent-filter>

在这里插入图片描述在这里插入图片描述

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

如果Intent对象中既包含Uri又包含Type,那么,在中也必须二者都包含才能通过测试。
Type属性则用于明确指定Data属性的数据类型或MIME类型(字符串,如.jpg/.png),但是通常来说,当Intent不指定Data属性时,Type属性才会起作用,否则Android系统会根据Data属性值来分析数据的类型,所以无需指定Type属性。

 /*
    * data属性,一般与Action配合使用(此组合是最常见的使用方法)
    * Type属性,用来表示数据的类型
    * */
    public void dataClick(View v){
        Intent intent=new Intent();
//        intent.setAction("com.action.MY_ACTION");
        intent.setAction(Intent.ACTION_VIEW);
        Uri data=Uri.parse("http://www.baidu.com");
//        intent.setData(data);//会把Type属性设置为空
//        intent.setType();//会把Data属性设置为空
        //要同时使用Data和Type,必须使用以下方法,匹配时必须两者同时匹配才能通过
        intent.setDataAndType(data,"text/html");
        startActivity(intent);
    }
<data android:scheme="http" android:host="www.baidu.com" android:mimeType="text/html"></data>

通常情况下只设置一个的比较常用

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

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

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

一个程序启动后系统会为这个程序分配- -个task供其使用, 另外同一个task 里面可以拥有不同应用程序的activity。那么,同 一个程序能不能拥有多个task?这就涉及到加载activity的四种模式: standard、singleTop、 singleTask、 singlelnstance。可以在AndroidManifest.xml中activity标签的属性launchMode中设置该activity的加载模式。

加载模式:android:launchMode=""

简述下这四种模式的区别:

  1. android:launchMode=“standard”:默认的模式,以这种模式加载每次启动会重新创建一个activity对象放到膜表task中的activity栈顶。
  2. android:launchMode=“singleTop”:这种模式与standard模式类似,区别在于加载activity会多个判断步骤。判断需要加载的新activity与当前task栈顶的activity是不是同一个,相同的话不在构造新的activity,并调用这个activity的newInstance()方法,不相同就还是会构造新的activity放到栈顶。
  3. android:launchMode=“singleTask”:在当前任务栈中,判断栈里是否存在Activity,如果不存在,创建一个新Activity入栈,如果存在,会把该Activity之上的所有Activity清除出栈,显示当前的Activity。
  4. android:launchMode=“singlelnstance”:这种模式下,会创建一个新的task,并且这个task中只能存在一个需要加载的这个Activity实例,即除了这个activity之外,不允许其他activity。如果已存在,那么会切换到该任务栈。

以下测试代码,可自行测试
新建两个文件,分为A,B
A:
在这里插入图片描述
B:
在这里插入图片描述
按钮事件:

public void startA(View v){
        Intent intent=new Intent(this,MainActivitya.class);
        startActivity(intent);
    }
    public void startB(View v){
        Intent intent=new Intent(this,MainActivityb.class);
        startActivity(intent);
    }

清单文件

<activity
    android:name=".MainActivityb"
    android:label="@string/title_activity_main_activityb"
    android:launchMode="standard"//在此修改加载模式>

</activity>
<activity
    android:name=".MainActivitya"
    android:label="@string/title_activity_main_activitya">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

用代码设置Activity的启动模式

public void flagClick(View v){
    Intent intent=new Intent(this,Main5Activity.class);
    //设置Activity的启动模式
    //Intent.FLAG_ACTIVITY_NEW_TASK  在新的任务栈中启动Activity,如果有,那么就在本任务中启动
    //
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

常用的三个属性:
FLAG_ACTIVITY_NEW_TASK 在新的任务栈中启动Activity
FLAG_ACTIVITY_CLEAR_TASK==singleTask
FLAG_ACTIVITY_CLEAR_TOP==singleTop

3.Intent应用

显示网页:

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

拨打电话:调用拨号程序(拨号面板,并不直接拨打)

 Uri data=Uri.parse("tel:xxxxxx");
 Intent intent=new Intent(Intent.ACTION_DIAL,data);
 startActivity(intent);

拨打电话:(直接拨打)
这个必须在配置文件中加入

 Uri data=Uri.parse("tel:xxxxxx");
 Intent intent=new Intent(Intent.ACTION_CALL,data);
 startActivity(intent);

发送SMS/MMS:调用发短信的程序

 Intent it=new Intent(Intent.ACTION_VIEW);
 it.putExtra("sms_body","The SMS text");
 it.setType("vnd.android-dir/mms-sms");
 startActivity(it);

发送短信

Uri uri=Uri.parse("smsto:0800000123");
Intent it=new Intent(Intent.ACTION_SENDTO,uri);
it.putExtra("sms_body","The SMS text");
startActivity(it);

播放多媒体

Uri uri=Uri.parse("file:///sdcard/song.mp3");
Intent it=new Intent(Intent.ACTION_VIEW,uri);
//it.addFlags(it.FLAG_ACTIVITY_NEW_TASK);//非必须选项
it.setDataAndType(uri,"audio/mp3");
startActivity(it);

Unistall 程序

Uri uri=Uri.parse("package:包名");
Intent it=new Intent(Intent.ACTION_DELETE,uri);
startActivity(it);

安装apk

Uri uri=Uri.fromFile(new File("文件路径"));
String action=Intent.ACTION_VIEW;
Intent intent=new Intent();
intent.setAction(action);
intent.setDataAndType(uri,"application/vnd.android.package-archive");
startActivity(intent);

猜你喜欢

转载自blog.csdn.net/UUUUUltraman/article/details/88941833