2012年9月7日 星期五

[Android] GCM可以怎麼用?

GCM的前身就是所謂的C2DM, 最早在今年Google I/O時聽到C2DM將進化到GCM時, 就在想, 一定要架個server才可以利用GCM嗎?

其實是可以不用的

從API console可知, 是可以設定允許從任意IP傳送的

再來看看一般的流程:
1. Regster:
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
  GCMRegistrar.register(this, SENDER_ID);
} else {
  Log.v(TAG, "Already registered");
}
2. 取得Registration ID後將ID送至Server
3. Server之後可以用這ID送訊息給這一支手機

由"2"看來, 其實Registration ID是關鍵, 而不是Server, 任何人只要有Registration ID, 就可以傳送訊息給這隻手機了

做了個小小實驗, 寫了一支Activity同時具備了收訊息以及傳送(給自己)的能力:

https://github.com/julianshen/GCMTest

想到的應用: 兩隻手機透過條碼或藍牙交換Registration ID, 就可以透過GCM互傳訊息了

缺點: Registration ID如果有變(GCM是有可能更換ID), 就失效了

[Android] 如何知道使用者是否已移除你的程式

這問題我原先是在Stack overflow看到的:

http://stackoverflow.com/questions/12245163/android-sdk-facebook-how-to-know-when-a-user-is-not-using-your-app-anymore/12250465#12250465

我也提供了一個解法, 不過, 慚愧的是, 我當初突然想到這解法後, 自己並沒有去實驗它, 只是覺得理論上可行... :P

我的方法是, 利用GCM (Google Cloud Messaging), 裡面有一段:

When users uninstall an application, it is not automatically unregistered on GCM. It is only unregistered when the GCM server tries to send a message to the device and the device answers that the application is uninstalled. At that point, you server should mark the device as unregistered (the server will receive a NotRegistered error).

後來拿了GCM sample試了一下, 好像也可行, 只是不是那麼即時, 也就是沒辦法剛移除就知道了, 我的測試結果是, 一兩個小時候才出現 "NotRegistered", 不過似乎也是個解法就是了...

2012年9月2日 星期日

[筆記] 2012 9月第一週

這禮拜想到的東西真有點雜, 標題只好隨便下, 本來這週給自己要求的進度應該要再多一點, 結果最後只為了node for Android加了Android log的機制

node for Android

這週本來預定的目標是串接上NativeActivity, 不過, 沒做到, 需要多花點時間想切入點:
  1. pass "struct android_app *" to Node (從android_main呼叫新的node::Start)
  2. wrap "struct android_app *" (是否要依附在process object? 參考資料: node_object_wrap.h, v8::Object::SetPointerInInternalField)
  3. Design of callbacks for AppCmd, InputEvent (NativeActivity --> Node)
這邊有點頭痛, 要找到一個比較好的切入點設計一個新的架構給NativeActivity, 不過這邊又回頭想了一個問題, 到底Node適不適合UI programming, 還是當做一個server, 掛到一個Android service會比較適合?

adding native module to Node:
為了練習這部份, 把android log的機制加進去, 完成後可以在js裡用下面這樣叫用Android log
require('android');
alog.d('tag', 'message1'); //debug log
alog.e('tag', 'var a=', a, ' found', 1, 'error'); //error log
由這code看, 主要有兩個部分, 一個是一個名為android的module, 一個是alog這個global object (Node本身已有"log", 為避免衝突, 改名為alog)

新增module的參考資料為: http://nodejs.org/api/addons.html#addons_hello_world , 不過, 這邊加的不是addon而是一個native module, 所以有點不同, 首先為了這個module新增了, node_android.cc (class Android), 名字一定要是"node_"開頭 , 這是由於binding時, 會尋找"node_"開頭的module (參考 node_extensions.cc : get_builtin_module), 這邊主要implement的是用"NODE_SET_METHOD"加入新的method "log", 用"NODE_DEFINE_CONSTANT"映射了幾個log level的常數, 最後用"NODE_MODULE"定義module的init method
Source code: https://github.com/julianshen/node-android/blob/master/jni/node-v0.8.8/android/node_android.cc
不過這樣不夠, 因為我要的不是只有"log", 而是要像"alog.d"這樣的東西, 因此又多了一個android.js來處理:
 
var binding = process.binding('android');
function log(level, args) {
    var tag = args[0];
    var len = args.length;
    var objs = [];
    for(var i = 1; i < len; i++) {
       objs.push(args[i]);
    }
    var msg = objs.join(' ');
    binding.log(level, tag, msg);
}
var alog = {
    v: function() {
        log(binding.ANDROID_LOG_VERBOSE, arguments);
    },
    d: function() {
        log(binding.ANDROID_LOG_DEBUG, arguments);
    },
    i: function() {
        log(binding.ANDROID_LOG_INFO, arguments);
    },
    w: function() {
        log(binding.ANDROID_LOG_WARN, arguments);
    },
    e: function() {
        log(binding.ANDROID_LOG_ERROR, arguments);
    }
};
global.alog = alog;



首先用了process.binding來bind剛剛native的部份, 另為就是把alog變成global object


其他TODO

Idea board, Bluetooth OPP....還沒想fb world hack做啥好

2012年9月1日 星期六

Idea board : step 1

昨天晚上,突然開始在想一件事,怎樣把一堆ideas變成一些有用的東西?有些人有想法但力有未逮,有些人則有能力,用一個東西把這些串一起實現一些酷玩意兒,或許不錯 XD