典型隐式Intent的组成
下面是一个隐式Intent的主要组成部分,可以用来定义我们的工作任务。
(1)要执行的操作。
通常以Intent类中的常量来表示。例如,要访问查看某个URL,可以使用 Intent.ACTION_VIEW;要发送邮件,可以使用Intent.ACTION_SNED。
(2)要访问数据的位置
这可能是设备以外的资源,如某个网页的URL,也可能是指向某个文件的URI,或者是指向ContentProvider中某条记录的某个内容URI(content URI)。
(3)操作涉及的数据类型
这是指MIME形式的数据类型,如text/html或audio/mpeg3.如果一个intent包含某类数据的位置,那么通常可以从中推测出数据的类型。
(4)可选类别。
如果操作用于描述具体要做什么,那么类别通常用来描述我们是何时、何地或者说如何使用某个activity的。Android的android.intent.category.LAUNCHER类别表明,activity应该显示在顶级应用启动器中。而android.intent.category.INFO类别表明,虽然activity向用户显示了包信息,但它不应该显示在启动器中。
通过配置文件中的intent过滤器设置,activity会对外宣称自己是合适处理ACTION_VIEW的activity。如果开发一款浏览器应用,为响应ACTION_VIEW操作,需要在activity声明中包含以下intent过滤器:
<activity
android:name=".BrowserActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" android:host="www.baidu.com">
</intent-filter>
</activity>
DEFAULTl类别必须明确地在intent过滤器中进行设置。intent过滤器中的action元素告诉操作系统,activity能够处理指定的任务,DEFAULTl类别告诉操作系统,activity愿意处理某项任务。DEFAULTl类别实际隐含添加到了几乎每一个隐式intent中(唯一的例外是LAUNCHER类别)。
获取隐式Intent发送的信息
/**
* 使用带有占位符(可在运行时替换)的格式化字符串创建可填充的陋习报告模板。 如:%1$s!The crime was discovered on
* %2$s. %3$s, and %4$s
* %1$、%2$s等特殊字符串即为占位符,它们接受字符串参数。在代码中。我们将调用getString(...)方法,并传入格式化字符串资源ID以及
* 四个其他字符串参数(与要替换的占位符顺序一致)。
*/
private String getCrimeReport() {
String solvedString = null;
if (mCrime.isSolved()) {
solvedString = getString(R.string.crime_report_solved);
} else {
solvedString = getString(R.string.crime_report_unsolved);
}
String dateFormat = "EEE, MMM dd";
String dateString = DateFormat.format(dateFormat, mCrime.getDate())
.toString();
String suspect = mCrime.getSuspect();
if (suspect == null) {
suspect = getString(R.string.crime_report_no_suspect);
} else {
suspect = getString(R.string.crime_report_suspect, suspect);
}
String report = getString(R.string.crime_report, mCrime.getTitle(),
dateString, solvedString, suspect);
return report;
}
发送隐式Intent
// 设置要执行的操作。例如,要访问查看某个URL,可以使用Intent.ACTION_VIEW;要发送邮件,可以使用Intent.ACTION_SEND
Intent intent = new Intent(Intent.ACTION_SEND);
// 操作涉及的数据类型
intent.setType("text/plain");
// 添加文本信息
intent.putExtra(Intent.EXTRA_TEXT, getCrimeReport());
// 添加主题信息
intent.putExtra(Intent.EXTRA_SUBJECT,
getString(R.string.crime_report_subject));
// 每次都显示响应隐式Intent的全部activity(即使设置默认应用不管用)
intent = Intent.createChooser(intent,
getString(R.string.send_report));
startActivity(intent);
获取联系人隐式Intent
// 设置要执行的操作以及要访问数据的位置
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, REQUEST_CONTACT);
if (requestCode == REQUEST_CONTACT) {
//联系人信息
Uri uri = data.getData();
String[] queryFields = new String[]{ContactsContract.Contacts.DISPLAY_NAME};
Cursor cursor = getActivity().getContentResolver().query(uri, queryFields, null, null, null);
if(cursor.getCount() == 0){
cursor.close();
return;
}
cursor.moveToFirst();
String suspect = cursor.getString(0);
mCrime.setSuspect(suspect);
mSuspectButton.setText(suspect);
cursor.close();
}
拨打电话隐式Intent
使用电话URI,创建一个隐式intent:
Uri number = Uri.parser("tel:5551234");
电话相关的intent操作通常有两种:Intent.ACTION_DIAL和Intent.ACTION_CALL。ACTION_CALL直接调出手机应用并立即拨打来自intent的电话号码;而ACTION_DIAL则拨好号码,然后等待用户发起通话。推荐使用ACTION_DIAL操作。
检查可以响应隐式Intent的activity
如果设备上没有任何与目标隐式Intent相匹配的activity,那么应用会立即崩溃。
解决办法是通过操作系统中的PackageManager类进行自检,检查匹配的activity的数量是否大于0.
PackageManager pm = getActivity().getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;