Android隐式意图

2016-07-04 · 🙈Lei · 0条 · 416次

One of Android's most important features is an app's ability to send the user to another app based on an "action" it would like to perform. 比如自己的应用要在地图上显示某个位置,就不需要在自己的应用中开发地图模块,直接用用户手机中安装的地图应用进行显示。

>_ Build an Implicit Intent 创建隐式意图

隐式意图不需要声明组件要启动的类名,但是要声明操作(action to perform)。action表明了你要做的事情,例如view, edit, send or get something.意图通常也包含与操作(action)相关的数据(data)。

1.如果数据是Uri类型的,可以采用如下的方式构造Intent():

// Map point based on address
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");//查看地图
// Or map point based on latitude/longitude
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
Uri webpage = Uri.parse("http://www.android.com");//查看网页
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

当应用使用startActivity()发起该意图时,“电话”应用会呼叫指定的电话号码。

2.其他类型的隐式意图,可以使用putExtra()方法添加一条或者多条额外数据。

默认情况下,系统通过Uri数据决定合适的MIME类型。如果Intent不包含Uri,则使用setType()来区分与Intent相关联的数据。设置MIME类型可进一步指定哪些类型的Activity应该接收intent。Intent emailIntent = new Intent(Intent.ACTION_SEND);

//发送带附件的电子邮件
// The intent does not have a URI, so declare the "text/plain" MIME type

emailIntent
.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent
.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
emailIntent
.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
emailIntent
.putExtra(Intent.EXTRA_TEXT, "Email message text");
emailIntent
.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
// You can also attach multiple items by passing an ArrayList of Uris
//创建日历事件,只有API14或更高级别支持此日历事件意图。
Intent
calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
calendarIntent
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent
.putExtra(Events.TITLE, "Ninja class");
calendarIntent
.putExtra(Events.EVENT_LOCATION, "Secret dojo");

注:尽可能具体的定义Intent是很重要的,指定具体的Intent才能避免不希望的应用被Intent触发。

>_ 确定是否有接收意图的应用

注意:如果使用了意图,但是设备上没有用于处理该意图的软件,那么你自己的软件会崩溃的。

要确认是否存在可响应意图的可用Activity,可以调用queryIntentActivities()获取能够处理Intent的Activity列表。如果返回的List不为空,则可以安全使用该意图。

PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;

如果isIntentSafe是true,则有应用可以处理该意图,如果是false,则没有可以处理该意图的应用。

应该提前执行这个检查,如果没有应用可以处理,则禁止该功能,以防止用户使用。如果你直到某个特定的应用可以提供这个功能,那么你应该提供一个该应用的下载链接。

>_ Start an Activity with the Intent 使用意图打开一个Activity

如果系统有多个activity可以处理intent,就会以列表的形式显示出用户可以选择的APP。如果仅有一款软件可以处理,那么系统会自动启动它。

//展示地图
// Build the intent

Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

// Verify it resolves
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;

// Start an activity if it's safe
if (isIntentSafe) {
startActivity
(mapIntent);

>_ 显示APP选择器

很多操作用户习惯于每次都使用相同的应用(默认打开方式),像上图中的底下的选择框。

像“分享”这种操作可能用户在每次选择的时候不一样,就不可以使用默认方式启动,应该明确显示选择框,应用选择框不会提供给用户选择默认应用的选项。

创建选择器,使用createChooser()创建Intent并将其传递至startActivity()。

Intent intent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);

// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity
(chooser);
}


  0