2012年2月26日 星期日

JAVA EE - Servlet / JSP

最近在看 JAVA EE - Servlet / JSP,雖然才剛剛接觸,可是感覺Web技術還蠻有趣的。希望趕快學會Web技術,並將它與Android做結合,這樣子我的點餐系統就更加完美了。

加油!

2012年2月24日 星期五

Google:智慧型眼鏡 (Display Glasses)

當蘋果推出iPhone後,這個革命性的裝置席捲全球,不只改變人們的生活,也改變了資訊產業的生態;如今智慧型手機銷售量已超越個人電腦,成為普及的商品,不禁令人好奇,繼手機之後會出現什麼樣的劃時代產品?其實蘋果與Google早已暗中較勁,過去一年中,均在研發穿戴式電腦(wearable computer)。

根據國外網站的報導,蘋果所研發的穿戴式電腦可能是一支類似iPod nano的手錶,而Google則是具有擴增實境功能的智慧型眼鏡。目前尚不清楚蘋果發展的進度,不過Google眼鏡已經非常具體,並將在今年底上市。

Google 眼鏡外觀如同一般的厚框眼鏡,目睹過的Google員工表示,其外型與知名運動眼鏡品牌Oakley的產品很類似。硬體規格與早期Android手機差不多,據猜測應該會搭配簡易版的Android作業系統。


這支眼鏡最大的特色是具備抬頭顯示(Heads Up Display,HUD)功能,在眼鏡前方有個小鏡頭,用來偵測周圍環境狀況,也可以用來拍照。在其中一片鏡片上有個小螢幕,用來顯示系統訊息,就如同電影中魔鬼終結者眼睛看出去的情況。
操作方式很特殊,是利用頭部傾斜來捲動螢幕,並搭配聲控指令,據說非常好學,一旦習慣之後,並不會讓周遭的人察覺。Google 眼鏡如同手機一樣,也內建感應器、GPS,可以透過 Google 定位服務打卡、透過 Google Map顯示附近資訊、透過Google Goggles以圖片搜尋。

Google眼鏡是由神秘的Google X實驗室進行開發,主導專案的兩位重要人物,一位是創造Google定位服務的工程師,另一位則是Google創辦人謝爾蓋.布林。目前Google將此眼鏡當作實驗性產品,可能會以類似Chromebook的模式進行銷售,估計價格應該與一支智慧型手機差不多。





2012年2月21日 星期二

Google:下一道甜點準備上菜 - Android 5.0 (Jelly Bean)

科技產品目前已經由電腦轉向行動裝置的時代,各家系統都紛紛轉往平板、手機來設計。雖然 Android 4.0 目前更新比率還不高,但因為表現平平,沒有受到太多關注,加上 Windows 8 快要現身,因此今年可能在第二季就會看到 Android 5.0(Jelly Bean)和大家見面。

Google:下一道甜點準備上菜

冰淇淋三明治不少人都還沒有吃到,就已經有 Android 5.0 的消息(來源:DigiTimes)出現。Android 目前的改版速度大約是半年一次,由去年10月19日發表 Android 4.0 的時程來推算,Android 5.0 確實也差不多會在第二季改版,可能就會在今年 Google I/O 中發表。
這次 Android 5.0 比較特別的功能是將會和 Windows 8 整合,可以同時和 Windows 8 安裝在同一台平板電腦上,而且可以在不關機的狀態切換不同的系統。過去 ViewPad 10Pro 就有做過這種設計,未來的平板電腦或是筆電可能會看到更多這種雙系統的設計。
另外 Android 5.0 可能還會加入 Chrome OS 的功能,讓 Android 5.0 在平板電腦、筆電上的運用更廣。如果是這種走向的話,Chrome OS 可能就要走入歷史,畢竟 Android 表現的要比 Chrome OS 要更好,也比較受到各界的關注,未來 Google 也許會借助 Android 5.0 來拉回自家系統在輕薄筆電的佔有率。

Android 作系系統更新年表

  • Android 1.1(Banana Bread):2009年2月9日
  • Android 1.5(Cupcake):2009年4月30日
  • Android 1.6(Donut):2009年9月15日
  • Android 2.0(Eclair):2009年10月26日
  • Android 2.2(Froyo):2010年5月20日
  • Android 2.3(Gingerbread):2010年12月7日
  • Android 3.0(Honeycomb):2011年2月2日
  • Android 4.0(Ice Cream Sandwich):2011年10月19日
  • Android 5.0(Jelly Bean):2012年第二季

2012年2月18日 星期六

Android - AIDL

在Android中,每個應用程式都可以有自己的進程,在相同的進程中彼此可以共用記憶體資訊,但在不同的進程中,Java中不允許跨進程記憶體共用。

在Linux中是以處理程序為單元來進行資料的配置與管理,但是基於保護目的,一個處理程序不能直接存取另一個處理程序資源。

解決方法 :透過 IPC(Inter-Prcess Communication) 來溝通。

為了完成處理程序之間的通訊,Binder採用了AIDL來描述處理程序間的介面,讓Android得以實踐跨界傳值的目的。(跨界存取)


AIDL(Androoid Interface Definition Language)是一種介面描述語言,編譯器可以通過 .aidl 檔生成一段程式代碼,通過預先定義的介面達到兩個進程內部通訊的目的。


實作方法
IAddService.aidl

package com.aidl;


interface IAddService
{
int add(in int x, in int y);
}


AddService.java

package com.service;


import com.aidl.IAddService;


import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;


public class AddService extends Service
{
@Override
public IBinder onBind(Intent arg0) 
{
IAddService.Stub stub = new IAddService.Stub()
{
@Override
public int add(int x, int y) throws RemoteException
{
return x+y;
}
};

return stub;
}
}


AddServiceConnection.java
package com.service;

import com.aidl.IAddService;

import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;

public class AddServiceConnection implements ServiceConnection
{
private IAddService service; 
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
this.service = IAddService.Stub.asInterface(service);
}

@Override
public void onServiceDisconnected(ComponentName name)
{
this.service =  null;
}
public IAddService getService()
{
return this.service;
}
}

AIDL_Add.java
package com.test;

import com.aidl.IAddService;
import com.service.AddServiceConnection;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class AIDL_Add extends Activity
{
private AddServiceConnection connection;
    private EditText editText01, editText02;
    private TextView textView01;
    private Button button01;
    
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        initService();
        
        editText01 = (EditText)findViewById(R.id.editText1);
        editText02 = (EditText)findViewById(R.id.editText2);
        
        textView01 = (TextView)findViewById(R.id.textView2);
        
        button01 = (Button)findViewById(R.id.button1);
        
        button01.setOnClickListener(new Button01OnClickListener());
    }
    
    private void initService()
    {
     connection = new AddServiceConnection();
     Intent intent = new Intent("com.service.REMOTE_SERVICE");
     bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }
    
    class Button01OnClickListener implements OnClickListener
    {
@Override
public void onClick(View view) 
{
int xValue = Integer.parseInt(editText01.getText().toString());
int yValue = Integer.parseInt(editText02.getText().toString());
IAddService service = connection.getService();
try
{
if(service==null)
{
Toast.makeText(AIDL_Add.this, "Service is null", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(AIDL_Add.this, String.valueOf(service.add(xValue, yValue)), Toast.LENGTH_SHORT).show();
textView01.setText(String.valueOf(service.add(xValue, yValue)));
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
    }
}

執行結果如下









2012年2月7日 星期二

Android - AsyncTask

在處理秏時的Android程序時,User可能感覺到系統畫面停頓,感到不協調,甚至發生ANR的錯誤。因此,該耗時程序應另指派一執行緒負責維護運作進行。
PS. UI Thread 若執行5秒以上的工作會拋出ANR的錯誤     
     
AsyncTask執行上的重要方法
(1) onPreExecute( )                               =>    任務執行前呼叫此方法      
(2) doInBackground(Params... )           =>    執行任務工作
(3) onProgressUpdate(Progress... )      =>    顯示任務執行進度
(4) onPostExecute(Result)                    =>    任務執行完成會呼叫此方法        

AsyncTask定義了三種泛型
AsyncTask<Params, Progress, Result>
(1) Params:啟動任務執行的輸入參數,設定於 execute() 的參數型別
(2) Progress:幕後工作執行的百分比
(3) Result:後台執行任務最終返回的結果,設定於 onPostExecute() 的參數型別

    實作方法
    package com.test;

    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;

    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;

    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;

    public class AsyncTeskProgress extends Activity
    {
    private Button Button01;
    private ImageView imageView01;
    private String imgURL = "http://vincentjava.skyhostsite.0lx.net/img/white.png";

        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
         
            Button01 = (Button) findViewById(R.id.Button01);
            imageView01 = (ImageView) findViewById(R.id.imageView01);
    Button01.setOnClickListener(new AsyncBtnOnClickListener());
        }
     
        private class AsyncBtnOnClickListener implements OnClickListener
    {
    @Override
    public void onClick(View view)
    {
    imageView01.setVisibility(View.VISIBLE);
    new AsyncTaskLoadImageProgress().execute(imgURL);
    }

    private class AsyncTaskLoadImageProgress extends AsyncTask<String,IntegerDrawable>
    {
    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute()
    {
    progressDialog = new ProgressDialog(AsyncTeskProgress.this);
    progressDialog.setTitle("ProgressDialog");
    progressDialog.setMessage("Wait!");
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setCancelable(false);
    progressDialog.show();
    }

    @Override
    protected Drawable doInBackground(String... args)
    {
    try
    {
    // 1.取得 HttpEntity 實體
    HttpEntity entity = getHttpEntityByURL(args[0]);
    long length = entity.getContentLength();
    InputStream is = entity.getContent();

    // 2.資料讀取與接收
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buf = new byte[128];
    int ch = -1;
    int count = 0;

    while ((ch = is.read(buf)) != -1)
    {
    baos.write(buf, 0, ch);
    count += ch;

    if (length > 0)
    {
    publishProgress((int) ((count / (float) length) * 100));
    }
    }

    // 3.資料轉換 byte[]  -->  Bitmap  -->  Drawable
    byte[] b = baos.toByteArray();
    Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
    Drawable drawable = new BitmapDrawable(bmp);

    return drawable;

    }

    catch (Exception e)
    {
    e.printStackTrace();
    }

    return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values)
    {
    // 更新進度
    progressDialog.setProgress(values[0]);
    }

    @Override
    protected void onPostExecute(Drawable resultImage)
    {
    progressDialog.dismiss();

    if (resultImage != null)
    {
    imageView01.setImageDrawable(resultImage);
    imageView01.setVisibility(View.VISIBLE);
    }
    }
    }
    }

    private HttpEntity getHttpEntityByURL(String url) throws Exception
    {
    HttpClient client = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);
    HttpResponse response = client.execute(get);
    HttpEntity entity = response.getEntity();
    return entity;
    }
    }


    執行結果如下