星期六, 8月 17, 2013

List of open source Android game Engine


http://ramkumarhelios.blogspot.in/2012/12/list-of-open-source-android-game-engine.html

For creating games in android, there are some supporting open source android game engine which are listed below

1.jMonkey Engine(Java based 3D Game Engine)
http://jmonkeyengine.org/

2.YoghurtGum(Android Game Engine)
https://code.google.com/p/yoghurtgum/

3.Catcake(Android Game Engine)
https://code.google.com/p/catcake/

4.jPCT-AE(Android Game 3D Engine)
http://www.jpct.net/jpct-ae/

5. Dwarf-fw(Android 3D Framework)
https://code.google.com/p/dwarf-fw/

6.Mages(Android Game Engine)
https://code.google.com/p/mages/

7.Angle(Android Game Engine)
https://code.google.com/p/angel-engine/

8.Shiva3d(Android Game Engine)
http://www.stonetrip.com/

9. Unity3d
http://unity3d.com/

10.E3Droid
http://www.e3roid.com/

11.LibGDX
https://code.google.com/p/libgdx/

12.Dxstudio
http://www.dxstudio.com/index.aspx

13.CuttleFishEngine(2D)
http://www.masonmc.com/2012/mkdir-cuttlefish2/

14.Rokon 2D game engine
https://code.google.com/p/rokon/

15. Corona Game Edition
http://www.coronalabs.com/products/corona-sdk/

16. cocos2d-x
http://www.cocos2d-x.org/

星期日, 7月 14, 2013

那年我們十九歲

      前幾天一位高中時期的好友, 上來台北受訓, 順道找我聚聚聊聊, 我們已差不多將近十年沒見. 再次相見, 感覺他沒甚麼多大改變, 只覺得多了一些滄桑, 也多了一些對現實環境的無奈與倦怠, 或許這是我們這個年紀常有的感觸.
      馬兆駿的"那年我們十九歲", 真的很貼切的道出我們當時的心境, 那個年少輕狂, 純真真誠的情誼, 永遠是我最為懷念的美好時光, 雖然目前大家都各分東西, 忙於自己的事業與家庭, 很少再相聚, 但我總是會在心裡默默的祝福他們, 願他們都能各有一片天, 平安快樂的生活每一天.


星期二, 7月 09, 2013

Android Volume Control


AudioManager   mAudioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
   int current_volume =mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
   //If you want to player is mute ,then set_volume variable is zero.Otherwise you may supply some value.
   int set_volume=0;
   mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,set_volume, 0);

Android hide a view after a few seconds


Spawn a separate thread that sleeps for 3 seconds then call runOnUiThread to hide the view.
Thread thread = new Thread() {
   @Override
   public void run() {
       try {
           Thread.sleep(3000);
       } catch (InterruptedException e) {
       }

       runOnUiThread(new Runnable() {
           @Override
           public void run() {
               // Do some stuff
           }
       });
   }
};

Android different ways to handle clicks

http://www.remwebdevelopment.com/dev/a69/Different-Ways-To-Handle-Clicks.html

星期三, 6月 19, 2013

Check Internet is Available in Android Device


http://capycoding.blogspot.tw/2012/10/check-internet-is-available-in-android.html

public boolean check_Internet(Context mContext)
{
        ConnectivityManager mConnectivityManager =
                  (ConnectivityManager) mContext
                               .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo mNetworkInfo =  mConnectivityManager
                                                            .getActiveNetworkInfo();

        if (mNetworkInfo != null &&  mNetworkInfo.isConnectedOrConnecting())
            return true;
        else
            return false;
}

星期二, 5月 07, 2013

eyes on me

這首歌一直是我最愛的歌之一, 百聽不膩,
歌曲意境很感人, 而 FF8 的故事情節更是令人動容.




Whenever sang my songs
on the stage on my own
Whenever said my words
Wishing they would be heard

I saw you smiling at me
Was it real or just my fantasy
You'd always be there in the corner of this tiny little bar

My last night here for you
same old songs just once more
My last night here with you
Maybe Yes Maybe No

I kind of liked it your way
How you shyly placed your eyes on me
Did you ever know that I had mine on you?

Darling So there you are
with that look on your face
As if you've never hurt
As if you've never down
Shall I be the one for you
Who pinches you softly but sure
If frown is shown then
I will know that you are no dreamer

So let me come to you
Close as I wanted to be
Close enough for me to feel your heart beating fast

and stay there as I whisper
How I loved your peaceful eyes on me
Did you ever know that I had mine on you?

Darling So share with me
your love if you have enough
your tears if you're holding back
of pain If that's what it is
How can I let you know
I'm more than the dress and the voice
Just reach me out then you will know that you're not dreaming

=============================================
http://www.ptt.cc/bbs/FayeWong/M.1237403583.A.253.html

此首歌的故事背景是一個名叫做Julia的女子在鋼琴酒吧演奏鋼琴,
後來他發現有個男子常常來聽她演奏。
兩人從沒攀談過,亦不認識,只是一直保持這樣的關係。
男子名叫Laguna,是這個小邦國的士兵,他並不喜歡當軍人,但他喜歡旅行,當軍人可以四處去看看,
且他有兩個同為軍人的好友,讓他並不無聊。

Laguna是個糊塗且有趣的人,在戰場上會帶錯地圖,且常常迷路,但他的朋友皆十分喜歡他。
這天他剛結束一個任務,一如往常的來聽Julia彈琴,她彈的即是〈eyes on me〉。
他的朋友鼓勵他去與Julia攀談,然而當Laguna鼓起勇氣走向前時,居然緊張到腳抽筋了,只好無奈的走回座位。
他的朋友正誇獎她有進步的時候,Julia已一曲彈完,從舞台走了下來。

她對拉格那說,發現他常常來這裡,並且總是坐著一樣的位子。
最後Julia邀請Laguna去 她的房間。那晚他們談了些各自的願望,
Laguna說他希望能夠當一名記者,四處遊山玩水並且寫下這些東西。
Julia則說自己的願望是當一名歌手。
她已寫好了〈eyes on me〉的曲,只是遲遲寫不出歌詞。
等到寫好了歌詞,她便要發表。他們並且還聊了許多事情,於是一晚過去了。

一次Laguna出任務,結果與朋友們皆重傷,他被帶到一個小村莊療養,在那兒並且遇見了Caraway,
Caraway的照料讓他漸漸喜歡上這個地方,便在這個村子待下去了。
某天他的一 個朋友來探望他。Laguna問起了關於Julia的事,朋友對他說,Julia遲遲等著Laguna,然而一切無消無息。
她以為Laguna已在任務中喪生了。

後來Julia終於完成了那首歌,〈eyes on me〉,發表後旋即成為當紅歌手,並下嫁一位高級官員。
Laguna聽著這些消息,只能一陣惆悵。
他娶了Caraway,然而Caraway過幾年即病逝,最後Laguna成為了記者,四處旅行。

-- 跟〈eyes on me〉有關的劇情大致上就這些。
王菲的歌詞中許多是那晚他們的對話內容,例如dreamer,那晚的對話便是如此提到。
整首歌歌詞是Julia形容Laguna的字句。

而 Final Fantasy VIII 的男主角史克爾即是Laguna與Caraway的兒子, 而女主角莉諾亞即是Julia的女兒.
==================================================
http://home.gamer.com.tw/creationDetail.php?sn=860190

Final Fantasy VIII OP


I'll be here...(我在這裡)
Why...?(為什麼?)
I'll be wating...here...(我會在這裡等著)
For what...?(為了什麼?)
I'll be waitig...for you...so...(我會在這裡等你...所以...)
If you come here...(如果你來到這)
You'll find me.(你會找到我)
I promise.(我保證)

在開頭動畫
我們看到的這些話
道盡了劇情的主軸
也對於劇情有了重大的暗示

從FINAL FANTASY VIII的logo上面
我們可以清楚的看到史克爾擁抱著莉諾亞
也就是代表著
這一代的FINAL FANTASY
是在敘述一段關於愛的故事

但是我認為
這一段Love Story並不是一段很完美的故事
反而蘊含著悲傷的輪迴

史克爾他一開始的沉默寡言與對許多事物的漠不關心
在遇到了熱情活潑的莉諾亞之後開始有了轉變
慢慢的也開始接受了她
一切從最早的舞會開始

印象中的一段劇情
讓我深刻感受到了史克爾的轉變

莉諾亞:我做了一個夢,夢到我變成了魔女,Seed會來殺了我,
而Seed的領導者就是史克爾。
史克爾:如果妳變成了魔女,我就會成為魔女的騎士,也就是你的騎士。

莉諾亞:我做了一個夢,在夢裡,不管我怎麼找就是找不到史克爾。
史克爾:妳會找不到我,是因為我們沒有好好的約定,只要你到了那個地方,
妳就一定會找到我,我保證。

到最後
莉諾雅真的繼承了魔女之力成為了魔女
而與史克爾一起去打倒未來的魔女阿爾緹米西雅
在最後與阿爾緹米西雅的決戰中
阿爾緹米西雅對史克爾說了一段話

回想起你的童年......
你的感覺.....
你的話語.....
時間.....
永遠不會等待.....
不管你如何的去抓緊.....
它還是會流逝.....

其實在我遊玩時
都覺得這些沒什麼異狀
但是在專版看到許多關於
阿爾緹米西雅=莉諾雅的一些論點之後
這些劇情讓我差點留下眼淚

以下為我對於阿爾緹米西雅=莉諾雅這件事情的一些想法

莉諾亞繼承了魔女之力之後
獲得了不老不死的生命
但是史克爾是正常人
所以在時光的流逝中
慢慢的老死
只留下莉諾雅一個人獨活
由於魔女之力所以有不死的生命
而莉諾雅也不願意把魔女之力轉給別人
讓別人承受著跟自己一樣的痛苦
所以繼續孤獨的活著
慢慢的變成了阿爾緹米西雅

但是由於使用GF的關係
記憶一點一滴的消逝
只記得要在約定的地方等一個人
所以在約定的孤兒院後面建造了自己的城堡
卻忘記等的人是誰
也忘記等的那個人已經死了
或許曾經努力的想阻止他的死亡
但是最後還是失敗了
或許
最後阿爾緹米西雅也忘記了這件事情吧....

之後打算使用時間壓縮的魔法
想把現在、過去、未來全部串連再一起
或許就是想要等的那個人出現

最後....
真的等到了那個人的出現
史克爾帶著Seed來討伐阿爾緹米西雅
就跟夢裡面一樣....

而這件事就一直的輪迴著
史克爾不斷的討伐未來魔女
也就是他最摯愛的人
莉諾雅....

=========================================

真的好沉痛悲傷
以前一直都以為是單純的勇者討伐魔女的故事
但是知道是這樣沉重的命運輪迴之後
不禁讓我對於這FF8的故事有了另一種感受
原來Happy end的背後有著悲傷的輪迴
史克威爾的劇情安排真的很巧妙

另外
這遊戲也是系列第一款有請明星來演唱主題曲
也就是在請我們華人裡面的天后王菲來演唱的
歌聲悠揚且令人動容
這首歌的歌詞在我聽來
彷彿是在敘述史克爾的父親拉格納與母親蕾茵的故事
玩過遊戲之後
對這歌詞更有感覺....

Eyes On Me

Whenever sing my songs
(不論在何時唱著我的歌)
On the stage on my own
(在舞台上也好,孤獨一個人也好)
Whenever said my words
(不管什麼時候說著我的話)
Wishing they would be heard
(一直希望能夠讓你聽見)
I saw you smiling at me
(望著你對我的笑容)
Was it real or just my fantasy
(不知道這是真實還是幻想)
You’d always be there in the corner
(你總是一如往日的出現在角落)
Of this tiny little bar…………………….
(在這狹小的小酒吧)


My last night here for you
(昨夜我為你守候了一晚)
Same old songs just once more
(一遍一遍唱著你我的歌曲)
My last night here with you?
(昨晚我真的為了你而在這裡嗎?)
Maybe yes maybe no
(也許是,也許不是)
I kind of liked it your way
(我好喜歡你的一切)
How you shyly placed your eyes on me
(你怎麼能夠用如此羞澀的眼神望著我)
Oh did you ever know?
(喔!你曾知道嗎?)
That I had mine on you……………….
(我的心早就屬於你)


Darling so there you are
(親愛的,所以你就在那裡)
With that look on your face
(讓我好好的看著你)
As if you’re never hurt
(就當你從不受傷)
As if you’re never down
(就當你從不跌倒)
Shall I be the one for you
(讓我成為你的一部份,好嗎?)
Who pinches you softly but sure
(誰溫柔但是卻傷了你呢?)
If frown is shown then
(如果為了挫折就皺眉的話)
I will know that you are no dreamer…………………,
(我會認為你是沒有夢想的人)
So let me come to you
(所以,讓我奔向你)


So let me come to you
(所以,讓我奔向你)
Close as I wanted to be
(像我所想像的去接近你)
Close enough for me
(盡量的靠近我)
To feel your heart beating fast
(讓我去感受你快速的心跳)
And stay there as I whisper
(留在那裡,當我低語時)
How I loved your peaceful eyes on me
(我是如此愛你用溫柔的的眼神看著我)
Did you ever know
(你是否明瞭)
That I had mine on you
(我的心早就屬於你)


Dailing, so share with me
(親愛的,跟我分享你的所有)
Your love if you have enough
(與你一起分享足夠的愛)
Your tears if you're holding back
(當你心情不好時,我會和你一同分擔)
Or pain if that's what it is
(或不管什麼痛苦,我與你承擔)
How can I let you know
(要如何才能讓你知道)
I'm more than the dress and the voice
(華麗的外表和動人的聲音都不夠形容我)
Just reach me out then
(只管放心的到我身邊)
You will know that you're not dreaming
(你會明瞭這不只是一場夢)


Darling so there you are
(親愛的,所以你就在那裡)
With that look on your face
(讓我好好的看著你)
As if you’re never hurt
(就當你從不受傷)
As if you’re never down
(就當你從不跌倒)
Shall I be the one for you
(讓我成為你的一部份,好嗎?)
Who pinches you softly but sure
(誰溫柔但是卻傷了你呢?)
If frown is shown then
(如果為了挫折就皺眉的話)
I will know that you are no dreamer…………………,
(我會認為你是沒有夢想的人)

=========================================

就像我以前常常說的
經典的東西
不管過了多久
都會長留在我們心中
FINAL FANTASY最終幻想
每一部都是經典
也難怪每一款都有不錯的成績
但是呢
幻想並沒有結束
人因為有幻想才會讓世界更美好
遊戲也一樣
隨著幻想的劇情
把我們帶入那幻想中的氛圍
是一件美好的事情
這也就是RPG容易懹人感動的地方

1999年到2009年
10年之後在回味一次
FF8給了我不同的感受
經典的遊戲
不管過了多久
依然有它經典的地方
或許再過10年
我再一次回味時
相信一樣可以帶給我相同的感動~

以上~

星期五, 5月 03, 2013

Mysql 帳號權限管理

無法查看此摘要。請 按這裡查看文章。

星期三, 5月 01, 2013

Android TransparentDialog


package com.TransparentDialog;


import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;


public class TransparentDialogActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button buttonStartDialog = (Button)findViewById(R.id.start);
    buttonStartDialog.setOnClickListener(new Button.OnClickListener(){


 @Override
 public void onClick(View arg0) {
  //Create AlertDialog
  AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(TransparentDialogActivity.this);
  myAlertDialog.setTitle("--- Title ---");
   
  myAlertDialog.setMessage("Alert Dialog Message");
   
  myAlertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
   // do something when the button is clicked
   public void onClick(DialogInterface arg0, int arg1) {
    //...
   }});
   
  myAlertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
   // do something when the button is clicked
   public void onClick(DialogInterface arg0, int arg1) {
    //...
   }});
   
  AlertDialog dialog = myAlertDialog.show();
   
  WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
  params.alpha = 0.6f;
  dialog.getWindow().setAttributes(params);
 }});
}
  
}

Android gl_to_bitmap

public Bitmap SavePixels(GL10 gl){
               int b[] = new int[Width * Height];
               IntBuffer ib = IntBuffer.wrap(b);
               ib.position(0);
               gl.glReadPixels(0, 0, Width, Height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
               // The bytes within the ints are in the wrong order for android, but convert into a
               // bitmap anyway. They're also bottom-to-top rather than top-to-bottom. We'll fix
               // this up soon using some fast API calls.
               Bitmap glbitmap = Bitmap.createBitmap(b, Width, Height, Bitmap.Config.ARGB_4444);
               ib = null; // we're done with ib
               b = null; // we're done with b, so allow the memory to be freed
               // To swap the color channels, we'll use a ColorMatrix/ColorMatrixFilter. From the Android docs:
               //
               // This is a 5x4 matrix: [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ]
               // When applied to a color [r, g, b, a] the resulting color is computed as (after clamping):
               //
               // R' = a*R + b*G + c*B + d*A + e;
               // G' = f*R + g*G + h*B + i*A + j;
               // B' = k*R + l*G + m*B + n*A + o;
               // A' = p*R + q*G + r*B + s*A + t;
               //
               // We want to swap R and B, so the coefficients will be:
               // R' = B => 0,0,1,0,0
               // G' = G => 0,1,0,0,0
               // B' = R => 1,0,0,0,0
               // A' = A => 0,0,0,1,0
               final float[] cmVals = { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 };
               Paint paint = new Paint();
               paint.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(cmVals))); // our R<->B swapping paint
               Bitmap bitmap = Bitmap.createBitmap(Width, Height, Config.ARGB_4444); // the bitmap we're going to draw onto
               Canvas canvas = new Canvas(bitmap); // we draw to the bitmap through a canvas
               canvas.drawBitmap(glbitmap, 0, 0, paint); // draw the opengl bitmap onto the canvas, using the color swapping paint
               glbitmap = null; // we're done with glbitmap, let go of its memory
               // the image is still upside-down, so vertically flip it
               Matrix matrix = new Matrix();
               matrix.preScale(1.0f, -1.0f); // scaling: x = x, y = -y, i.e. vertically flip
               return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); // new bitmap, using the flipping matrix
           }

traceview: Test the performance of an Android application


 
If you want to profile your application to find performance bottlenecks you can use the traceview tool. This gives you a graphical view of performance traces of your application.

To create a trace add the following to your code where you want to start tracing:
Debug.startMethodTracing("myapp");
 
and then put the following when you want to stop tracing:
Debug.stopMethodTracing();
This will create a trace file call myapp.trace in the root directory of the SD Card. As it is written to the SD Card:
    If you're using the emulator you'll need to add an SD card to your AVD.
    You'll need to give you app permission to write the SD card by adding the following to your Manifest:
   
 
Once the file has been created you'll need to copy it to your PC. You can do this using the adb command:
adb pull /sdcard/myapp.trace c:/my/dir/myapp.trace

Finally, start traceview giving it the full path to the trace file:
traceview c:/my/dir/myapp.trace

I did have some problems with traceview failing with OutOfMemory exceptions. I fixed this on Windows by changing the last line of traceview.bat from:

call java -Djava.ext.dirs=%javaextdirs% -Dcom.android.traceview.toolsdir= -jar %jarpath% %*
to:
call java -Xmx1g -Djava.ext.dirs=%javaextdirs% -Dcom.android.traceview.toolsdir= -jar %jarpath% %*

Adding the -Xmx1g option allows traceview to use more memory.

Android NDK Sample

Create a regular Android project.
The project has a package name of com.miles.ndk with a default Activity name of
AndroidNDKSample1Activity
In Linux,
Create a ndk1 directory, and create a directory name jni in this directory.
Like this:
/var/tmp/miles/ndk1
/var/tmp/miles/ndk1/jni

add native.c in /var/tmp/miles/ndk1/jni
add Android.mk in /var/tmp/miles/ndk1/jni
native.c ==>
// -----------------------------------------------------
#include <jni.h>
#include <string.h>
#include <android/log.h>


#define DEBUG_TAG "NDK_AndroidNDKSample1Activity"
void Java_com_miles_ndk_AndroidNDKSample1Activity_helloLog(JNIEnv * env, jobject this, jstring logThis)
{
    jboolean isCopy;
    const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy);
    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szLogThis);
    (*env)->ReleaseStringUTFChars(env, logThis, szLogThis);
}
// ----------------------------------------------------

Android.mk ==>
// ----------------------------------------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE    := ndk1
LOCAL_SRC_FILES := native.c
include $(BUILD_SHARED_LIBRARY)
// -----------------------------------------------------
cd /var/tmp/miles/ndk1
/var/tmp/miles/android/NDK/android-ndk-r8/ndk-build
copy /var/tmp/miles/ndk1/libs to Android directory
// ======================================================
AndroidNDKSample1Activity.java ==>
package com.miles.ndk;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class AndroidNDKSample1Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
    }

    public void but1_onclick(View v){
       TextView tv = (TextView)findViewById(R.id.textView1);
       tv.setText("Hello World!!");
       helloLog("This will log to LogCat via the native call.");
    }

    private native void helloLog(String logThis);

    static {
       System.loadLibrary("ndk1");
    }
}
// =====================================================
main.xml ⇒
// =====================================================
   <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1">
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
<Button android:text="Button" android:id="@+id/button1" android:layout_height="wrap_content" android:onClick="but1_onclick" android:layout_width="wrap_content"></Button>

<TextView android:text="TextView" android:layout_weight="0.08" android:id="@+id/textView1" android:layout_height="wrap_content" android:layout_width="99dp"></TextView>

</LinearLayout>

星期六, 4月 27, 2013

取得外掛字幕 srt 的內容


import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.R.integer;
import android.content.Context;
import android.util.Log;

/**
 * class for read and parse srt subtitle
 * 
 * This class is used to read and parse srt subtitle 
 * 
 */
public class VNSubtitleSRT {
 private static Matcher srtMatcher = null;
 
 public VNSubtitleSRT() {
  // do something
 }
 // --------- read srt file contents ----------
 /**
  * get subtitle srt file contents
  * @param filename SRT filename
  * @return SRT file contents
  */
 public static String getSRTContents(String filename) {
  StringBuilder text = new StringBuilder();
  try{
      //Get the text file
   BufferedReader br = new BufferedReader(new FileReader(filename));
         String line;
         while ((line = br.readLine()) != null) {
          text.append(line);
          text.append("\r\n");
         }
         br.close();
   return text.toString();
     }catch(Exception e){
         e.printStackTrace();
     }
  return "";
 }
 // --------- parse srt contents ---------------
 /**
  * parse srt file contents to ArrayList
  * @param contents srt file contents
  * @return false:parse error, true:parse correct
  */
 public static boolean parseSRTContents(String contents) {
  String pat = "(\\d+)\r\n(\\d{2}\\:\\d{2}\\:\\d{2},\\d{3}) --\\> (\\d{2}\\:\\d{2}\\:\\d{2},\\d{3})\r\n([\\s\\S]*?\r\n\r\n)";
  Pattern p = Pattern.compile(pat);
  srtMatcher = p.matcher(contents);
  if (srtMatcher.find(0)){
   return true;
  }
  return false;
 }
 // --------- get subtilte from CurrentPosition -------------
 public static String getSubtitle(int currentPosition){
  String sequence = "";
  int start = 0;
  int end = 0;
  String text = "";
  if (null == srtMatcher){
   return "";
  }
  if (!srtMatcher.find(0)){
   return "not find matcher";
  }
  while(srtMatcher.find()){
   sequence = srtMatcher.group(1);
   start = timeToInt(srtMatcher.group(2));
   end = timeToInt(srtMatcher.group(3));
   text = srtMatcher.group(4);
   if (currentPosition > start && currentPosition < end){
    return text;
   }
  }
  return "";
 }
 // --------- time to int ------------
 private static int timeToInt(String ctime){
  int hours = Integer.valueOf(ctime.substring(0, 2));
  int mins =  Integer.valueOf(ctime.substring(3, 5));
  int secs =  Integer.valueOf(ctime.substring(6, 8));
  int msec =  Integer.valueOf(ctime.substring(9, 12));
  
  return (hours*60*60 + mins*60 + secs)*1000 + msec;
 }
}

Android Debug Bridge

Adb 全名是 Android Debug Bridge,是開發或使用 Android 時很常用到的工具。使用者可以從Android 官方站下載 SDK,在其中的 platform-tools (原本在 \Tools) 中找到。

當機器上有打開 USB debug mode 時,使用者即可通過adb 進行各種 debug 、底層(linux user space)的 Android 功能。比較常用的功能:
- tools\ddms.bat: Android AP/Framework 層最主要的 debug tool
- 安裝 Android 應用程式
- 連接機器,使用 linux userspace 的功能。 ex: ping, ssh, ftp ... blah blah.

adb的工作方式比較特殊採用監聽Socket TCP 5554等端口的方式讓IDE和Qemu通訊,預設情況下adb會daemon相關的port。

這篇文章主要是整理了一些adb 的基本功能,後面補上一些開發時常用的功能。

文件參考:

- 官方的說明文件: http://developer.android.com/tools/help/adb.html
- Android模擬器adb命令介紹

- Source code: system/core/adb/ ,除了 adb client 跟 adbd (Android 系統內負責處理 adb 功能的 daemon)的實作外,裡面包含了 service 跟 overview 的文件。

功能介紹
1. 通過adb 進入機器或模擬器的shell模式
adb shell
也可以執行各種Linux的命令,其命令格式為:adb shell command

PS: 當 adb shell 之後提示字元為"#"時,表示使用者為 root (最大權限),若是 "$" 則是以shell 權限工作

adb shell ls 就是列出目錄
adb shell dmesg 會列印出Linux kernel log
adb shell cat /proc/kmsg 持續印出 kernel log (需要 root)
adb shell keyevent 1 輸入 keyevent,可輸入的內容參考 adb shell keyevent

2. 安裝Android 應用程式(*.apk)
可執行adb install android123.apk,這樣名為android123的安裝包就會安裝到Android模擬器中,前提是android123.apk文件需要放到SDK\Tools目錄下。
比較特殊的安裝方法還有:
"-r": 當已經安裝過舊版本的程式時,可以使用 -r 去覆蓋。
"-f": 強制安裝,通常在安裝程式時會遇到相容問題,可使用此參數解決。

3. PC 端與Android 機器的檔案傳輸
除了使用記憶卡模式外,還可使用下面命令可以進行檔案傳輸:
把android123.txt 傳到機器上的/tmp/ 資料夾中:
adb push android123.txt /tmp/android123.txt

從機器上把 android123.txt 抓到PC端:
adb pull /tmp/android123.txt android123.txt

4. 顯示系統資訊 - dumpsys
除了直接輸入 adb shell dumpsys 外,也可以另外指定要顯示的 service,簡列一些參數,用法如:
adb shell dumpsys SurfaceFlinger
battery: 列出基本的電池資訊
batteryinfo: 各種功能使用 power 的狀況,同About Phone 裡面的電池使用狀況。
SurfaceFlinger: 系統的 Surface 使用情況
power: 列出 Power Manager 的參數,如 wakelock 時間等
alarm: 列出目前有註冊 alarm 者

5. 其他
- Android 預設可編譯成三種模式: eng, userdebug, user。一般使用者拿到的機器多是 user 版,當然如果是開發人員,可能會使用 eng 或 userdebug 版 進行debug。或是使用者自行 root 機器後,可使用下列指令取得 root 權限

adb root
- 一般為了防止系統出問題,所以 /system 通常在掛載時會設定為唯讀(read only),當使用者有root權限時,可使用下面指令將系統重新掛載成 R/W 模式,可對 /system 內的檔案做修改
adb remount
- 如果在使用 adb 時發現有* daemon not running. starting it now *的提示可以結束adb
adb kill-server
- 顯示 android 機器連接狀況
adb devices
- 等待正在運行的設備
adb wait-for-device
- Port forwarding,在某些應用如模擬器的網路連接使用、VNC時,會用到這項功能。主要是用來將機器上的的TCP port 5555 轉發到 port 1234
adb forward tcp:5555 tcp:1234
- 擷取系統內的各種資訊,產生 bug report
adb bugreport


香水

其實大約從高中時期開始, 我就對身上散發某種迷人淡淡香水味道的女生特別喜愛,
感覺非常有女人味, 對我有絕對的吸引力, 每次碰到這種女生, 都好想撲到她身上 (羞).

前一陣子, 我太太帶我去挑選男用香水, 首先去百貨公司的 Christian Dior 專櫃,
試聞了幾款香水, 發現都沒有喜愛的 (其實是該櫃姊服務有待加強), 於是就再到莎莎去找看看.
該莎莎的店員服務很不錯, 推薦一款 Ferre 男用淡香水, 還蠻對味的, 於是就決定是它了.

最近每天都噴一些此香水在身上, 自己聞的都覺得心情似乎也會變更好, 哈~~
我太太則是用 Novae Plus 紫貓物語的香水, 味道非常迷人, 不過她不太愛塗香水,
只有爾偶在某些場合才會用, 其實我還蠻希望她能每天用.

夏天快到了, 或許再找個時間去挑選一下適合夏天的香水也不錯.