知识点:Intent
最后更新于:2022-04-01 16:16:12
### 一. Intent的介绍
- Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的activity, service和broadcast receiver之间的交互。
- Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来响应。
Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息,起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。
Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯。比如说调用 startActivity()来启动一个activity,或者由broadcaseIntent()来传递给所有感兴趣的 BroadcaseReceiver, 再或者由startService()/bindservice()来启动一个后台的service。所以可以看出来,intent主要是用来启动其他的 activity 或者service,所以可以将intent理解成activity之间的粘合剂。
### 主要用途
Intent是一种消息传递机制,它可以在应用程序内使用,也可以在应用程序间使用,主要用途分为:
1.使用类名显示的启动一个特定的Activity或Service
2.启动Activity或Service来执行一个动作的Intent,通常需要使用特定的数据,或者对特定的数据执行动作
3.广播某个事件已经发生
activity、service和broadcast receiver之间是通过Intent进行通信的,而另外一个组件Content Provider本身就是一种通信机制,不需要通过Intent。我们来看下面这个图就知道了:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-02-18_56c5a953f3470.png)
如果Activity1需要和Activity2进行联系,二者不需要直接联系,而是通过Intent作为桥梁。通俗来讲,Intnet类似于中介、媒婆的角色。
Intent最常见的一个用法是显示的(通过指定要装载的类)或隐式的(通过请求对一条数据执行某个动作)启动新的activity,在后一种情况下,动作不一定由调用应用程序中的Activty执行。
Intent也可以在系统范围内发送广播消息。应用程序可以注册一个Broadcast Receiver来监听相应这些广播的Intent。Android就是通过广播Intent来公布系统事件,比如网络连接状态或者电池电量的改变。
### 二. Inten启动组件的方法
Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。具体方法如下:
#### 对于向这三种组件发送intent有不同的机制:
- 使用Context.startActivity() 或 Activity.startActivityForResult(),传入一个intent来启动一个activity。使用 Activity.setResult(),传入一个intent来从activity中返回结果。
- 将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service。将intent对象传给 Context.bindService()来绑定一个service。
- 将intent对象传给 Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被传给 broadcast receiver。
<table align="center" width="400" border="1" cellpadding="2" cellspacing="0"><tbody><tr><td valign="top" width="194"><p align="center">组件名称</p></td><td valign="top" width="204"><p align="center">方法名称</p></td></tr><tr><td valign="top" width="191">Activity</td><td valign="top" width="207"><p>startActvity( ) </p><p>startActivityForResult( )</p></td></tr><tr><td valign="top" width="189">Service</td><td valign="top" width="209"><p>startService( ) </p><p>bindService( )</p></td></tr><tr><td valign="top" width="188">Broadcasts</td><td valign="top" width="211"><p>sendBroadcasts( ) </p><p>sendOrderedBroadcasts( ) </p><p>sendStickyBroadcasts( )</p></td></tr></tbody></table>
### 三. Intent的构成
Intent由以下各个组成部分:
- component(组件):目的组件
- action(动作):用来表现意图的行动
- category(类别):用来表现动作的类别
- data(数据):表示与动作要操纵的数据
- type(数据类型):对于data范例的描写
- extras(扩展信息):扩展信息
- Flags(标志位):期望这个意图的运行模式
#### 1、component(组件):目的组件
指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。
例如,启动第二个Activity时,我们可以这样来写:
~~~
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//创建一个意图对象
Intent intent = new Intent();
//创建组件,通过组件来响应
ComponentName component = new ComponentName(MainActivity.this, SecondActivity.class);
intent.setComponent(component);
startActivity(intent);
}
});
~~~
如果写的简单一点,监听事件onClick()方法里可以这样写:
~~~
Intent intent = new Intent();
//setClass函数的第一个参数是一个Context对象
//Context是一个类,Activity是Context类的子类,也就是说,所有的Activity对象,都可以向上转型为Context对象
//setClass函数的第二个参数是一个Class对象,在当前场景下,应该传入需要被启动的Activity类的class对象
intent.setClass(MainActivity.this, SecondActivity.class);
startActivity(intent);
~~~
再简单一点,可以这样写:(当然,也是最常见的写法)
~~~
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
~~~
#### 2、Action(动作):用来表现意图的行动
当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想“做”三个俯卧撑;我要“写”一封情书,等等。在Intent中,Action就是描述做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK等, 基本涵盖了常用动作。加的动作越多,越精确。
#### 标准的Activity Actions
ACTION_MAIN 作为一个主要的进入口,而并不期望去接受数据
ACTION_VIEW 向用户去显示数据
ACTION_ATTACH_DATA 用于指定一些数据应该附属于一些其他的地方,例如,图片数据应该附属于联系人
ACTION_EDIT 访问已给的数据,提供明确的可编辑
ACTION_PICK 从数据中选择一个子项目,并返回你所选中的项目
ACTION_CHOOSER 显示一个activity选择器,允许用户在进程之前选择他们想要的
ACTION_GET_CONTENT 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
ACTION_DIAL 拨打一个指定的号码,显示一个带有号码的用户界面,允许用户去启动呼叫
ACTION_CALL 根据指定的数据执行一次呼叫
(ACTION_CALL在应用中启动一次呼叫有缺陷,多数应用ACTION_DIAL,ACTION_CALL不能用在紧急呼叫上,紧急呼叫可以用ACTION_DIAL来实现)
ACTION_SEND 传递数据,被传送的数据没有指定,接收的action请求用户发数据
ACTION_SENDTO 发送一个信息到指定的某人
ACTION_ANSWER 处理一个打进电话呼叫
ACTION_INSERT 插入一条空项目到已给的容器
ACTION_DELETE 从容器中删除已给的数据
ACTION_RUN 运行数据,无论怎么
ACTION_SYNC 同步执行一个数据
ACTION_PICK_ACTIVITY 为已知的Intent选择一个Activity,返回别选中的类
ACTION_SEARCH 执行一次搜索
ACTION_WEB_SEARCH 执行一次web搜索
ACTION_FACTORY_TEST 工场测试的主要进入点,
#### 标准的广播Actions
ACTION_TIME_TICK 当前时间改变,每分钟都发送,不能通过组件声明来接收,只有通过Context.registerReceiver()方法来注册
ACTION_TIME_CHANGED 时间被设置
ACTION_TIMEZONE_CHANGED 时间区改变
ACTION_BOOT_COMPLETED 系统完成启动后,一次广播
ACTION_PACKAGE_ADDED 一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)
ACTION_PACKAGE_CHANGED 一个已存在的应用程序包已经改变,包括包名
ACTION_PACKAGE_REMOVED 一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
ACTION_PACKAGE_RESTARTED 用户重新开始一个包,包的所有进程将被杀死,所有与其联系的运行时间状态应该被移除,包括包名(重新开始包程序不能接收到这个广播)
ACTION_PACKAGE_DATA_CLEARED 用户已经清楚一个包的数据,包括包名(清除包程序不能接收到这个广播)
ACTION_BATTERY_CHANGED 电池的充电状态、电荷级别改变,不能通过组建声明接收这个广播,只有通过Context.registerReceiver()注册
ACTION_UID_REMOVED 一个用户ID已经从系统中移除
#### 3、category(类别):用来表现动作的类别
Intent中的Category属性是一个执行动作Action的附加信息。比如:CATEGORY_HOME则表示放回到Home界面,ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。
指定Action范围,这个选项指定了将要执行的这个action的其他一些额外的约束。有时通过Action,配合Data 或Type,很多时候可以准确的表达出一个完整的意图了,但也会需要加一些约束在里面才能够更精准。比如,如果你虽然很喜欢做俯卧撑,但一次做三个还只是在特殊的时候才会发生,那么你可能表达说:每次吃撑了的时候 ,我都想做三个俯卧撑。吃撑了,这就对应着Intent的Category的范畴,它给所发生的意图附加一个约束。在Android中,一个实例是:所有应用的主Activity(单独启动时候,第一个运行的那个Activity...),都需要一个Category为 CATEGORY_LAUNCHER,Action为ACTION_MAIN的Intent。
在自定义动作时,使用activity组件时,必须添加一个默认的类别
具体的实现为:
~~~
<intent-filter>
<action android:name="com.example.action.MY_ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
~~~
如果有多个组件被匹配成功,就会以对话框列表的方式让用户进行选择。
每个Intent中只能指定一个action,但却能指定多个category;类别越多,动作越具体,意图越明确(类似于相亲时,给对方提了很多要求)。
自定义类别: 在Intent添加类别可以添加多个类别,那就要求被匹配的组件必须同时满足这多个类别,才能匹配成功。操作Activity的时候,如果没有类别,须加上默认类别
| Constant | Meaning |
|-----|-----|
| `CATEGORY_BROWSABLE` | The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message. |
| `CATEGORY_GADGET` | The activity can be embedded inside of another activity that hosts gadgets. |
| `CATEGORY_HOME` | The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed. |
| `CATEGORY_LAUNCHER` | The activity can be the initial activity of a task and is listed in the top-level application launcher. |
| `CATEGORY_PREFERENCE` | The target activity is a preference panel. |
#### 4、data(数据):表示与动作要操纵的数据 =
- Data属性是Android要访问的数据,和action和Category声明方式相同,也是在<intent-filter>中。
- 多个组件匹配成功显示优先级高的; 相同显示列表。
Data是用一个uri对象来表示的,uri代表数据的地址,属于一种标识符。通常情况下,我们使用action+data属性的组合来描述一个意图:做什么
使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的功能共享成为了可能。比如应用程序中需要展示一个网页,没有必要自己去实现一个浏览器(事实上也不太可能),而是只需要条用系统的浏览器来打开这个网页就行了。
- 当Intent匹配成功的组件有多个时,显示优先级高的组件,如果优先级相同,显示列表让用户自己选择
- 优先级从-1000至1000,并且其中一个必须为负的才有效
注:系统默认的浏览器并没有做出优先级声明,其优先级默认为正数。
Data属性的声明中要指定访问数据的Uri和MIME类型。可以在<data>元素中通过一些属性来设置:
android:scheme、android:path、 android:port、android:mimeType、android:host等,通过这些属性来对应一个典型的Uri格式 scheme://host:port/path。例如:http://www.google.com。
#### 5、type(数据类型):对于data范例的描写
如果Intent对象中既包含Uri又包含Type,那么,在<intent-filter>中也必须二者都包含才能通过测试。
Type属性用于明确指定Data属性的数据类型或MIME类型,但是通常来说,当Intent不指定Data属性时,Type属性才会起作用,否则Android系统将会根据Data属性值来分析数据的类型,所以无需指定Type属性。
data和type属性一般只需要一个,通过setData方法会把type属性设置为null,相反设置setType方法会把data设置为null,如果想要两个属性同时设置,要使用Intent.setDataAndType()方法。
#### 6、extras(扩展信息):扩展信息
是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。
#### 7、Flags(标志位):期望这个意图的运行模式
一个程序启动后系统会为这个程序分配一个task供其使用,另外同一个task里面可以拥有不同应用程序的activity。那么,同一个程序能不能拥有多个task?这就涉及到加载activity的启动模式,这个需要单独讲一下。能识别,有输入,整个Intent基本就完整了,但还有一些附件的指令,需要放在Flags中带过去。顾名思义,Flags是一个整形数,有一些列的标志 位构成,这些标志,是用来指明运行模式的。比如,你期望这个意图的执行者,和你运行在两个完全不同的任务中(或说进程也无妨吧...),就需要设置**FLAG_ACTIVITY_NEW_TASK**的标志位。
注:android中一组逻辑上在一起的activity被叫做task,自己认为可以理解成一个activity堆栈。
### Intent 的解析机制
理解Intent的关键之一是理解清楚Intent的两种基本用法:一种是**显式的Intent**,即在构造Intent对象时就指定接收者;另一种是**隐式的Intent**,即Intent的发送者在构造Intent对象时,并不知道也不关心接收者是谁,有利于降低发送者和接收者之间的耦合。官方建议使用隐式Intent。上述属性中,component属性为直接类型,其他均为间接类型。
对于显式Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些隐式Intent,通过解析,将 Intent映射给可以处理此Intent的Activity、IntentReceiver或Service。
相比与显式Intent,隐式Intnet则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的活动去启动。
Activity 中 Intent Filter 的匹配过程 :
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-02-18_56c5a954193f0.png)
Intent 解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的 Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:
- 如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
- 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
- 如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme (比如 http: 或者[mailto](http://www.androidcn.net/wiki/index.php/Reference/android/content/mailto):) 进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
- 如果Intent指定了一个或多个category,这些类别必须**全部**出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。
**Intent-Filter的定义**
一些属性设置的例子:
~~~
<action android:name="com.example.project.SHOW_CURRENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="image/*" />
<data android:scheme="http" android:type="video/*" />
~~~
完整的实例
~~~
<activity android:name="NotesList" android:label="@string/title_notes_list">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
</intent-filter>
</activity>
~~~
### Intent的构造函数
公共构造函数:
1、Intent() 空构造函数
2、Intent(Intent o) 拷贝构造函数
3、Intent(String action) 指定action类型的构造函数
4、Intent(String action, Uri uri) 指定Action类型和Uri的构造函数,URI主要是结合程序之间的数据共享ContentProvider
5、Intent(Context packageContext, Class<?> cls) 传入组件的构造函数,也就是上文提到的
6、Intent(String action, Uri uri, Context packageContext, Class<?> cls) 前两种结合体
Intent有六种构造函数,3、4、5是最常用的,并不是其他没用!
Intent(String action, Uri uri) 的action就是对应在AndroidMainfest.xml中的action节点的name属性值。在Intent类中定义了很多的Action和Category常量。
**示例代码二:**
~~~
Intent intent = new Intent(Intent.ACTION_EDIT, null);
startActivity(intent);
~~~
示例代码二是用了第四种构造函数,只是uri参数为null。执行此代码的时候,系统就会在程序主配置文件AndroidMainfest.xml中寻找
<action android:name="android.intent.action.EDIT" />对应的Activity,如果对应为多个activity具有<action android:name="android.intent.action.EDIT" />此时就会弹出一个dailog选择Activity。
如果是用示例代码一那种方式进行发送则不会有这种情况。
**利用Intent在Activity之间传递数据**
在Main中执行如下代码:
~~~
Bundle bundle = new Bundle();
bundle.putStringArray("NAMEARR", nameArr);
Intent intent = new Intent(Main.this, CountList.class);
intent.putExtras(bundle);
startActivity(intent);
~~~
在CountList中,代码如下:
~~~
Bundle bundle = this.getIntent().getExtras();
String[] arrName = bundle.getStringArray("NAMEARR");
~~~
以上代码就实现了Activity之间的数据传递!
###总结说明
这篇文章是我刚开始学习Android时看到的,当时理解的不是很深入,现在再回头看这篇文章总结的很详细,在这里与大家分享。
1,调用web浏览器
~~~
<pre name="code" class="java">Uri myBlogUri = Uri.parse("http://kuikui.javaeye.com");
returnIt = new Intent(Intent.ACTION_VIEW, myBlogUri);
~~~
~~~
~~~
2,地图
~~~
Uri mapUri = Uri.parse("geo:38.899533,-77.036476");
returnIt = new Intent(Intent.ACTION_VIEW, mapUri);
~~~
3,调拨打电话界面
~~~
Uri telUri = Uri.parse("tel:100861");
returnIt = new Intent(Intent.ACTION_DIAL, telUri);
~~~
4,直接拨打电话
~~~
Uri callUri = Uri.parse("tel:100861");
returnIt = new Intent(Intent.ACTION_CALL, callUri);
~~~
5,卸载
~~~
Uri uninstallUri = Uri.fromParts("package", "xxx", null);
returnIt = new Intent(Intent.ACTION_DELETE, uninstallUri);
~~~
6,安装
~~~
Uri installUri = Uri.fromParts("package", "xxx", null);
returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);
~~~
7,播放
~~~
Uri playUri = Uri.parse("file:///sdcard/download/everything.mp3");
returnIt = new Intent(Intent.ACTION_VIEW, playUri);
~~~
8,调用发邮件
~~~
Uri emailUri = Uri.parse("mailto:shenrenkui@gmail.com");
returnIt = new Intent(Intent.ACTION_SENDTO, emailUri);
~~~
9,发邮件
~~~
returnIt = new Intent(Intent.ACTION_SEND);
String[] tos = { "shenrenkui@gmail.com" };
String[] ccs = { "shenrenkui@gmail.com" };
returnIt.putExtra(Intent.EXTRA_EMAIL, tos);
returnIt.putExtra(Intent.EXTRA_CC, ccs);
returnIt.putExtra(Intent.EXTRA_TEXT, "body");
returnIt.putExtra(Intent.EXTRA_SUBJECT, "subject");
returnIt.setType("message/rfc882");
Intent.createChooser(returnIt, "Choose Email Client");
~~~
10,发短信
~~~
Uri smsUri = Uri.parse("tel:100861");
returnIt = new Intent(Intent.ACTION_VIEW, smsUri);
returnIt.putExtra("sms_body", "shenrenkui");
returnIt.setType("vnd.android-dir/mms-sms");
~~~
11,直接发邮件
~~~
Uri smsToUri = Uri.parse("smsto://100861");
returnIt = new Intent(Intent.ACTION_SENDTO, smsToUri);
returnIt.putExtra("sms_body", "shenrenkui");
~~~
12,发彩信
~~~
Uri mmsUri = Uri.parse("content://media/external/images/media/23");
returnIt = new Intent(Intent.ACTION_SEND);
returnIt.putExtra("sms_body", "shenrenkui");
returnIt.putExtra(Intent.EXTRA_STREAM, mmsUri);
returnIt.setType("image/png");
~~~
用获取到的Intent直接调用startActivity(returnIt)就ok了。
###Intent用法实例
#### 1、打开指定网页:(直接复制的上面的代码)
MainActivity.java中,监听器部分的核心代码如下:
~~~
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);
}
});
~~~
第4行代码:指定了Intent的action是 **Intent.ACTION_VIEW**,表示查看的意思,这是一个Android系统内置的动作;
第5行代码:通过Uri.parse()方法,将一个网址字符串解析成一个Uri对象,再调用intent的setData()方法将这个Uri对象传递进去。
#### 2、打电话:
【方式一】打开拨打电话的界面:
~~~
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
~~~
运行程序后,点击按钮,显示如下界面:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-02-18_56c5a95434437.png)
【方式二】直接拨打电话:
~~~
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
~~~
要使用这个功能必须在配置文件中加入权限:(加一行代码)
~~~
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
~~~
#### 3、发送短信:
【方式一】打开发送短信的界面:action+type
~~~
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("vnd.android-dir/mms-sms");
intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
startActivity(intent);
~~~
【方式二】打开发短信的界面(同时指定电话号码):action+data
~~~
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("smsto:18780260012"));
intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
startActivity(intent);
~~~
#### 4、播放指定路径音乐:action+data+type
~~~
Intent intent = 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);
~~~
####5、卸载程序:action+data(例如点击按钮,卸载某个应用程序,根据包名来识别)
注:无论是安装还是卸载,应用程序是根据包名package来识别的。
~~~
Intent intent = new Intent(Intent.ACTION_DELETE);
Uri data = Uri.parse("package:com.example.smyh006intent01");
intent.setData(data);
startActivity(intent);
~~~
#### 6、安装程序:action+data+type
~~~
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.fromFile(new File("/storage/sdcard0/AndroidTest/smyh006_Intent01.apk")); //路径不能写成:"file:///storage/sdcard0/···"
intent.setDataAndType(data, "application/vnd.android.package-archive"); //Type的字符串为固定内容
startActivity(intent);
~~~
注:第2行的路径不能写成:"file:///storage/sdcard0/···",不然报错如下:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-02-18_56c5a9544b499.png)
综上所述,完整版代码如下:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/button1_browsePage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="browsePageClick"
android:text="打开指定网页"/>
<Button
android:id="@+id/button2_openDialPage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="openDialPageClick"
android:text="打开拨号面板"/>
<Button
android:id="@+id/button3_dialPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="dialPhoneClick"
android:text="直接拨打指定号码"/>
<Button
android:id="@+id/button4_openMsgPage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="openMsgPageClick"
android:text="打开发短信的界面"/>
<Button
android:id="@+id/button5_sendMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="sendMsgClick"
android:text="给指定的人发短信"/>
<Button
android:id="@+id/button6_playMusic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="playMusicClick"
android:text="播放指定路径音乐"/>
<Button
android:id="@+id/button7_uninstall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="uninstallClick"
android:text="卸载程序"/>
<Button
android:id="@+id/button8_install"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="installClick"
android:text="安装程序"/>
</LinearLayout>
~~~
MainActivity.java代码如下:
~~~
package com.example.m06intent01;
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//打开指定网页
public void browsePageClick(View view){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com/"));
startActivity(intent);
}
//打开拨号面板
public void openDialPageClick(View view){
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
//直接拨打指定号码
public void dialPhoneClick(View view){
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
//打开发短信的界面:action+type
public void openMsgPageClick(View view){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("vnd.android-dir/mms-sms");
intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
startActivity(intent);
}
//打开发短信的界面(指定电话号码):action+data
public void sendMsgClick(View view){
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("smsto:18780260012"));
intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
startActivity(intent);
}
//播放指定路径音乐
public void playMusicClick(View view){
Intent intent = 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);
}
//卸载某个应用程序,根据包名来识别
public void uninstallClick(View view){
Intent intent = new Intent(Intent.ACTION_DELETE);
Uri data = Uri.parse("package:com.example.smyh006intent01");
intent.setData(data);
startActivity(intent);
}
//安装某个应用程序,根据apk的文件名来识别
public void installClick(View view){
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.fromFile(new File("/storage/sdcard0/AndroidTest/smyh006_Intent01.apk")); //路径不能写成:"file:///storage/sdcard0/···"
intent.setDataAndType(data, "application/vnd.android.package-archive"); //Type的字符串为固定内容
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
~~~
**1.无参数Activity跳转**
~~~
Intent it = new Intent(Activity.Main.this, Activity2.class);
startActivity(it);
~~~
**2.向下一个Activity传递数据(使用Bundle和Intent.putExtras)**
~~~
Intent it = new Intent(Activity.Main.this, Activity2.class);
Bundle bundle=new Bundle();
bundle.putString("name", "This is from MainActivity!");
it.putExtras(bundle); // it.putExtra(“test”, "shuju”);
startActivity(it); // startActivityForResult(it,REQUEST_CODE);
~~~
对于数据的获取可以采用:
~~~
Bundle bundle=getIntent().getExtras();
String name=bundle.getString("name");
~~~
**3.向上一个Activity返回结果(使用setResult,针对startActivityForResult(it,REQUEST_CODE)启动的Activity)**
~~~
Intent intent=getIntent();
Bundle bundle2=new Bundle();
bundle2.putString("name", "This is from ShowMsg!");
intent.putExtras(bundle2);
setResult(RESULT_OK, intent);
~~~
**4.回调上一个Activity的结果处理函数(onActivityResult)**
~~~
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==REQUEST_CODE){
if(resultCode==RESULT_CANCELED)
setTitle("cancle");
else if (resultCode==RESULT_OK) {
String temp=null;
Bundle bundle=data.getExtras();
if(bundle!=null) temp=bundle.getString("name");
setTitle(temp);
}
}
}
~~~
运行后,主界面如下:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-02-18_56c5a9545ba57.png)
**下面是转载来的其他的一些Intent用法实例(转自javaeye)**
###显示网页
~~~
Uri uri = Uri.parse("http://google.com");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
~~~
### 显示地图
~~~
Uri uri = Uri.parse("geo:38.899533,-77.036476");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
//其他 geo URI 範例
//geo:latitude,longitude
//geo:latitude,longitude?z=zoom
//geo:0,0?q=my+street+address
//geo:0,0?q=business+near+city
//google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom
~~~
### 路径规划
~~~
Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
//where startLat, startLng, endLat, endLng are a long with 6 decimals like: 50.123456
~~~
### 打电话
~~~
//叫出拨号程序
Uri uri = Uri.parse("tel:0800000123");
Intent it = new Intent(Intent.ACTION_DIAL, uri);
startActivity(it);
//直接打电话出去
Uri uri = Uri.parse("tel:0800000123");
Intent it = new Intent(Intent.ACTION_CALL, uri);
startActivity(it);
//用這個,要在 AndroidManifest.xml 中,加上
//<uses-permission id="android.permission.CALL_PHONE" />
~~~
### 传送SMS/MMS
~~~
//调用短信程序
Intent it = new Intent(Intent.ACTION_VIEW, uri);
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);
//传送 MMS
Uri uri = Uri.parse("content://media/external/images/media/23");
Intent it = new Intent(Intent.ACTION_SEND);
it.putExtra("sms_body", "some text");
it.putExtra(Intent.EXTRA_STREAM, uri);
it.setType("image/png");
startActivity(it);
~~~
### 传送 Email
~~~
Uri uri = Uri.parse("mailto:xxx@abc.com");
Intent it = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(it);
Intent it = new Intent(Intent.ACTION_SEND);
it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");
it.putExtra(Intent.EXTRA_TEXT, "The email body text");
it.setType("text/plain");
startActivity(Intent.createChooser(it, "Choose Email Client"));
Intent it=new Intent(Intent.ACTION_SEND);
String[] tos={"me@abc.com"};
String[] ccs={"you@abc.com"};
it.putExtra(Intent.EXTRA_EMAIL, tos);
it.putExtra(Intent.EXTRA_CC, ccs);
it.putExtra(Intent.EXTRA_TEXT, "The email body text");
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");
it.setType("message/rfc822");
startActivity(Intent.createChooser(it, "Choose Email Client"));
//传送附件
Intent it = new Intent(Intent.ACTION_SEND);
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");
it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");
sendIntent.setType("audio/mp3");
startActivity(Intent.createChooser(it, "Choose Email Client"));
~~~
###播放多媒体
~~~
Uri uri = Uri.parse("file:///sdcard/song.mp3");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
it.setType("audio/mp3");
startActivity(it);
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
~~~
###Market 相关
~~~
//寻找某个应用
Uri uri = Uri.parse("market://search?q=pname:pkg_name");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
//where pkg_name is the full package path for an application
//显示某个应用的相关信息
Uri uri = Uri.parse("market://details?id=app_id");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
//where app_id is the application ID, find the ID
//by clicking on your application on Market home
//page, and notice the ID from the address bar
~~~
###Uninstall 应用程序
~~~
Uri uri = Uri.fromParts("package", strPackageName, null);
Intent it = new Intent(Intent.ACTION_DELETE, uri);
startActivity(it);
~~~
参考:
[http://www.cnblogs.com/smyhvae/p/3959204.html](http://www.cnblogs.com/smyhvae/p/3959204.html "http://www.cnblogs.com/smyhvae/p/3959204.html")
[http://blog.csdn.net/yulei_qq/article/details/21233901](http://blog.csdn.net/yulei_qq/article/details/21233901 "http://blog.csdn.net/yulei_qq/article/details/21233901")
[http://zy77612.iteye.com/blog/764699](http://zy77612.iteye.com/blog/764699 "http://zy77612.iteye.com/blog/764699")