2015年4月17日 星期五

Android多國語言設定 - 使用Android Studio

通常在開發Android App時,可能會需要考慮到使用者可能來自各種國家,要對不同國家的使用者產生相應的語言介面,這時就需要在「res」資源資料夾中建立相應語言、地區的設定。

下面簡單地介給在Android Studio中要如何設定多國語言,在這裡,我們設定三個語言:中文、英文、日文,以「strings.xml」為例:


  1. 在Android模式中,對「res」資料夾按右鍵,選擇「New--> Android resource file」。
  2. 在「File name」中打「strings」、「Resource type」選「Values」,在左下方的方框中將「Language」和「Region」給放到右邊方框中並選擇想要的語言(Language)和地區(Region),選好後「Directory name」中會自動產生相應的名稱,例如中文台灣為「values-zh-rTW」。

2015年4月6日 星期一

Android中觸控動作的傳遞 dispatchTouchEvent()

在Android中,MotionEvent(動作事件)是可以被傳遞的,例如你可以把事件由一個元件接收,處理過後再把它傳給另一個元件去接收,這時侯接收事件的元件會當成事件在它之中發生。

下面我們用一個簡單的例子來體會,以下程式碼的成品中有兩個方塊,小方塊的長寬皆為大方塊的一半,小方塊在大方塊的下面,當使用者在小方塊上觸控時,會移動大方塊裡的星星圖型,而移動到的位置是小方塊以等比例的方式對應到大方塊的位置。

需要注意的是,此例只是直接地由小方塊傳送觸控動作事件給大方塊,大方塊並沒有去判斷此事件是由哪裡來的,所以如果直接觸控大方塊的話,一樣可以移動其中的星星圖型。

2015年4月5日 星期日

「Intel的虛擬化技術」在ASUS UEFI BIOS中的位置

在開發Android時,常會用到虛擬機(AVD),而AVD可以使用Intel的虛擬化技術來增加效能,在於 Intel® 架構加速 Android* 模擬器這裡有詳細的介紹,要用Intel的虛擬化技術實,必須要在BIOS中設置「Virtualization Technology」選項為Enable,此選項在ASUS UEFI BIOS中放置的位置與傳統的BIOS有一點不一樣,所以在這邊特別紀錄起來。

ASUS UEFI BIOS中Intel的虛擬化技術的位置為:

進階(Advanced)-->中央處理器設定(CPU Configuration)-->Intel 虛擬化技術(Intel Virtiual Technology)

無法進入BIOS(按下del後螢幕黑屏或平常開機沒有顯示開機畫面直接進入windows)

如果在想要進入電腦的BIOS時,發現按下del或F2等BIOS進入按鍵時,螢幕出現黑屏沒反應或平常開機從來沒看過開機前置畫面就直接進入windows時,有可能是螢幕造成的問題,其實並不是沒有進入BIOS,只是螢幕沒顯示出來而己,換個螢幕可能就可以正常顯示及進入BIOS。

以我碰到的例子是,我有一台電腦使用HDMI接到一個螢幕,而又接了一條普通的VGA線到另一台電視螢幕中,結果BIOS畫面跟開機前置畫面全部跑到電視螢幕上去了,進入windows才跑到電腦螢幕上。

以下是從網路上搜到的資料:
win7无法显示BIOS,开机动画,开机等待项

視窗超出螢幕時如何移動視窗

今天發生一個非常窘的事情,就是打Android Studio打開的手機模擬器(AVD : android vertiual device)視窗太大超出螢幕,上面的選單那列完全被擋住了,無法用滑鼠去點來移動,雖然是一個小問題就也突然讓我愣了一下不知道該怎麼辦,上網查了一下才發現原來早就有好多人碰到也解決了,只是我今天才碰到,算是孤陋寡聞了,所以在這簡單地紀錄一下解決的方法:


  1. 選取超出螢幕的視窗。
  2. 用鍵盤按下 alt-space(空白鍵),會出現視窗的選單。
  3. 在選單中按下移動後,就可以用鍵盤的方向鍵或滑鼠移到想要的位置放置。
下面是一些找到的參考資料:

  1. 視窗跑到螢幕外 該怎麼辦?
  2. 視窗 超出螢幕 消失 無法移動視窗 (使用鍵盤移動視窗)

Android的手勢判斷 : GestureDetector

GestureDetctor是Android的一個手勢判斷用的類別,它讓開發者可以更容易、方便地判斷手勢的各種動作,包括有下列等等:

  1. onSingleTapUp : 按一下(按下並放開)。
  2. onLongPress : 長按(按下不放開)。
  3. onScroll : 捲動、捲動(按下移動沒有放開)。
  4. onFling :  滑動(按下移動並放開)。
  5. onShowPress : 按住(按下沒放開)。
  6. onDown : 按下。
  7. onDoubleTap : 按兩下(算一次事件)。
  8. onDoubleTapEvent : 按兩下(算兩次事件)。
  9. onSingleTapConfirmed : 確定按一下。
在這篇Android觸摸事件onScroll和onFling特別重要啊,要區分裡有對各項動作做了較為清楚的說明,也寫出了事件發生的順序及由何種動作觸發。


下面我們就寫一個簡單的程式碼來試試看各種動作的觸發狀況:

2015年4月1日 星期三

Android的動態桌布 - Wallpaper

在Android中可以製作動態桌布,動態桌布是一個類似動畫的桌布,上面可以顯示動畫,甚或可以與使用者產生互動。

下面以一個範例來實作一個簡單的動態桌布,桌布背景為黑色, 當使用者點擊或劃過桌布時,會產生藍色的圓,並且隨時間變小消失:

  1. 建立WallpaperService。動態桌布其實也是一種Service,使用的class為WallpaperService,所以我們要先建立WallpaperService類別,程式碼如下,需要注意的是,在WallpaperService裡的Engine內部類別不行在WallpaperService之外建立然後使用,必須是也內部類別的方式存在在WallpaperService中:

  2. MyWallpaperService.java:
    package com.example.administrator.wallpaperservice_example;
    
    import android.service.wallpaper.WallpaperService;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    
    public class MyWallpaperService extends WallpaperService{
        @Override
        public Engine onCreateEngine() {
            return new MyEngine();
        }
    
        //設定自訂的Engine
        class MyEngine extends Engine{
            WallpaperThread wallpaperThread;
            public MyEngine() {
                SurfaceHolder surfaceHolder = getSurfaceHolder();
                wallpaperThread = new WallpaperThread(surfaceHolder);
            }
    
            @Override
            public void onCreate(SurfaceHolder surfaceHolder) {
                super.onCreate(surfaceHolder);
                //設定動態桌布可以互動觸控事件
                setTouchEventsEnabled(true);
            }
    
            @Override
            public void onSurfaceCreated(SurfaceHolder holder) {
                super.onSurfaceCreated(holder);
                //開始執行動態桌布
                wallpaperThread.start();
            }
    
            @Override
            public void onSurfaceDestroyed(SurfaceHolder holder) {
                super.onSurfaceDestroyed(holder);
                //結束動態桌布
                wallpaperThread.stopRunning();
            }
    
            @Override
            public void onDestroy() {
                super.onDestroy();
                //讓GC回收wallpaperThread
                wallpaperThread = null;
            }
    
            @Override
            public void onTouchEvent(MotionEvent event) {
                super.onTouchEvent(event);
                //執行wallpaperThread裡的觸控事件
                wallpaperThread.doTouchEvent(event);
            }
        }
    }