在Android中,Intent主要用于激活系统组件,以及在组件之间传递数据。Intent与系统组件有着密切关系,但不是系统组件。由开发人员创建和维护。Intent可以实现调用Android系统内置的功能如拨打电话。Intent可以理解为组件之间的“连接器”。可以用于激活Activity,Service,Broadcastreceiver但不用于激活Content Provider.
Intent的属性
Component Name
表示组件名称,使用Intent激活系统组件时,通过设置该属性的值来确定被激活的组件。可以通过以下方式设置该属性的值。
- Intent intent=new Intent(getApplicationContext(),XXXActivity.class);
- Intent intent=new Intent();
intent.setClass(getApplicationContext(),XXXActivity.class);
Action
Action表示动作,通常用于隐式激活组件。即不指定组件的名称,这样的Intent称为隐式意图。该属性的数据类型为String.Android系统在Intent类中定义了一系列以ACTION_为前缀的常量。例如ACTION_DIAL可用于激活系统的拨号程序。通过setAction()可以设置Action属性的值。
Data
Data表示数据,通常与Action属性配合使用。用于指定某个动作所需要的,或者被操作的数据。该属性的数据类型为Uri,可以通过Uri.parse()方法将字符串转换得到。可以通过setData(Uri.parse(“XXX”))设置该属性的值。(不要使用Data封装与Action属性无关的值)Data属性的常用值如下:
tel://:号码数据格式,后跟电话号码。
mailto://:邮件数据格式,后跟邮件收件人地址。
smsto://:短息数据格式,后跟短信接收号码。
content://:内容数据格式,后跟需要读取的内容。
file://:文件数据格式,后跟文件路径。
Catagory
Catagory表示分类,用于表示组件的类别。在一个Intent中可以有多个Catagory.该属性的数据类型为String。涉及到Catagory时,通常应用于隐式意图。且存在Intent Filter(意图过滤器)。Intent与Intent Filter匹配时才可以隐式激活组件。Android系统中定义了一些以Catagory为前缀的常量分别是:
- CATAGORY_DEFAULT:默认的
- CATAGORY_LAUNCHER:入口Activity的分类
- CATAGORY_BROWSABLE:可以被浏览器触发的分类
- CATAGORY_HOME:显示HOME界面的分类
Extra
extra表示额外的,用于封装在组件间传递的数据。它的数据类型是Bundle类型,Bundle实质上是个key为String的HashMap。可以通过putExtras方法将类型为Bundle的数据赋值给该属性。Intent类重载了多次putExtra方法,用于附加不同类型的数据。还提供了对应的get方法用于对不同数据类型的获取。如getStringExtra,getIntExtra等。对于get方法,都有第二个参数作为当根据name属性获取不到值时的返回值。如getIntExtra(“id”,-1)。使用Extra传递数据的用法示例:
数据绑定方 Intent intent=new Intent();
intent.putExtra("id",666);
数据接收方 Intent intent=getIntent();
intent.getIntExtra("id",-1);
Flag
Flag表示标志,通常用于指定Intent对象的一些特殊意义。例如在Activity的Back Stack的处理中,通过设置Flag属性确定Activity归属于某个Task。或者在广播中,设置是否仅动态注册的接收者才可以接收等。该属性的数据类型为Integer,通过setFlags()来设置。
IntentFilter
IntentFilter表示“Intent过滤器”,在隐式激活组件时,必须为被激活的组件配置IntentFilter,当激活组件时,如果Intent与对应的IntentFilter存在匹配关系,则可以成功的激活该组件。IntentFilter主要对Intent的Action、Category、Data属性进行过滤。如果匹配则放行,否则将阻止。大致匹配规则如下:
关于Action:Intent对象的Action在IntentFilter可以找到。
关于Catagory:Intent对象的所有Catagory在IntentFilter中都可以被找到。(IntentFilter需要配置Catagory.DEFAULTE这个节点。因为Intent对象默认有Catagory.DEFAULTE这个Catagory)
接下来我们用隐式意图激活系统的拨号,呼叫程序。首先介绍下Android中的权限(Permission)
Permission
在Android系统中,敏感操作(涉及到隐私的,安全的,可能产生费用的)都需要申请权限。且当应用程序被安装到设备上之前,会列举当前应用程序所申请的权限。用户可以选择继续安装或不安装。所有权限通过在AndroidManifest.xml中添加
<uses-permission android:name="权限名称"/>
来申请,该节点是根节点的直接子节点,可以添加多个。通话的权限为:
<uses-permission android:name="android.permission.CALL_PHONE"/>
下面是该程序运行效果:
代码如下:
Activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
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"
tools:context="com.wanghongxiang.intentdialandcall.MainActivity">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="phone"
android:ems="10"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="38dp"
android:id="@+id/etCallNum"
android:hint="请输入电话号码" />
<Button
android:text="拨号"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/etCallNum"
android:layout_alignStart="@+id/etCallNum"
android:layout_marginTop="17dp"
android:id="@+id/btnDial" />
<Button
android:text="呼叫"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/btnDial"
android:layout_toEndOf="@+id/btnDial"
android:layout_marginStart="12dp"
android:id="@+id/btnCall" />
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private EditText etCallNum;
private Button btDial,btCall;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etCallNum= (EditText) findViewById(R.id.etCallNum);
btDial= (Button) findViewById(R.id.btnDial);
btDial.setOnClickListener(new myListener());
btCall= (Button) findViewById(R.id.btnCall);
btCall.setOnClickListener(new myListener());
}
//自定义监听器,实现对按钮单击事件的监听
private class myListener implements View.OnClickListener{
@Override
public void onClick(View view) {
Intent intent=new Intent();
String callNum=etCallNum.getText().toString();
//Data电话号码的格式为tel://10086
intent.setData(Uri.parse("tel://"+callNum));
switch (view.getId()){
//拨号
case R.id.btnDial:
intent.setAction(Intent.ACTION_DIAL);
break;
//呼叫
case R.id.btnCall:
intent.setAction(Intent.ACTION_CALL);
break;
}
startActivity(intent);
}
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wanghongxiang.intentdialandcall">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!--授予通话权限-->
<uses-permission android:name="android.permission.CALL_PHONE"> </uses-permission>
</manifest>