2010年1月23日 星期六

替Pluroium加上plugin功能

之前一篇文章囉哩八梭的講了一堆Intent, 這次來看個實例

拿Pluroid的open source - Pluroium來當作實驗對象, 這次要實驗的是如何替它的compose畫面提昇一個簡單而彈性的功能, 先來看一下畫面:




為了怕被鍵盤擋住, 所以先稍微小一下Layout把表情符號給加了上去, 並且加了一個按鈕"Attach"

這Attach的作用是用來讓使用者選擇要插入的內容, 比如說他可以選擇一個圖片上傳後把圖片URL插入到內容內, 或是選擇一個位置把地址插入到裡面, 諸如此類的功能, 但這邊又不想把功能寫死, 而是要可以讓主程式不動, 隨著外掛plugin安裝可以讓它支援更多的內容

先來看看插入的Attch button的layout

<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Attach" android:onClick="handleAttachment"></Button>


在Button01定義的onClick是handleAttachement, 所以我們在ComposeActivity上加上

public void handleAttachment(View target) {
Intent intent = new Intent("org.pluroid.pluroium.COMPOSE_PLUGIN");
startActivityForResult(Intent.createChooser(intent, "Choose a plugin"), RESULT_COMPOSE_PLUGIN);
}

這段有幾個部份要解釋一下:
  • org.pluroid.pluroium.COMPOSE_PLUGIN 這是用來呼叫plugin的action
  • startActivityForResult 這跟startActivity的不同點是, 當它呼叫的Activity結束時, 它可以接收到它呼叫的Activity的結果
  • createChooser 這算是個utility method, 它幫你包裝了一些東西, 在這邊搭配startActivity使用的話, 如果有多個Activity支援COMPOSE_PLUGIN, 那麼當按下Attach後就會先跳出一個標題是"Choose a plugin"的視窗列出所有支援這intent的Activities讓User選擇(如果只有一個Activity, 就不會出現這視窗
  • RESULT_COMPOSE_PLUGIN 這是一個數字, request code, 當callee activity結束後, 要靠這個讓caller activity知道它剛剛是處理哪種


Activity還需要overwrite一個onActivityResult, 範例如下

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == RESULT_COMPOSE_PLUGIN && resultCode == RESULT_OK) {
String text = data.getStringExtra(Intent.EXTRA_TEXT);
plurkContent.append(" ");
plurkContent.append(text);
return;
}
super.onActivityResult(requestCode, resultCode, data);
}

這就是接收剛call那個activity回傳回來的結果

這時候你如果興沖沖的跑去測試這按鈕, 你一定會很失望, 因為一按下按鈕, 程式馬上爆炸...別急, 因為你這時候還沒找到任何支援這個intent action的activities, 當然會有問題啦!!

為了保險起見, 我們可以在initView裡加上一段保險, 如果裡面沒有任何Activities有支援這action就把attach button給disable

PackageManager pm = this.getPackageManager();
Intent intent = new Intent("org.pluroid.pluroium.COMPOSE_PLUGIN");
List ativities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

if(ativities.size() == 0) //No activity found for "org.pluroid.pluroium.COMPOSE_PLUGIN"
findViewById(R.id.Button01).setEnabled(false);


加上這個後, 看起來就保險多了, 接下來我們可以來設計plugin了:
這plugin基本上只要可以處理COMPOSE_PLUGIN就好, 因此Intent filter很簡單,

接下來我們先來做一個簡單的plugin activity, 讓使用者按下OK後就回傳"Hello Pluroium", 以下是Sample code:

public void doOK(View target) {
Intent data = new Intent();
data.putExtra(Intent.EXTRA_TEXT, "Hello Pluroium");
setResult(RESULT_OK, data);
finish();
}
public void doCancel(View target) {
setResult(RESULT_CANCELED);
finish();
}

(兩個button, 一個onClick設成doOK, 一個是doCancel)
利用"Activity.setResult", 我們就可以把user的選擇結果回傳給ComposeActivity了

----------------------------------
謎之音: 文句寫的真不通暢, 果然該睡了

----------------------------------