Develop--Training(三)Getting Started--Interacting with Other Apps

序:从这一篇开始,翻译的是Android 6.0官网上的原文。

一个Android应用程序,通常有几个Activites。每个Activity显示一个用户界面,允许用户执行特定的操作(比如地图上的一个界面或者拍照)。为了让用户能从一个界面到另一个界面,应用程序必须要使用一个意图,通过定义一个“intent”来做一些事情。当你在系统中通过方法使用一个Intent,比如startActivity(),系统通过使用intent识别并启动适当的应用程序组件。使用意图甚至能够打开一个Activity,被包含在一个单独的应用程序中。
一个intent能够明确打开哪一个具体的组件(一个具体Activity的实例),或者隐式的打开任何一个组件,能够处理预期的动作(比如截图)。
这节课教你怎样使用intent和其他应用程序执行一些基本的交互,比如打开另一个应用程序,接受应用程序的返回结果,让你的应用程序有能力发送意图给其他的应用程序。

Sending the User to Another App

创建一个隐式的意图,通过执行一些动作,来运行其他的应用程序。
Build an Implicit Intent(构建一个隐式意图)
打电话的intent:

Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

查看地图的intent:

// Map point based on address
Uri location = Uri.parse("geo:0,0q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
// Or map point based on latitude/longitude
// z param is zoom level
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); 
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

查看网页的intent:

Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

发送带附件的电子邮件的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

创建日历事件的intent:

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");

注意: 只有 API 级别 14 或更高级别支持此日历事件意向。

1.Verify There is an App to Receive the Intent(确认是否存在接收意向的应用)

bug: 如果调用了intent,但设备上没有可用于处理intent的应用,应用将崩溃。
要确认是否存在可响应intent的可用Activity,请调用 queryIntentActivities() 来获取能够处理Intent 的Activity列表。 如果返回的 List 不为空,您可以安全地使用该intent。方法如下:

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

如果 isIntentSafe 是 true,则至少有一个应用将响应该intent。 如果它是 false,则没有任何应用处理该intent。

2.Start an Activity with the Intent(开始具有意向的Activity)

启动intent完整的code:

// 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);
}

3.Show an App Chooser(显示应用选择器)
这里写图片描述

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);
}
Getting a Result from an Activity(获取Activity的结果)

打开另一个Activity,接受一个Activity的返回值

1..Start the Activity(打开一个Activity)

显示用户选择联系人的Activity:

static final int PICK_CONTACT_REQUEST = 1;  // The request code
...
private void pickContact() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, new Uri("content://contacts"));
    pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

2.Receive the Result(接受返回结果)

获取联系人列表:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request it is that we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // Get the URI that points to the selected contact
            Uri contactUri = data.getData();
            // We only need the NUMBER column, because there will be only one row in the result
            String[] projection = {Phone.NUMBER};

            // Perform the query on the contact to get the NUMBER column
            // We don't need a selection or sort order (there's only one result for the given URI)
            // CAUTION: The query() method should be called from a separate thread to avoid blocking
            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
            // Consider using CursorLoader to perform the query.
            Cursor cursor = getContentResolver()
                    .query(contactUri, projection, null, null, null);
            cursor.moveToFirst();

            // Retrieve the phone number from the NUMBER column
            int column = cursor.getColumnIndex(Phone.NUMBER);
            String number = cursor.getString(column);

            // Do something with the phone number...
        }
    }
}
Allowing Other Apps to Start Your Activity(允许其他应用开始您的Activity)

1.Add an Intent Filter(添加一个意图过滤器)

  • Action
    对要执行的操作命名的字符串。通常是平台定义的值之一,比如 ACTION_SEND 或 ACTION_VIEW。
  • Data
    与意向关联的数据描述。用 元素在您的意向过滤器中指定此内容。使用此元素中的一个或多个属性,您可以只指定 MIME 类型、URI 前缀、URI 架构或这些的组合以及其他指示所接受数据类型的项。
  • Category
    提供另外一种表征处理意向的Activity的方法,通常与用户手势或Activity开始的位置有关。 系统支持多种不同的类别,但大多数都很少使用。 但是,所有隐含意向默认使用 CATEGORY_DEFAULT 进行定义。用 元素在您的意向过滤器中指定此内容。
    比如,有一个在数据类型为文本或图像时处理 ACTION_SEND 意向的意向过滤器:
<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

每个intent仅指定一项操作和一个数据类型,但可以在每个 中声明 、 和 元素的多个实例。
比如,这个Activity就可以同时处理 ACTION_SEND 和 ACTION_SENDTO 意向的文本和图像。

<activity android:name="ShareActivity">
    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

注意:为了接收隐含意向,您必须在意向过滤器中包含 CATEGORY_DEFAULT 类别。startActivity() 和 startActivityForResult() 就声明 CATEGORY_DEFAULT 类别那样处理所有意向。 如果您不在意向过滤器中声明它,则没有隐含意向来处理Activity。

2.Handle the Intent in Your Activity(处理您的Activity中的意图)

当Activity开启时,调用 getIntent() 检索开始Activity的 Intent。 可以在onCreate() 或 onStart()中执行。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();

    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data ...
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text ...
    }
}

3.Return a Result(返回结果)

// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
setResult(Activity.RESULT_OK, result);
finish();

注意:结果默认设置为 RESULT_CANCELED。因此,如果用户在完成操作动作或设置结果之前按了返回按钮,之前的Activity会收到“已取消”的结果。

setResult(RESULT_COLOR_RED);
finish();

注意:无需检查Activity是使用 startActivity() 还是 startActivityForResult() 打开的。如果打开Activity的意向可能需要结果,只需调用 setResult()。 如果之前的Activity已调用 startActivityForResult(),则系统将向其传递你所提供给 setResult() 的结果;否则,会忽略结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值