Android APP之間的交互




在很多情況下,一個應用程序包含了很多Activity,這多Activity之間的交互都是通過
intent進行交互的,如從這個界面跳轉到下一個界面,或者界面之間的數據交互

在不同的APP之間,Android也提供了很好的機制給我們用戶數據交互
同樣也是 intent,只是叫法不一樣了
以前Activity之間的交互是叫做 explicit Intent(明確的意圖)
現在不同的APP之間叫做 implicit intent(含蓄的意圖);

explicit Intent的用法:
    A調用B,在A中定義:
  Intent intent = new Intent(a_Activity.this,b_Activity.class );
   StartActivity(intent );

在APP之間交互:

一、使用URI(應用程序之間的定位符)來進行數據交互

如:
顯示網頁:
 
 Uri uri = Uri.parse("http://www.google.com");
 Intent it = new Intent(Intent.ACTION_VIEW,uri);
 startActivity(it);

顯示地圖:
Uri uri = Uri.parse("geo:38.899533,-77.036476");
Intent it = new Intent(Intent.Action_VIEW,uri);
startActivity(it);

二、添加額外的數據進行交互,你可以綁定你想要的任意類型的數據到extra data,使用的各種 putExtra()方法
如下所示,你可以使用URI,綁定額外的數據,如果不適用URI,必須使用 setType()指定你所綁定到Intent的數據是什麼類型的;

  • Send an email with an attachment:
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[] {"[email protected]"}); // 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

  • Create a calendar event:
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");

確定有一個APP接收你的intent
    如果你發了一個intent,設備上沒有任何一個APP可以接收,並回應你去處理Intent,那麼你的APP將會 Crash

爲了確認能夠知道,是否有APP響應你的Intent,Android提供了一個接口 queryIntentActivities()  ,調用這個接口即可返回一個list,如果這個list不爲空,就可以放心的去發送Intent了,如下例子說明:
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;

使用Intent啓動Activity
startActivity(intent);

下面有個例子說明,怎麼使用Intent去訪問 map,並且檢查了是否有APP存在去處理intent
// 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讓用戶選擇:
很多情況下,我們發送的Intent,可能不止一個APP響應,比如:你要分享一些照片在社交網站,可能手機上就有
很多社交的APP,新浪,QQ,微信等等,因此我們需要做一下處理,讓用戶自己選擇用哪個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);
}

另一種啓動另外的APP的方式

除了上面講到的 startActivity()方法之外,還有一個方法可以啓動另外的APP
並且能夠獲取APP給的返回結果,這種方法也是非常常見的

如,我們要調用相機去拍照,拍完照後,想要得到拍的照片;或者是調用聯繫人APP找某個聯繫人的聯繫方式,也需要返回結果的

這種方法就是 startActivityForResult()  ,使用startActivityForResult() 函數時,既可以使用 implicit Intent,又可以使用 explicit Intent
startActivityForResult()的用法和 StartActivity的用法基本差不多,
    但是startActivityForResult()的使用需要傳遞一個 整型參數 request code 表明你想要獲取什麼樣的結果
我們的Activity通過一個回調函數 onActivityResult() 獲取返回的結果

下面一個例子是,如何去調用聯繫人APP選擇一個聯繫人,並獲取返回的結果:
static final int PICK_CONTACT_REQUEST = 1;  // The request code
...
private void pickContact() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
    pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}


獲取返回結果:
    當用戶操作完成之後,系統會自動調用我們Activity的 onActivityResult();
因此我們需要重寫這個函數:
    這個方法會返回三個參數:
    @1: request code,即傳給APP的code
    @2:獲取的結果是否成功,RESULT_OK表明獲取成功,RESULT_CANCELED 表明獲取失敗
    @3:返回的結果數據,由intent攜帶

因此爲了能夠正確的去得到我們想要的結果,需要對這個intent包含的數據格式很瞭解,才能將數據解析出來
比如:聯繫人APP,返回的就是Content URI表明選擇的聯繫人,而Camera返回的就是一個bitmap格式的數據,
以下的代碼說明了怎麼獲取聯繫認的電話號碼,並不做深入的瞭解,因爲要想深入瞭解需要去了解 content providers
</pre><pre name="code" class="html">@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...
        }
    }
}


這裏需要注意的是query()查詢的方法,最好另起一個線程去完成,不要在UI線程裏做這個操作,因爲他很有可能會阻塞UI線程


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章