本讲介绍了Android应用程序中最为重要Intent和四大组件之一
文章目录第八讲Intent和BroadcastReceiverIntentIntent对象构成Component nameActionDataCategoryExtrasFlagsURI和intent-filter匹配:一个打电话和发短信示例1. 布局文件2. java文件3. 添加权限BroadcastReceiver标准广播有序广播发布广播-自定义标准广播示例:接收广播-接受广播示例:实现短消息提示示例题目记录 IntentIntent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcast。
组件名称 | 方法名称 |
---|---|
Activity | startActivity() startActivityForResult() |
Service | startService() bindService() |
Broadcasts | sendBroadcast() sendOrderedBroadcast()sendStickyBroadcast() |
1.启动Activity:
向Context.startActivity() 或[Activity.startActivityForResult()](http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int))方法传递一个Intent对象,可以启动一个activity,或使得一个已经存在的activity去做一些新的事情。
(也可以向 [Activity.setResult()](http://developer.android.com/reference/android/app/Activity.html#setResult(int, android.content.Intent)) 去传递这个Intent对象,返回调用了
startActivityForResult()
的activity的一些信息。)
2.启动Service:
向 Context.startService() 方法传递Intent对象可以初始化一个service或者向一个已经存在的service传递新的指令。
类似的,向[Context.bindService()](http://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)) 方法传递Intent对象可以在调用所在的组件和目标service之间建立一种连接。如果这个service并没有开始运行,则它可以初始化这个service。
3.发起广播Broadcast
可以向下面的广播方法传递Intent对象来发起广播:
Context.sendBroadcast(),[Context.sendOrderedBroadcast()](http://developer.android.com/reference/android/content/Context.html#sendOrderedBroadcast(android.content.Intent, java.lang.String)), 或 Context.sendStickyBroadcast()。系统会找到相应的广播接收者对此进行响应。
Intent在寻找目标组件时有两种方法:
第一种,显式调用,通过Component name直接指定;
第二种,隐式调用,没有明确指定目标组件的名称,那么就要通过一定的条件过滤筛选。
启动activity、service和broadcast的消息系统是没有任何重合的,即,一个要启动activity的Intent对象是绝对不会启动一个service的。
Intent对象构成Intent对象由以下六个部分组成:
Component name
Action
Data
Category
Extras
Flags
Component name即组件名称,是要处理这个Intent对象的组件名称。
组件名称对象由ComponentName类来封装,组件名称包含包名称和类名称,被声明在AndroidManifest.xml文件中。
组件名称通过 setComponent(),[setClass()](http://developer.android.com/reference/android/content/Intent.html#setClass(android.content.Context, java.lang.Class)),[setClassName()](http://developer.android.com/reference/android/content/Intent.html#setClassName(java.lang.String, java.lang.String))设置,通过getComponent()获取。
需要注意的是Component name是一个可选项,如果被设置,那么Intent对象就显式指定了要转向的组件,如果没有被设置,则Intent对象需要根据其他信息进行筛选查找。
ActionAction是指Intent要完成的动作,是一个字符串常量。
在Intent类里面定义了很多Action常量,其中有:
ACTION_MAIN: | Android Application的入口,每个Android应用必须且只能包含一个此类型的Action声明。 |
---|---|
ACTION_VIEW: | 系统根据不同的Data类型,通过已注册的对应Application显示数据。 |
ACTION_EDIT: | 系统根据不同的Data类型,通过已注册的对应Application编辑示数据。 |
ACTION_DIAL: | 打开系统默认的拨号程序,如果Data中设置了电话号码,则自动在拨号程序中输入此号码 |
ACTION_CALL: | 直接呼叫Data中所带的号码 |
ACTION_ANSWER: | 接听来电 |
ACTION_SEND: | 由用户指定发送方式进行数据发送操作 |
ACTION_SENDTO: | 系统根据不同的Data类型,通过已注册的对应Application进行数据发送操作 |
ACTION_BOOT_COMPLETED: | Android系统在启动完毕后发出带有此Action的广播(Broadcast) |
ACTION_TIME_CHANGED: | Android系统的时间发生改变后发出带有此Action的广播(Broadcast) |
ACTION_PACKAGE_ADDED: | Android系统安装了新的Application之后发出带有此Action的广播(Broadcast) |
ACTION_PACKAGE_CHANGED: | Android系统中已存在的Application发生改变之后(如应用更新操作)发出带有此Action的广播(Broadcast) |
ACTION_PACKAGE_REMOVED: | 卸载了Android系统已存在的Application之后发出带有此Action的广播(Broadcast)。 |
Intent类中有很多预定义的常量,为了一些通常的动作;还有一些定义在Android API的其他地方。
也可以自己定义Action常量,自定义的常量需要加上你的应用的包名作为前缀。
Action在很大程度上决定了Intent的其他部分是如何构造的,尤其是 data 和 extras域。(就好像函数名会决定着参数值和返回值一样。)所以Action的名字应该尽可能具体,并且它们应该和Intent中的其他域紧密结合。
使用 setAction() 和 getAction()来设置和读取Action属性。
DataData属性是执行动作的URI和MIME类型,不同的动作有不同的数据规格。
比如,Action是ACTION_EDIT时,数据域将是文档的URI;Action是ACTION_CALL时,数据域是 tel: URI ,带有要拨打的电话号码;如果Action是 ACTION_VIEW,则数据域是http: URI。
当匹配intent和能够处理intent所带的数据的组件时,知道数据类型(MIME类型)是很重要的。比如,一个展示图像的组件不应该被叫去播放一个音频。
很多情况下,从URI可以看出数据类型,比如content: URIs,表示数据是在设备上,但是是由content provider控制。
数据类型也可以显式指定,比如setData()方法指定数据为URI,setType() 指定为MIME type,[setDataAndType()](http://developer.android.com/reference/android/content/Intent.html#setDataAndType(android.net.Uri, java.lang.String)) 指定它既为URI又为MIME type。读取的时候URI用getData(),MIME type用getType()。
在intent-filter中指定data属性的实际目的是:要求接收的Intent中的data必须符合intent-filter中指定的data属性,这样达到反向限定Intent的作用。
tel://: | 号码数据格式,后跟电话号码。 |
---|---|
mailto://: | 邮件数据格式,后跟邮件收件人地址 |
smsto://: | 短息数据格式,后跟短信接收号码 |
content://: | 内容数据格式,后跟需要读取的内容。 |
file://: | 文件数据格式,后跟文件路径 |
market://search?q=pname:pkgname: | 市场数据格式,在Google Market里搜索包名为pkgname的应用 |
geo://latitude,longitude: | 经纬数据格式,在地图上显示经纬度指定的位置。 |
Category是一个字符串,提供了额外的信息,有关于能够处理这个Intent对象的组件种类。
Category属性用于指定当前动作(Action)被执行的环境。通过addCategory()方法或在清单文件AndroidManifest.xml中设置。默认为:CATEGORY_DEFAULT
一个Intent对象中可以包含任意数量的category描述信息。
Intent类中也定义了一些Category常量:
Constant | Meaning |
---|---|
*CATEGORY_DEFAULT: | Android系统中默认的执行方式,按照普通Activity的执行方式执行。 |
CATEGORY_HOME: | 设置该组件为Home Activity*。* |
CATEGORY_PREFERENCE: | 设置该组件为Preference*。* |
CATEGORY_LAUNCHER: | 设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。 |
CATEGORY_BROWSABLE: | 设置该组件可以使用浏览器启动 |
CATEGORY_GADGET: | 设置该组件可以内嵌到另外的Activity中 |
与category相应的方法有添加addCategory()、移除removeCategory() 和获取所有category getCategories() 。
Extras传递给Intent的额外数据,以Bundle的形式定义,就是一些键值对。就好像一些动作和特定的数据URI对应,一些动作和特定的extras对应。
比如ACTION_TIMEZONE_CHANGED intent对象有一个 "
time-zone
"的extra来确认新的时区;
ACTION_HEADSET_PLUG
有一个"state
" extra表示耳机是否插入,还有一个 “name
” extra关于耳机类型;
如果你要设计一个SHOW_COLOR动作,那么extra中应该包含颜色值。
Intent对象有一系列的putXXX()函数用于放入各种数据类型,相应的也有一系列的getXXX()函数用于读取数据。
实际上,数据可以被作为一个Bundle对象被使用,利用 putExtras() 和 getExtras() 方法。
EXTRA_BCC: | 存放邮件密送人地址的字符串数组。 |
---|---|
EXTRA_CC: | 存放邮件抄送人地址的字符串数组 |
EXTRA_EMAIL: | 存放邮件地址的字符串数组 |
EXTRA_SUBJECT: | 存放邮件主题字符串 |
EXTRA_TEXT: | 存放邮件内容 |
EXTRA_KEY_EVENT: | 以KeyEvent对象方式存放触发Intent的按键 |
EXTRA_PHONE_NUMBER: | 存放调用ACTION_CALL时的电话号码 |
各种类型的Flag。很多是用来指定Android系统如何启动activity,还有启动了activity后如何对待它。所有这些都定义在Intent类中。
参考链接:https://www.cnblogs.com/mengdd/archive/2013/03/18/2965839.html
URI和intent-filter匹配:Intent中URI和intent-filter进行比较的时候只会进行部分的比较:
(1)当intent-filter中只设置了scheme,只会比较URI的scheme部分;
(2)当intent-filter中只设置了scheme和authority,那么只会匹配URI中的scheme和authority;
(3)当intent-filter中设置了scheme、authority和path,那么只会匹配URI中的scheme、authority、path;(path可以使用通配符进行匹配)
(4)当intent-filter中设置了mimeType,还会进行数据类型的匹配。
一个打电话和发短信示例 1. 布局文件
2. java文件
package com.example.bean.myapplicationv0;
import android.Manifest;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS},1);
//申请权限
}
public void myClick(View view){
EditText et1 = (EditText)findViewById(R.id.et1);
EditText et2 = (EditText)findViewById(R.id.et2);
Button btn = (Button)view;
Intent intent = new Intent();//新建对象
switch (btn.getId()){
case R.id.bt1:
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+ et1.getText().toString()));
break;
case R.id.bt2:
intent.setAction(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("smsto:"+ et1.getText().toString()));
intent.putExtra("sms_body",et2.getText().toString());
break;
}
startActivity(intent);//启动Intent
}
}
3. 添加权限
在mainfest.xml中<application前面添加
BroadcastReceiver
Android四大组件之一,用于不同组件和多线程之间的通信。
标准广播标准广播(Normal broadcasts):是一种完全异步执行的广播,在广播发出后,所有的广播接收器几乎都会在同一时间接收到这条广播,没有先后顺序。
有序广播有序广播(Ordered broadcasts):是一种同步执行的广播,在广播发出后,同一时刻只有一个广播接收器能接收到广播。有先后顺序。
发布广播-自定义标准广播示例:public void myClick(View view){
Intent intent = new Intent();
intent.setAction("myBroadcast");
intent.setPackage("com.example.bean.myapplication00");
intent.putExtra("myMsg","Hello");
sendBroadcast(intent);
}
接收广播-接受广播示例:
myReceiver类
public class myReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,intent.getStringExtra("myMsg"),Toast.LENGTH_SHORT).show();
}
}
在mainfest.xml中下面
实现短消息提示示例
步骤:
创建BroadcastReceiver类的子类。
实现onReceive()方法。
配置AndroidManifest.xmI中的receiver。
action为: “android.provider.Telephony.SMS_RECEIVED”
配置AndroidManifest.xml的短信接收许可:“android.permission.RECEIVE_SMS”
配置判断主活动中是否授权了短信的接收许可,并申请短信接收许可。
New - Other - Broadcast Recerive新建MyReceiver
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
//throw new UnsupportedOperationException("Not yet implemented");
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))
Toast.makeText(context,"有短信到了!",Toast.LENGTH_SHORT).show();
}
}
权限
main.java判断是否有权限
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECEIVE_SMS)!= PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.RECEIVE_SMS},1);
}
}
题目记录
Intent的ComponentName属性主要是 C
A.指明某一个包下的,要启动的组件
B.指明要启动的组件对应的类
C.用包名和类名唯一确定一个要启动的组件
D.指明要启动的组件0.00
对于Intent的说法下列哪些是不对的 C 老师说改B
A.是一个被动的数据结构 0000
B.Android的四大组件都是通过Intent来激活的0.00
C.intent保存了一个将要执行操作的抽象描述
D.Intent是一个对象
下列哪个不是Intent常用的传输机制 D
A.将一个Intent对象传递给任何广播方法,都可以传递到所有感兴趣的广播接收者0.00
B.将一个Intent对象传递给Context.startActivity()启动一个活动
C.将一个Intent对象传递给Context.startService()传递一个新指令给正在运行的Service
D.将一个携带数据的Intent对象ContentProvider以提供开放的数据
对于Intent的Data属性下列说法不正确的是 D
A.可以向Activity传递一些额外键值对信息0.00
B.Data是作用于Intent上的数据的URI和MIME类型 0000
C.不同的动作有不同的数据规格
D.可以使用setData()方法设置URI数据
Intetn的Data属性的数据类型可以是 D
A.整型
B.字符型
C.实型
D.MIME
Intent的Category属性是指 D
A.Intent的分类0.00
B.Intent的Action属性分类
C.Intent的Data属性的分类
D.作为被执行动作的附加信息
Intent的Extras属性 D
A.只是作为留用一般不使用
B.主要用于ContentProvider向外部提供信息
C.只能使用Bundle传递额外的键值对信息
D.可以传递额外的键值对信息
显示Intent是指 D
A.使用new关键字声明的Intent
B.在StartActivity中使用的Intent
C.使用getIntent()方法获得的Intent
D.通过名称指定目标组件的Intent
隐式Intent是指 B
A.不指定Extra的Intent
B.不指定目标名称的Intent1.00/1.00
C.不指定Action属性的Intent
D.不指定Category的Intent
Intent过滤器不检测的属性是 C
A.Data
B.Action
C.Extra1.00/1.00
D.Category
Intent的Action属性 A
A.很大程度上决定了Intent如何构建1.00/1.00
B.与Intent其他属性互不影响
C.必须和Component属性一同使用
D.常用于组件的显式启动
Intent有两种形式其中一种是 A E
A.显式Intent1.00/1.00
B.明确式Intent
C.直接Intent
D.声明式Intent
E.隐式Intent
对于Intent过滤器,下列说法正确的是: B
A.在Activity的onCreate()方法中配置过滤器
B.过虑器的标签是1.00/1.00
C.只能为某组件设置一个过滤器
D.过滤器只适用于隐式Intent
下列哪个不是Intent的功能? D
A.用于启动组件
B.封装了程序的启动意图
C.交换数据
D.只用于启动Activity
ComponentName属性 A
A.使用setClass方法设置1.00/1.00
B.可以通过setComponentName()方法设置
C.使用setComponentClass()方法设置
D.使用Component的构造方法设置
作者:江山点墨