Twitter for Android popup a user list when you enter “@” in post screen. Like this:

T1

How it implement such feature? The solution can’t be simpler - You could use MultiAutoCompeleteTextView to do this.

Here is the sample codes:

And the result:

T2

To use this widget, you need to implement a Tokenizer to tell it where the sub text is. In this case, just find the string between ’@’ and space.

昨晚熬夜看了Google I/O的live(那是一定要的啦!), 雖然沒睡多少, 到現在依然興奮!

今年Day 1的Keynote搞到真的像是Android I/O一樣, Android儼然是今年必然主角一樣, 不過與我之前想像的不太一樣, 今年沒特別著重在平板, 也沒特別著重在TV和其他裝置, 而是Android本身, Android本身已經適用到手機, 平板, TV這是自然不在話下, ADK, Android@Home的加入, 等於把它延伸到更大的範圍, Movie rental, Google Music更揭示了, Google後面那朵雲可以做Android多大的後盾, 今年的主角不是Android平板呀~~~而是Android everywhere~~~

這些東西朝我理想中的移動裝置越來越接近了, 之前一個想法就是, 一個好的移動裝置, 要有的三個特色, “everywhere”, “get connected”, 以及"seamless", 要能夠隨處取用(everywhere), 隨處取用並不只是單單針對一個裝置來說而已, 在不同場合可以取用不同適合的裝置, 如手機, 平板, 電視, 甚至智慧型3C家電, 而且這些東西不只要能夠有對外界溝通的管道, 甚至彼此可以互相溝通(Get connected), 這一點似乎Android@Home已經是某種程度上的實現了, 最後是"seamless", 不同的移動裝置除了可以互相溝通外, 甚至在使用轉換上可以"無感", 舉個簡單的例子來說, 當你在看一部電影時, 在等公車時, 可能因為有位子坐著, 所以拿出平板來看比較舒服, 等上了公車後, 人潮擁擠, 你會拿出手機接續著看, 等到了家, 電影還沒看完, 繼續轉到電視上看, 如果像這樣的使用體驗在不同的裝置上可以無縫的接續, 那真的會是更大的威力(不知道拿ADK bluetooth有沒辦法實現這樣的東西)

當所有的裝置都連接了, 在配合後端的雲, 那整個會成為一個Skynet或是Borg呢? :D

不過也不是完全沒負面的東西啦, 像是Music和Movie rental那東西, 勢必會變成Carrier一個惡夢, 智慧型手機替他們爭取到了不少使用者, 但是相對的也得付出代價, 越來越多的連網裝置, 如果基礎的infrastructure跟不上, 那勢必會是災難, 也不只Carrier而已, 對於一些網路的服務來說, 連接的媒體就不再只有PC, 數量會越來越多, 需求的架構就要更加紮實了…

According to Facebook mobile development document (Android), you need to generate a key hash for your application in order to apply Facebook SSO(Single Sign on).

Here is the formal way to do this:

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

But sometimes you won’t have a tradtional key store especially when building with Android open sources. Keys in Android open sources are in pk8 format. In order to generate key hashes with these keys, you need to tranfer them into a pk12 key store.

I created another way to generate keyhash without keytool and openssl. Here is the source codes: FacebookKeyHashGen

This program get package sigature directly from package itself. 

上次的作法:

var button1 = findview(R.id(‘button1’));

button1.setOnClickListener(function(view, methodName)
{
     if (methodName == “onClick”) {
         log(“MyScript”, “clicked”);
} });

當然不是很滿意, “if(methodName == "onClick”)“這樣的寫法太醜了啦!

所以這次的目標是:

button1.onclick = function(view) {

     log("MyScript”, “clicked”);

     alert('Hi there!’);

};

這樣比較像印象中javascript的寫法

為了達到這目的, 必須在View中加入onclick這個property, 但原本View class(Java)並沒這東西, 如何將它包裝出來?

Rhino對於Javascript使用原生的java objects並不是直接使用, 還是有透過一層包裝, 因此這就是要做出這個property的路了, 包裝的點在於WrapFactory, 而原生的Java object會被包裝長NativeJavaObject 

而Rhino允許我們用自己的WrapFactory取代原本的, 像是這樣:

jsContext.setWrapFactory(new AndroidWrapFactory());

因此我們會需要自己實作這一個AndroidWrapFactory, 把原本的View改用不同的包裝, 而非原本的NativeJavaObject, 基本上只需要實作wrapAsJavaObject即可:

這邊用了一個新實作的ViewWrapper來取代NativeJavaObject

本來我的打算是繼承自NativeJavaObject, 然後再加入自己的東西, 不過後來發現這樣的作法總會在"put"時出差錯, 原因是NativeJavaObject是沒辦法加入新的member了(其實這說法有點問題, 應該是只要設prototype給它的話還是可以), 加上一些比較實用的function是定義在ScriptableObject的裡面, 因此, 我最後採用ScriptableObject來包裝

但要如何在ScriptableObject裡面實現像NativeJavaObject那樣可以直接叫用原本的Java class裡面的member呢?這部份不用自己實作, 只要把原本的NativeJavaObject當做這新的ViewWrapper的prototype就好了, 所以這邊constructor呼叫的super contructor是:

public ScriptableObject(Scriptable scope, Scriptable prototype)

===> super(scope, new NativeJavaObject(scope, javaObject, staticType));

defineProperty這包裝是從ScritableObject那邊改寫其中一個過來的, 主要是用來讓我們可以把這些"onlick",“onlongclick"包裝成property, 在ViewWrapper可以實作getter和setter, 為了避免名稱上的混淆, 所以把getter的prefix定義成"jsget"而setter是"jsset”

在onlick的setter中, 除了將function object存起來外, 還直接對原本包裝的View設一個OnClickListener, 動作則是執行這個Function object

最後, 前面的範例裡面有一個"alert('Hi! there’)“, 因此為了"alert()"多實作一個Alert.java出來(跟上面的無關啦), 這是source:

接下來的目標, 

  • 包裝一個實際真的可以拿來開發的package, release 0.1 alpha
  • 實作XmlHttpRequest
  • Adapter & AdapterView, Service & Provider

上次做的僅止於setText這個簡單的動作, 那像是處理click這類的怎做?

先拿click來做範例, 在Android中, 如果要替一個view加上處理click動作要利用到View.setOnClickListener, 但setOnClickListener的參數是onClickListener, 這是一個java interface, 在Rhino中如何實作一個Java interface?

首先, 不要被Rhino的文件給騙了, 那有問題(還花了我一個晚上看 :( ), Rhino的source codes裡有個example目錄, 裡面有隻SwingApplication.js, 答案就在這邊

因此, onClick就會像是這樣:

var button1 = findview(R.id(‘button1’));

button1.setOnClickListener(function(view, methodName)
{
     if (methodName == “onClick”) {
         log(“MyScript”, “clicked”);
} });

在這function內, 必須要自己判斷methodName來知道是哪個method被呼叫到, 應該是所有的java interface都可以用這樣去實作

OK, 這樣…很醜…繼續改進