Android 官网: https://developer.android.com/training/basics/intents/sending#java
目录
一.概述
Android 最重要的功能之一是应用能够基于它要执行的“操作”将用户转到其他应用。
例如,如果您的应用包含您想要在地图上显示的商家地址,您无需在应用中构建用于显示地图的 Activity,而是可以创建使用 Intent
查看地址的请求。
然后,Android 系统即会启动能够在地图上显示地址的应用。
对特定操作创建隐式 Intent,使用该 Intent 启动在另一个应用中执行操作的 Activity。
二. 构建隐式 Intent
隐式 Intent 不会声明要启动的组件的类名称,而是声明要执行的操作。该操作指定您要执行的操作,例如查看、编辑、发送或获取某项内容。
下面把每个操作封装成一个方法(方便自己测试,例如响应一个Button 的onClick 操作)。
//startActivity(callIntent); ---> 该行后面的代码是使用Intent 启动Activity 部分,为了方便,自定义一个start 方法处理。在后面有介绍
1. 发起通话
public void dial(View view) {
Uri number= Uri.parse("tel:12345");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
//startActivity(callIntent);
start(callIntent);
}
2. 查看地图
public void viewMap(View view) {
Uri location=Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
//startActivity(mapIntent);
start(mapIntent);
}
3. 查看网页
public void viewWeb(View view) {
Uri webPage = Uri.parse("https://www.baidu.com/");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webPage);
//startActivity(webIntent);
start(webIntent);
}
4. 发送带有附件的电子邮件
public void sendEmail(View view) {
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.setType("text/plain" );
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jan@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
//startActivity(emailIntent);
start(emailIntent);
}
5. 创建日历活动
public void createCalendar(View view) {
// Event is on January 23, 2021 -- from 7:30 AM to 10:30 AM.
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, CalendarContract.Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance();
beginTime.set(2021, 0, 23, 7, 30);
Calendar endTime = Calendar.getInstance();
endTime.set(2021, 0, 23, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.Events.TITLE, "Ninja class");
calendarIntent.putExtra(CalendarContract.Events.EVENT_LOCATION, "Secret dojo");
//startActivity(calendarIntent);
start(calendarIntent);
}
三. 验证是否存在可接收 Intent 的应用
尽管 Android 平台保证某些 Intent 会解析到内置应用(例如“电话”、“电子邮件”或“日历”应用)之一,但应始终在调用 Intent 之前执行验证步骤。
注意:如果您调用了一个 Intent,但设备上没有可以处理该 Intent 的应用,您的应用将会崩溃。
如需验证是否存在可以响应相应 Intent 的 Activity,请调用 queryIntentActivities()
以获取能够处理您的 Intent
的 Activity 列表。如果返回的 List
不为空,则您可以安全地使用该 Intent。例如:
例如验证上面的mapIntent
// Verify it resolves
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;
四. 使用 Intent 启动 Activity
注意,如果没有验证,可能会有找不到Activity的情况。
private void start(Intent intent){
try {
// Try to invoke the intent.
startActivity(intent);
}catch (ActivityNotFoundException e) {
// Define what your app should do if no activity can handle the intent.
e.printStackTrace();
Toast.makeText(this, "ActivityNotFoundException", Toast.LENGTH_SHORT).show();
}
}
五.显示应用选择器(chooser)
当通过将 Intent
传递给 startActivity()
启动一个 Activity,并且有多个应用可以响应该 Intent 时,用户可以选择默认使用哪个应用.
public void share(View view) {
Intent intent = new Intent(Intent.ACTION_SEND);
//需要指定type: EXTRA_TEXT or EXTRA_STREAM
//https://developer.android.com/reference/android/content/Intent#ACTION_SEND
intent.setType("text/plain");
// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = "Share this xxx with";
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);
// Try to invoke the intent.
// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
//startActivity(chooser);
start(chooser);
}
}
主要,需要对intent 设置它的类型 (setType) , 系统才能不同的分享方式供用户选择
六、显式Intent
例如启动一个新的Activity ,创建Intent 实例的时候,设置它的包名和类名:
intent.setClassName("com.example.widgettest", "com.example.widgettest.InputActivity") // 调用以下的函数
public @NonNull Intent setClassName(@NonNull String packageName, @NonNull String className) {
或者简单一点
intent.setClassName(this, InputActivity::class.java.name) // 调用以下的函数
public @NonNull Intent setClassName(@NonNull Context packageContext, @NonNull String className)