2010年12月31日星期五

在Windows桌面上體驗HTC Home


你喜歡HTC手機的板面嗎?

下載HTC Home便可以在Windows Vista 或 Windows 7桌面上體驗HTC.



HTC Home 2是一個時鐘, 天氣預報和動畫的部件(widget). 你可以看雲漂浮在你的桌面上, 雨滴滑落在你的屏幕, 甚至雷擊.


除了HTC Home的風格之外, 它還提供Windows Phone 7的Metro風格.


http://www.htchome.org/



香港電訊管理局(OFTA)推出寬頻表現測試網站

電訊局寬頻表現測試@Android
Android手機用戶可以在Android設備啟動Market搜索"OFTA".


此寬頻表現測試系統("系統")由電訊管理局("電訊局")委託香港國際互聯網交換中心設計、建立、操作和提供支援。

本系統讓寬頻服務用戶量度以下寬頻連接的表現—

下載速度指把數據從系統下載至用戶裝置的速度。

上載速度指把數據從用戶裝置上載至系統的速度。

網絡時延指把數據由用戶裝置發送至系統,以及其後用戶裝置從系統接收數據的來回時間。

封包遺失指從用戶裝置傳送數據至系統期間的封包遺失百分率。

抖動指接收封包延誤的變動。在傳送端,封包以連續流的方式傳送,封包與封包之間平均地分隔。由於網絡擠塞及其他因素,每個封包在接收時的時延或會有所不同,而不會維持不變。

系統以處理在香港境內的寬頻表現測試而設計。

本系統供用戶免費使用,然而用戶使用該網站時,須留意其寬頻服務供應商可能會向其徵收數據使用服務費用。位處香港境外的用戶(不論是否本地寬頻服務供應商的用戶)須注意,他們或須就接達系統繳付額外服務費,款額可能甚為可觀。

由於現時絶大部分寬頻服務的速度在每秒100兆比特以下,測試網站被調校至最適合測試每秒100兆比特或以下的寬頻服務。



iPhone 和 Android 手機的用戶

除桌上電腦和筆記簿電腦的用戶外,蘋果iPhone和Android手機的用戶也可接達本系統。相關應用軟件的正式名稱為"電訊局寬頻表現測試"("OFTA Broadband Performance Test"),用戶可經以下途徑免費下載:

蘋果 iPhone: http://www.apple.com/iphone/apps-for-iphone

Android 手機 : http://www.android.com/market

用戶須注意,本系統只支援測量蘋果iPhone和Android手機的上載速度、下載速度和網絡時延。

Source: 電訊局寬頻表現測試



2010年12月30日星期四

使用意圖"MediaStore.ACTION_IMAGE_CAPTURE"要求其他服務提供程序幫我們拍照

在之前另一篇文章描述了如何"實現Android照相機的拍照功能(Camera.takePicture)", 當然,這是一個很簡單的例子. 其實,有時我們不需要我們自己編寫所有的程序碼; Android提供了一種機制: 意圖(Intent).

通過使用意圖"android.provider.MediaStore.ACTION_IMAGE_CAPTURE", 我們可以要求其他服務提供程序幫助, Android操作系統會自動選擇合適的程序幫我們拍照, 然後再把圖片送回給我們.

MediaStore.ACTION_IMAGE_CAPTURE

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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/captureimage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Call for ACTION_IMAGE_CAPTURE"
/>
<ImageView
android:id="@+id/imagecaptured"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>


AndroidImageCapture.java
package com.AndroidImageCapture;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class AndroidImageCapture extends Activity {

ImageView imageiewImageCaptured;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonImageCapture = (Button)findViewById(R.id.captureimage);
imageiewImageCaptured = (ImageView)findViewById(R.id.imagecaptured);

buttonImageCapture.setOnClickListener(buttonImageCaptureOnClickListener);
}

Button.OnClickListener buttonImageCaptureOnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);

}};

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK)
{
Bundle extras = data.getExtras();
Bitmap bmp = (Bitmap) extras.get("data");
imageiewImageCaptured.setImageBitmap(bmp);
}

}
}


相關文章:
- 通過EXTRA_OUTPUT, 指定儲存圖像的路徑



2010年12月28日星期二

如何取消狀態欄通知(status bar notification)

前文示範"如何產生狀態欄通知(status bar notification)", 本文示範"如何取消狀態欄通知(status bar notification)".

如何取消狀態欄通知(status bar notification)

你可以使用cancel(int)方法, 清除個別ID的通知. 或使用cancelAll()方法清除所有你的通知.

<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/fire1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Fire Notification #1 -"
/>
<Button
android:id="@+id/fire2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Fire Notification #2 -"
/>
<Button
android:id="@+id/clear1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Clear Notification #1 -"
/>
<Button
android:id="@+id/clear2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Clear Notification #2 -"
/>
<Button
android:id="@+id/clearall"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Clear ALL Notification -"
/>
</LinearLayout>


package com.AndroidStatusBarNotifications;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
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;

public class AndroidStatusBarNotifications extends Activity {

private static final int ID_My_Notification_1 = 1;
private static final int ID_My_Notification_2 = 2;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonFire1 = (Button)findViewById(R.id.fire1);
Button buttonFire2 = (Button)findViewById(R.id.fire2);
Button buttonClear1 = (Button)findViewById(R.id.clear1);
Button buttonClear2 = (Button)findViewById(R.id.clear2);
Button buttonClearAll = (Button)findViewById(R.id.clearall);
buttonFire1.setOnClickListener(buttonFire1OnClickListener);
buttonFire2.setOnClickListener(buttonFire2OnClickListener);
buttonClear1.setOnClickListener(buttonClear1OnClickListener);
buttonClear2.setOnClickListener(buttonClear2OnClickListener);
buttonClearAll.setOnClickListener(buttonClearAllOnClickListener);
}

private Button.OnClickListener buttonClearAllOnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager)getSystemService(ns);
mNotificationManager.cancelAll();
}};

private Button.OnClickListener buttonClear1OnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
clearNotification(ID_My_Notification_1);
}};

private Button.OnClickListener buttonClear2OnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
clearNotification(ID_My_Notification_2);
}};

private void clearNotification(int notification_id){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager)getSystemService(ns);
mNotificationManager.cancel(notification_id);
}

private Button.OnClickListener buttonFire1OnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
fireNotification(ID_My_Notification_1);
}};

private Button.OnClickListener buttonFire2OnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
fireNotification(ID_My_Notification_2);
}};

private void fireNotification(int notification_id){
//Get a reference to the NotificationManager
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager)getSystemService(ns);

//Instantiate the Notification
int icon = android.R.drawable.ic_dialog_alert;
CharSequence tickerText = "Hello" + String.valueOf(notification_id);
long when = System.currentTimeMillis();

Notification notification = new Notification(icon, tickerText, when);

//Define the Notification's expanded message and Intent
Context context = getApplicationContext();
CharSequence contentTitle = "My Notification" + String.valueOf(notification_id);
CharSequence contentText = "Hello My Notification!" + String.valueOf(notification_id);
//Intent notificationIntent = new Intent(AndroidStatusBarNotifications.this, AndroidStatusBarNotifications.class);
Intent notificationIntent = new Intent(getBaseContext(), AndroidStatusBarNotifications.class);
PendingIntent contentIntent = PendingIntent.getActivity(AndroidStatusBarNotifications.this, 0, notificationIntent, 0);

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

//Pass the Notification to the NotificationManager
mNotificationManager.notify(notification_id, notification);

}
}




2010年12月26日星期日

狀態欄通知(status bar notification)

狀態欄通知(status bar notification)在系統的狀態欄之上添加一個圖標(連帶有可選的文本信息), 以及在“通知“窗口之上添加一個擴展信息.

狀態欄通知(status bar notification)在系統的狀態欄之上添加一個帶有文本信息的圖標
通知窗口之上添加的擴展信息

創建狀態欄通知的基本步驟:

1 - 獲取NotificationManager引用對象(Get a reference to the NotificationManager)

2 - 實例化(Instantiate the Notification)

3 - 定義通知擴展的消息和意圖(Define the Notification's expanded message and Intent)

4 - 傳遞通知給其NotificationManager(Pass the Notification to the NotificationManager)

下面是一個簡單的例子:

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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/fire"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Fire Notification -"
/>
</LinearLayout>


AndroidStatusBarNotifications.java
package com.AndroidStatusBarNotifications;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class AndroidStatusBarNotifications extends Activity {

private static final int ID_My_Notification = 1;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonFire = (Button)findViewById(R.id.fire);
buttonFire.setOnClickListener(buttonFireOnClickListener);
}

private Button.OnClickListener buttonFireOnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

//Get a reference to the NotificationManager
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

//Instantiate the Notification
int icon = android.R.drawable.ic_dialog_alert;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();

Notification notification = new Notification(icon, tickerText, when);

//Define the Notification's expanded message and Intent
Context context = getApplicationContext();
CharSequence contentTitle = "My Notification";
CharSequence contentText = "Hello My Notification!";
//Intent notificationIntent = new Intent(AndroidStatusBarNotifications.this, AndroidStatusBarNotifications.class);
Intent notificationIntent = new Intent(getBaseContext(), AndroidStatusBarNotifications.class);
PendingIntent contentIntent = PendingIntent.getActivity(AndroidStatusBarNotifications.this, 0, notificationIntent, 0);

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

//Pass the Notification to the NotificationManager
mNotificationManager.notify(ID_My_Notification, notification);

}};
}



相關文章:
- 如何取消狀態欄通知(status bar notification)



進度對話框(ProgressDialog)

本範例示範如何實現進度對話框(ProgressDialog), 通過異步任務(AsyncTask)啟動和關閉進度對話框.

進度對話框(ProgressDialog)

啟動進度對話框:
ProgressDialog.show();

關閉進度對話框:
progressDialog.dismiss();

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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Start -"
/>
</LinearLayout>


AndroidProgressDialog.java
package com.AndroidProgressDialog;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;

public class AndroidProgressDialog extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonStart = (Button)findViewById(R.id.start);

buttonStart.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new asyncTaskUpdateProgress().execute();
}

});

}

public class asyncTaskUpdateProgress extends AsyncTask<Void, Integer, Void> {

int progress;
ProgressDialog progressDialog;

@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
progressDialog.dismiss();
}

@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progress = 0;
progressDialog = ProgressDialog.show(AndroidProgressDialog.this, "ProgressDialog", "Wait!");
}

@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
while(progress<100){
progress++;
SystemClock.sleep(20);
}
return null;
}
}
}




2010年12月23日星期四

香港HTC Wildfire已更新Android 2.2作業系統

香港HTC已公佈提供Wildfire Android 2.2作業系統軟體的無線更新

Android 2.2 on HTC Wildfire

更新-HTC Wildfire 軟體無線更新
我們將於12月23 號開始提供HTC Wildfire無線軟體更新,系統會陸續送出更新提示,當您收到系統提示只要點選立即下載即可經由3G/GPRS或無線網路的連線方式,完成您的手機系統更新。(更新後請從功能表>設定>關於手機>軟體資訊>軟體號碼會更新成2.27.708.1即表示更新成功) 主要更新功能如下: Android 2.2作業系統升級 注意: 請先備份您資料,然後再升級裝置。建議您可選擇在有免費的Wi-Fi環境下載更新(例如:住家及辦公室等)。如您目前使用3G網路,下載可能須支付電信業者額外費用,請先確認已申租無限上網費率後再使用。如有疑問請致電 HTC 客服專線 +852-3520-1234。

如果還未收到OTA通知, 可以嘗試檢查系統軟件更新.

在HOME SCREEN, 按MENU鍵, 點擊About phone -> System software updates.

2010年12月21日星期二

Google 快將為 Nexus One 更新薑餅(Gingerbread)操作系統.

Google透過Nexus One Twitter公佈: 將在未來幾週內以OTA為Nexus One更新薑餅(Gingerbread)操作系統.

The Gingerbread OTA for Nexus One will happen in the coming weeks. Just hang tight!

2010年12月18日星期六

實現Android照相機的拍照功能(Camera.takePicture)

前文描述了"Android的照相機預覽功能(Camera Preview)", 本文進一步新增照相機的拍照功能.

Android照相機的拍照功能(Camera.takePicture)

修改AndroidManifest.xml
- 授予使用照相機權限, "android.permission.CAMERA"
- 並設定屏幕在一定的方向, android:screenOrientation="portrait"
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.AndroidTakePicture"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidTakePicture"
android:label="@string/app_name"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
</manifest>


修改佈局(main.xml), 再多添加一個Button.
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/takebutton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- Take Picture -"
/>
<SurfaceView
android:id="@+id/previewsurface"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


主要代碼, AndroidTakePicture.java
主要是實踐ShutterCallback, 和PictureCallback, 調用takePicture()方法.
本應用程序運行的結果是一個圖片的Bitmap位圖, bitmapPicture.
package com.AndroidTakePicture;

import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class AndroidTakePicture extends Activity implements SurfaceHolder.Callback{

Camera myCamera;
SurfaceView previewSurfaceView;
SurfaceHolder previewSurfaceHolder;
boolean previewing = false;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

getWindow().setFormat(PixelFormat.UNKNOWN);
previewSurfaceView = (SurfaceView)findViewById(R.id.previewsurface);
previewSurfaceHolder = previewSurfaceView.getHolder();
previewSurfaceHolder.addCallback(this);
previewSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

Button buttonTakePicture = (Button)findViewById(R.id.takebutton);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
myCamera.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);
}});
}

ShutterCallback shutterCallback = new ShutterCallback(){

@Override
public void onShutter() {
// TODO Auto-generated method stub

}};

PictureCallback rawPictureCallback = new PictureCallback(){

@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub

}};

PictureCallback jpegPictureCallback = new PictureCallback(){

@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);

}};

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

if(previewing){
myCamera.stopPreview();
previewing = false;
}


try {
myCamera.setPreviewDisplay(arg0);
myCamera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
myCamera = Camera.open();
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
myCamera.stopPreview();
myCamera.release();
myCamera = null;
previewing = false;
}
}


拍照後, 預覽顯示便會停止. 如果要不斷預覽的話, 需重新調用startPreview()方法.


相關文章:
- 使用意圖"MediaStore.ACTION_IMAGE_CAPTURE"要求其他服務提供程序幫我們拍照



照相機預覽功能(Camera Preview)畫面轉了90度!!!

據聞相機預覽功能(Camera Preview)並劃一標準化, 可能會出現畫面轉了90度!

(據聞)可以硬性設定屏幕方向便可解決問題:
- 通過XML設置屏幕方向(android:screenOrientation), 或
- 通過Java程序碼, 運行時設置屏幕方向 - setRequestedOrientation().



2010年12月16日星期四

Android的照相機預覽功能(Camera Preview)

這是一個最簡單的照相機預覽功能的示範: 在佈局設置一個SurfaceView提供預覽功能; 本應用程式只能預覽, 並不支持其他如拍照等功能.

在Android模擬器上運行
在真正的Android移動電話上運行

首先, 修改AndroidManifest.xml授予使用照相機權限, "android.permission.CAMERA".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.AndroidCameraPreview"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidCameraPreview"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
</manifest>


修改佈局(main.xml), 添加一個SurfaceView.
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<SurfaceView
android:id="@+id/previewsurface"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


主要代碼, AndroidCameraPreview.java
package com.AndroidCameraPreview;

import java.io.IOException;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class AndroidCameraPreview extends Activity implements SurfaceHolder.Callback{

Camera myCamera;
SurfaceView previewSurfaceView;
SurfaceHolder previewSurfaceHolder;
boolean previewing = false;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

getWindow().setFormat(PixelFormat.UNKNOWN);
previewSurfaceView = (SurfaceView)findViewById(R.id.previewsurface);
previewSurfaceHolder = previewSurfaceView.getHolder();
previewSurfaceHolder.addCallback(this);
previewSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

if(previewing){
myCamera.stopPreview();
previewing = false;
}


try {
myCamera.setPreviewDisplay(arg0);
myCamera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
myCamera = Camera.open();
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
myCamera.stopPreview();
myCamera.release();
myCamera = null;
previewing = false;
}
}


主活動(AndroidCameraPreview)定義為extends Activity implements SurfaceHolder.Callback, 所以,我們必須重寫surfaceCreated(), surfaceChanged()和surfaceDestroyed()方法. 這裡亦是實現照相機預覽功能的主要部分.
以及, 需要在onCreate()方法中先設置我們的SurfaceHolder.


相關文章:
- 照相機預覽功能(Camera Preview)畫面轉了90度!!!
- 實現Android照相機的拍照功能(Camera.takePicture)



2010年12月8日星期三

ADT極速更新版本 ADT 8.0.1

跟隨 Android 2.3 SDK 發布的 Eclipse 插件 ADT 8.0.0 已經極速推出更新版本 ADT 8.0.1.

更新ADT:

在Eclipse點擊Help, 再點擊Check for Updateds.



Android大師Andy Rubin演示摩托羅拉Android平版電腦以及Android Google Map 5.0

就在 Samsung Nexus S 剛剛推出(還未見街!), 谷歌官方公佈Android 2.3 薑餅(Gingerbread)的差不多同時, 它已成為舊型號!!!

Android的創造者, 超級大師Andy Rubin在D: Dive Into Mobile大會上演示摩托羅拉 Android 平版電腦的原型機. 它運行Nvidia雙核心芯片, 下一代的Android操作系統-蜂窩(Honeycomb). 他用它來炫耀谷歌即將更新的手機地圖應用程式-Android Google Map 5.0.


Andy Rubin with Motorola Tablet Prototype with Honeycomb



2010年12月7日星期二

下載 Android 2.3 的用戶指南


下載 Android 2.3 的用戶指南網址:

http://www.google.com/support/mobile/bin/answer.py?hl=en&answer=182077

千呼萬喚 - Google官方發布Android 2.3 SDK


對應Android 2.3的軟件開發工具包(Android SDK)現已推出. 此外也同時發布新的開發工具和文檔, 以及新的NDK. 欲了解更多有關新的Android 2.3, 請參考版本說明.

如果你已經安裝有Android SDK, 可以通過添加SDK component來安裝Android 2.3. 如果你還沒有, 可以安裝SDK starter package.

更多細節: Android Developers Blog - Android 2.3 Platform and Updated SDK Tools



2010年12月1日星期三

如何使用Android Debug Bridge (adb) 複製文件



如果你想複製文件到Android模擬器上的SD Card中, 可以使用Android Debug Bridge(adb)工具的push指令.

./adb push <file to be copied> /sdcard/