1.1 要激活一个新的Activity,或者让一个现有的Activity做新的操作,可以通过调用Context.startActivity()或者Activity.startActivityForResult()方法。
1.2 要启动一个新的Service,或者向一个已有的Service传递新的指令,调用Context.startService()方法或者调用Context.bindService()方法将调用此方法的上下.Intent形式文对象与Service绑定。
1.3 Context.sendBroadcast()、Context.sendOrderBroadcast()、Context.sendStickBroadcast()这三个方法可以发送Broadcast Intent。发送之后,所有已注册的并且拥有与之相匹配IntentFilter的BroadcastReceiver就会被激活。
Intent一旦发出,Android都会准确找到相匹配的一个或多个Activity,Service或者BroadcastReceiver作响应。所以,不同类型的Intent消息不会出现重叠,即Broadcast的Intent消息只会发送给BroadcastReceiver,而决不会发送给Activity或者Service。由startActivity()传递的消息也只会发给Activity,由startService()传递的Intent只会发送给Service。
Intent形式
(1).显示意图(Explicit Intents)
明确指定组件名的Intent为显式意图,指定了Intent应该传递给那个组件。通过下面代码方式,可以创建显示意图实例化对象,并设定需要传递的参数信息。由于显示意图指定了具体的组件对象,不需要设置intent的其它意图过滤对象。
[java]
// 1.创建Intent实例化对象几种方式
Intent intent = new Intent();
intent.setClass(Context packageContext, Class<?> cls) ; //内部调用setComponent(ComponentName)
intent.setClassName(Context packageContext, String className) ; //内部调用setComponent(ComponentName)
intent.setClassName(String packageName, String className) ; //内部调用setComponent(ComponentName),可以激活外部应用
intent.setComponent(new ComponentName(this, Class<?> cls));
intent.setComponent(new ComponentName(this, "package Name"));
2).隐式意图(Implicit Intents)
没有明确指定组件名的Intent为隐式意图,系统会根据隐式意图中设置的 动作(action)、类别(category)、数据URI等来匹配最合适的组件。
1).action
The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, 包括Android 系统指定的 和 自定义
[java]
intent.setAction("com.baidu.action.TEST");
[html] view plaincopy
<action android:name="com.baidu.action.TEST"/>
2).data
expressed as a Uri, The data to operate on, such as a person record in the contacts database.
系统自带的Action简单举例
Action Data(Uri)Content
ACTION_VIEW
content://contacts/people/1
Display information about the person whose identifier is "1".
ACTION_VIEW
tel:123
Display the phone dialer with the given number filled in.
ACTION_DIAL
tel:123
Display the phone dialer with the given number filled in.
自定义data匹配
[java]
intent.setData(Uri.parse("baidu://www.baidu.com/news"));
[html]
<!-- android:path 内容字符串需要以 / 开头 -->
<data android:scheme="baidu" android:host="www.baidu.com" android:path="/news"/>
3).category
Gives additional information about the action to execute.
注意:项目清单的xml文件意图过滤器中必须指定 android.intent.category.DEFAULT类别,Activities will very often need to support the CATEGORY_DEFAULT so that they can be found by Context.startActivity,or Context can't the acitivity component
[java]
intent.addCategory("com.baidu.category.TEST");
[html]
<!-- 必须指定CATEGORY_DEFAULT,只有这样startActivity(intent)才能找到 -->
<category android:name="com.baidu.category.TEST" />
<category android:name="android.intent.category.DEFAULT" />
除了以上主要属性外,下面还有其它属性可以额外增强。
4).type
Specifies an explicit type (a MIME type) of the intent data.
[java]
intent.setType("image/jpeg");
[html] view plaincopy
<data android:mimeType="image/*" />
注意:java文件中data Uri 和 type不能同时使用各自的函数进行设定,因为使用type时会把Uri清除掉,可以使用setDataAndType方法设定
[java]
intent.setDataAndType(Uri.parse("baidu://www.baidu.com/news"), "image/jpeg");
[html]
<data android:mimeType="image/*" android:scheme="baidu" android:host="www.baidu.com" android:path="/news"/>
(3).两者的使用区别
显式意图一般在应用的内部使用,因为在应用内部已经知道了组件的名称,直接调用就可以了。
当一个应用要激活另一个应用中的Activity时,只能使用隐式意图,根据Activity配置的意图过滤器建一个意图,让意图中的各项参数的值都跟过滤器匹配,这样就可以激活其他应用中的Activity。所以,隐式意图是在应用与应用之间使用的。
ntent解析机制
Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有<intent-filter>及其中定义的Intent,通过PackageManager(注:PackageManager能够得到当前设备上所安装的
application package的信息)来查找能处理这个Intent的component。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:
1.1 如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
1.2 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
1.3 如果Intent中的数据不是content:类型的URI,而且Intent也没有明确指定type,将根据Intent中数据的scheme(比如 http:或者mailto:)进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
1.4 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。
[代码] 调用拨号程序
//
给移动客服10086拨打电话
Uri
uri = Uri.parse("tel:10086");
Intent
intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);
[代码] 发送短信或彩信
//
给10086发送内容为“Hello”的短信
Uri
uri = Uri.parse("smsto:10086");
Intent
intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body",
"Hello");
startActivity(intent);
//
发送彩信(相当于发送带附件的短信)
Intent
intent = new Intent(Intent.ACTION_SEND);
intent.putExtra("sms_body",
"Hello");
Uri
uri = Uri.parse("content://media/external/images/media/23");
intent.putExtra(Intent.EXTRA_STREAM,
uri);
intent.setType("image/png");
startActivity(intent);
[代码] 通过浏览器打开网页
//
打开Google主页
Uri
uri = Uri.parse("http://www.google.com");
Intent
intent =
new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
[代码] 发送电子邮件
//
给someone@domain.com发邮件
Uri
uri = Uri.parse("mailto:someone@domain.com");
Intent
intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(intent);
//
给someone@domain.com发邮件发送内容为“Hello”的邮件
Intent
intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL,
"someone@domain.com");
intent.putExtra(Intent.EXTRA_SUBJECT,
"Subject");
intent.putExtra(Intent.EXTRA_TEXT,
"Hello");
intent.setType("text/plain");
startActivity(intent);
//
给多人发邮件
Intent
intent=new Intent(Intent.ACTION_SEND);
String[]
tos = {"1@abc.com", "2@abc.com"}; // 收件人
String[]
ccs = {"3@abc.com", "4@abc.com"}; // 抄送
String[]
bccs = {"5@abc.com", "6@abc.com"}; // 密送
intent.putExtra(Intent.EXTRA_EMAIL,
tos);
intent.putExtra(Intent.EXTRA_CC,
ccs);
intent.putExtra(Intent.EXTRA_BCC,
bccs);
intent.putExtra(Intent.EXTRA_SUBJECT,
"Subject");
intent.putExtra(Intent.EXTRA_TEXT,
"Hello");
intent.setType("message/rfc822");
startActivity(intent);
[代码] 显示地图与路径规划
//
打开Google地图中国北京位置(北纬39.9,东经116.3)
Uri
uri = Uri.parse("geo:39.9,116.3");
Intent
intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
//
路径规划:从北京某地(北纬39.9,东经116.3)到上海某地(北纬31.2,东经121.4)
Uri
uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9 116.3&daddr=31.2 121.4");
Intent
intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
[代码] 播放多媒体
Intent
intent = new Intent(Intent.ACTION_VIEW);
Uri
uri = Uri.parse("file:///sdcard/foo.mp3");
intent.setDataAndType(uri,
"audio/mp3");
startActivity(intent);
Uri
uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");
Intent
intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
[代码] 拍照
//
打开拍照程序
Intent
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,
0);
//
取出照片数据
Bundle
extras = intent.getExtras();
Bitmap
bitmap = (Bitmap) extras.get("data");
[代码] 获取并剪切图片
//
获取并剪切图片
Intent
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra("crop",
"true"); // 开启剪切
intent.putExtra("aspectX",
1); // 剪切的宽高比为1:2
intent.putExtra("aspectY",
2);
intent.putExtra("outputX",
20); // 保存图片的宽和高
intent.putExtra("outputY",
40);
intent.putExtra("output",
Uri.fromFile(new File("/mnt/sdcard/temp"))); // 保存路径
intent.putExtra("outputFormat",
"JPEG");// 返回格式
startActivityForResult(intent,
0);
//
剪切特定图片
Intent
intent = new Intent("com.android.camera.action.CROP");
intent.setClassName("com.android.camera",
"com.android.camera.CropImage");
intent.setData(Uri.fromFile(new
File("/mnt/sdcard/temp")));
intent.putExtra("outputX",
1); // 剪切的宽高比为1:2
intent.putExtra("outputY",
2);
intent.putExtra("aspectX",
20); // 保存图片的宽和高
intent.putExtra("aspectY",
40);
intent.putExtra("scale",
true);
intent.putExtra("noFaceDetection",
true);
intent.putExtra("output",
Uri.parse("file:///mnt/sdcard/temp"));