—Intent:一个intent就是一次对将要执行的操作的抽象描述。
一、Intent显式激活组件
1、即明确指定要激活的组件
//SecondActivity是将要启动的另一个activity
// //方法1> 直接设置参数
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
// Intent intent = new Intent();
// //方法2> 用setClass的方法设置下一个Activity
// intent.setClass(MainActivity.this, SecondActivity.class);
// //方法3> 设置下一个要激活的组件
// intent.setComponent(new ComponentName(this, SecondActivity.class));
// //方法4> 直接打开当前应用中的某个Activity
// intent.setClassName(this, "com.example.edittext.SecondActivity");
// //方法5> 打开其它应用中的Activity
// intent.setClassName("com.test.Activity", "com.example.edittext.SecondActivity");
//
//单个参数传递
// intent.putExtra("name", "张三");
// intent.putExtra("age", 20);
//批量参数传递
Bundle bundle = new Bundle();
bundle.putString("name", "张三");
bundle.putInt("age", 20);
intent.putExtras(bundle);
startActivity(intent);//启动另一个Activity
2、注册Activity,每个Activity必须要在androidManifest.xml文件中注册
<activity
android:name="com.example.edittext.SecondActivity"
android:label="SecondActivity"/>
3、被启动的activity
public class SecondActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
Intent intent = this.getIntent();// getIntent方法可以得到传递过来的Intent
//单个参数获取
// String name = intent.getStringExtra("name");
// int aget = intent.getIntExtra("age", 0);//第二个参数是默认值,如果没有取到值就用它
//批量参数获取
Bundle bundle = intent.getExtras();// getExtras方法可以获得intent中的键值对
String name = bundle.getString("name");
int age = bundle.getInt("age");
}
}
二、Intent隐式激活组件 :
1、即不明确指定要激活的组件
//1、当没有数据参数时,只要Intent中的Action和Category都出现在intent-filter中,就能匹配成功并激活此组件
Intent intent = new Intent();
intent.setAction("android.intent.action.MyAction");
intent.addCategory("com.example.edittext.MyCategory");
//startActivity方法默认会给Intent添加android.intent.category.DEFAULT的Category,所以在Manifest.xml文件中要加上这个Category
startActivity(intent);
// //2、当有数据而没有数据类型时,用setData设置数据
// intent.setData(Uri.parse("itcast://www.itcast.cn/hello"));
// //3、当有数据和数据类型时,必须用setDataAndType同时设置,否则设置类型时会把设置的数据清除掉
// intent.setDataAndType(Uri.parse("itcast://www.itcast.cn/hello"), "image/jpeg");
2、activity的配置
<activity android:name="com.example.edittext.SecondActivity" >
<intent-filter>
<action android:name="com.example.edittext.MySecondAct" />
<category android:name="com.example.edittext.MyCategory" />
<category android:name="android.intent.category.DEFAULT" />
<!-- 设置数据 -->
<!-- scheme是网站协议的开头 -->
<data android:scheme="itcast" />
<!-- host是我们的网站名字 -->
<data android:host="www.itcast.cn" />
<!-- mimeType是类型 -->
<data android:mimeType="image/jpeg" />
<data android:path="/hello" />
</intent-filter>
</activity>
二、Intent接收Activity返回的结果
—a) MainActivity中:
private final static int REQUEST_CODE=1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent();
ntent.setClass(MainActivity.this, SecondActivity.class);
intent.putExtra("str", "this is intent...");
startActivityForResult(intent, REQUEST_CODE);//启动另一个activity
}
//重写onActivityResult方法接收上面启动的那个activity的返回值
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE){
if(resultCode == SecondActivity.RESULT_CODE){
Bundle bundle = data.getExtras();
String str = bundle.getString("secdata");
Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
}
}
}
}
—b) SecondActivity中:
public final static int RESULT_CODE = 1;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
Intent inte = new Intent();
Inte.putExtra("secdata", "sec intent");//设置参数
setResult(RESULT_CODE, inte);//设置返回结果
finish();//结束当前activity
}
三、Intent拨号:
// //1、调用系统自带拨号器的拨号Activity来拨号
// Intent intent = new Intent();
// intent.setAction("android.intent.action.CALL");//设置拨号动作:Intent.ACTION_CALL
// intent.setData(Uri.parse("tel:5556"));//设置号码
// startActivity(intent);//开始拨号
// //2、通过Uri调用系统自带拨号程序来拨号
// Uri uri = Uri.parse("tel:5556");
// Intent it = new Intent(Intent.ACTION_DIAL, uri);
// startActivity(it);
//3、直接打电话出去
Uri uri = Uri.parse("tel:5556");
Intent it = new Intent(Intent.ACTION_CALL, uri);
startActivity(it);
//用这个,要在 AndroidManifest.xml中,加上 拨号权限
//<uses-permission id="android.permission.CALL_PHONE" />
四、Intent发短信
—1、用intent调用系统发短信程序:
// //使用SmsManager发短信
// String number = "5556";
// String content = "hello worldlskdjlafkjslkdjf";
// SmsManager manager = SmsManager.getDefault();
// //如果短信内容超过字数限制则会拆分成多个短信
// ArrayList<String> messages = manager.divideMessage(content);
// for(String message : messages){
// manager.sendTextMessage(number, null, message, null, null);
// }
//使用Intent发短信
Uri uri = Uri.parse("smsto:5556");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "The SMS text");
startActivity(intent);//开始进入发短信界面
—2、需要在AndroidManifest.xml文件中设置发短信的权限:
<uses-permission android:name="android.permission.SEND_SMS" />
五、Intent显示网页
Uri uri = Uri.parse("http://www.google.com");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
六、intent-filter
如果一个 Intent 请求在一片数据上执行一个动作, Android 如何知道哪个应用程序(和组件)能用来响应这个请求呢? Intent Filter就是用来注册 Activity、Service和Broadcast Receiver 具有能在某种数据上执行一个动作的能力。
使用 Intent Filter ,应用程序组件告诉 Android ,它们能为其它程序的组件的动作请求提供服务,包括同一个程序的组件、本地的或第三方的应用程序。
使用 Intent Filter ,应用程序组件告诉 Android ,它们能为其它程序的组件的动作请求提供服务,包括同一个程序的组件、本地的或第三方的应用程序。
1、定义
scheme, host, port, path, pathPrefix, pathPattern 是用来匹配 Intent 中的 Data Uri 的。具体规则如下:
scheme://host:port/path or pathPrefix or pathPattern
上面那句最后的 “path or pathPrefix or pathPattern” 是指后面的 path 验证可以使用 data 属性中的
android:path、android:pathPrefix 或 pathPattern,你可以添加任意个 data 标签,由于是 “or” ,因此,只要其
中任意一个 data 匹配,系统就会选择你的 Activity 启动,当然,如果别的 Activity 也有相同的 data 标签,系统
就会给用户弹出一个 Chooser Dialog。
2、区别
这里主要说的区别是 path、pathPrefix、pathPattern 之间的区别
path 用来匹配完整的路径,如:http://example.com/blog/abc.html,这里将 path 设置为 /blog/abc.html 才能够进行匹配;
pathPrefix 用来匹配路径的开头部分,拿上面的 Uri 来说,这里将 pathPrefix 设置为 /blog 就能进行匹配了;
pathPattern 用表达式来匹配整个路径,这里需要说下匹配符号与转义。
scheme, host, port, path, pathPrefix, pathPattern 是用来匹配 Intent 中的 Data Uri 的。具体规则如下:
scheme://host:port/path or pathPrefix or pathPattern
上面那句最后的 “path or pathPrefix or pathPattern” 是指后面的 path 验证可以使用 data 属性中的
android:path、android:pathPrefix 或 pathPattern,你可以添加任意个 data 标签,由于是 “or” ,因此,只要其
中任意一个 data 匹配,系统就会选择你的 Activity 启动,当然,如果别的 Activity 也有相同的 data 标签,系统
就会给用户弹出一个 Chooser Dialog。
2、区别
这里主要说的区别是 path、pathPrefix、pathPattern 之间的区别
path 用来匹配完整的路径,如:http://example.com/blog/abc.html,这里将 path 设置为 /blog/abc.html 才能够进行匹配;
pathPrefix 用来匹配路径的开头部分,拿上面的 Uri 来说,这里将 pathPrefix 设置为 /blog 就能进行匹配了;
pathPattern 用表达式来匹配整个路径,这里需要说下匹配符号与转义。
匹配符号:
1) “*” 用来匹配0次或更多,如:“a*” 可以匹配“a”、“aa”、“aaa”...
2) “.” 用来匹配任意字符,如:“.” 可以匹配“a”、“b”,“c”...
3) 因此 “.*” 就是用来匹配任意字符0次或更多,如:“.*html” 可以匹配 “abchtml”、“chtml”,“html”,“sdf.html”...
1) “*” 用来匹配0次或更多,如:“a*” 可以匹配“a”、“aa”、“aaa”...
2) “.” 用来匹配任意字符,如:“.” 可以匹配“a”、“b”,“c”...
3) 因此 “.*” 就是用来匹配任意字符0次或更多,如:“.*html” 可以匹配 “abchtml”、“chtml”,“html”,“sdf.html”...
转义:
因为当读取 Xml 的时候,“\” 是被当作转义字符的(当它被用作 pathPattern 转义之前),因此这里需要两次转义,读取 Xml 是一次,在 pathPattern 中使用又是一次。如:“*” 这个字符就应该写成 “\\*”,“\” 这个字符就
应该写成 “\\\\”。
3、MIME TYPE描述
多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions)是一个互联网标准,它扩展了电子邮件标准
,使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。
内容类型(Content-Type),这个头部领域用于指定消息的类型。一般以下面的形式出现。[type]/[subtype]
type有下面的形式。
Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据;
Application:用于传输应用程序数据或者二进制数据;
Message:用于包装一个E-mail消息;
Image:用于传输静态图片数据;
Audio:用于传输音频或者音声数据;
Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。
subtype用于指定type的详细形式。content-type/subtype配对的集合和与此相关的参数,将随着时间而增长。为了确保
这些值在一个有序而且公开的状态下开发,MIME使用Internet Assigned Numbers Authority (IANA)作为中心的注册机
制来管理这些值。常用的subtype值如下所示:
text/plain(纯文本)
text/html(HTML文档)
application/xhtml+xml(XHTML文档)
image/gif(GIF图像)
image/jpeg(JPEG图像)【PHP中为:image/pjpeg】
image/png(PNG图像)【PHP中为:image/x-png】
video/mpeg(MPEG动画)
application/octet-stream(任意的二进制数据)
application/pdf(PDF文档)
application/msword(Microsoft Word文件)
message/rfc822(RFC 822形式)
multipart/alternative(HTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示)
application/x-www-form-urlencoded(使用HTTP的POST方法提交的表单)
multipart/form-data(同上,但主要用于表单提交时伴随文件上传的场合)
这里需要十分注意的是 Intent.setType(), Intent.setData,Intent.setDataAndType() 这三个方法!
setType 调用后设置 mimeType,然后将 data 置为 null;
setData 调用后设置 data,然后将 mimeType 置为 null;
setDataAndType 调用后才会同时设置 data 与 mimeType。
另外需要注意的是,如果你在 data 标签,既设置了 mimeType 又设置了 scheme 之内的,那么你的 Intent 需要同时
设置匹配的 data 与 mimeType 即调用 setDataAndType ,系统才能匹配到这个 Activity(即便你 mimeType 设置为
"*/*" 也是如此)。当然,如果你没有设置 mimeType,那么调用 setData 进行匹配,如果你设置了任何的 mimeType
将不会匹配到该 Activity。
因为当读取 Xml 的时候,“\” 是被当作转义字符的(当它被用作 pathPattern 转义之前),因此这里需要两次转义,读取 Xml 是一次,在 pathPattern 中使用又是一次。如:“*” 这个字符就应该写成 “\\*”,“\” 这个字符就
应该写成 “\\\\”。
3、MIME TYPE描述
多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions)是一个互联网标准,它扩展了电子邮件标准
,使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。
内容类型(Content-Type),这个头部领域用于指定消息的类型。一般以下面的形式出现。[type]/[subtype]
type有下面的形式。
Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据;
Application:用于传输应用程序数据或者二进制数据;
Message:用于包装一个E-mail消息;
Image:用于传输静态图片数据;
Audio:用于传输音频或者音声数据;
Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。
subtype用于指定type的详细形式。content-type/subtype配对的集合和与此相关的参数,将随着时间而增长。为了确保
这些值在一个有序而且公开的状态下开发,MIME使用Internet Assigned Numbers Authority (IANA)作为中心的注册机
制来管理这些值。常用的subtype值如下所示:
text/plain(纯文本)
text/html(HTML文档)
application/xhtml+xml(XHTML文档)
image/gif(GIF图像)
image/jpeg(JPEG图像)【PHP中为:image/pjpeg】
image/png(PNG图像)【PHP中为:image/x-png】
video/mpeg(MPEG动画)
application/octet-stream(任意的二进制数据)
application/pdf(PDF文档)
application/msword(Microsoft Word文件)
message/rfc822(RFC 822形式)
multipart/alternative(HTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示)
application/x-www-form-urlencoded(使用HTTP的POST方法提交的表单)
multipart/form-data(同上,但主要用于表单提交时伴随文件上传的场合)
这里需要十分注意的是 Intent.setType(), Intent.setData,Intent.setDataAndType() 这三个方法!
setType 调用后设置 mimeType,然后将 data 置为 null;
setData 调用后设置 data,然后将 mimeType 置为 null;
setDataAndType 调用后才会同时设置 data 与 mimeType。
另外需要注意的是,如果你在 data 标签,既设置了 mimeType 又设置了 scheme 之内的,那么你的 Intent 需要同时
设置匹配的 data 与 mimeType 即调用 setDataAndType ,系统才能匹配到这个 Activity(即便你 mimeType 设置为
"*/*" 也是如此)。当然,如果你没有设置 mimeType,那么调用 setData 进行匹配,如果你设置了任何的 mimeType
将不会匹配到该 Activity。
4、一些例子
例子1:如果我们想要匹配 http 以 “.pdf” 结尾的路径,使得别的程序想要打开网络 pdf 时,用户能够可以选择我们的程序进行下载查看。
我们可以将 scheme 设置为 “http”,pathPattern 设置为 “.*\\.pdf”,整个 intent-filter 设置为:
1 <intent-filter>
2 <action android:name="android.intent.action.VIEW"></action>
3 <category android:name="android.intent.category.DEFAULT"></category>
4 <data android:scheme="http" android:pathPattern=".*\\.pdf"></data>
5 </intent-filter>
如果你只想处理某个站点的 pdf,那么在 data 标签里增加 android:host="yoursite.com" 则只会匹配 http://yoursite.com/xxx/xxx.pdf,但这不会匹配 www.yoursite.com,如果你也想匹配这个站点的话,你就需要再添加一个 data 标签,除了 android:host 改为 “www.yoursite.com” 其他都一样。
例子2:如果我们做的是一个IM应用,或是其他类似于微博之类的应用,如何让别人通过 Intent 进行调用分享出现在选择框里呢?
我们只用注册 android.intent.action.SEND 与 mimeType 为 “text/plain” 或 “*/*” 就可以了,整个 intent-filter 设置为:
1 <intent-filter>
2 <action android:name="android.intent.action.SEND" />
3 <category android:name="android.intent.category.DEFAULT" />
4 <data mimeType="*/*" />
5 </intent-filter>
这里设置 category 的原因是,创建的 Intent 的实例默认 category 就包含了 Intent.CATEGORY_DEFAULT ,google 这样做的原因是为了让这个 Intent 始终有一个 category。
例子3:如果我们做的是一个音乐播放软件,当文件浏览器打开某音乐文件的时候,使我们的应用能够出现在选择框里?
这类似于文件关联了,其实做起来跟上面一样,也很简单,我们只用注册 android.intent.action.VIEW 与 mimeType 为 “audio/*” 就可以了,整个 intent-filter 设置为:
1 <intent-filter>
2 <action android:name="android.intent.action.VIEW" />
3 <category android:name="android.intent.category.DEFAULT" />
4 <data android:mimeType="audio/*" />
5 </intent-filter>