Git 使用記錄 (下載Git+安裝Git+設定配置姓名和Email)


1.安裝git

直接到官網下載安裝,除了 Mac/Windows 使用安裝檔(dmg/exe),其他的都用指令安裝

2.測試git

開啓終端機,輸入
git

順利的話會得到類似以下畫面的回應,代表已經安裝完成
來看看目前版本,輸入
git --version

會顯示安裝版本
3.設定個人訊息
在提交檔案之前先來設定 個人訊息 的配置,包含名字和E-mail
輸入

git config user.name "your_name"
git config user.email "your_email"

如果出現

error: could not lock config file .git/config: No such file or directory

請加入 --global

git config --global user.name "your_name"
git config --global user.email "your_email"

之後提交檔案都會使用這組個人訊息,當然想重新設定也是沒問題

可以使用 git config --list 來查看個人訊息
想要查詢指令如何使用,輸入
git help 指令

如 git help config



MacBook Pro 編譯 Android 核心


上一篇已建立並編譯 Android Source Tree ,這篇記錄 Android Kernel 的編譯

上篇提到的 Android Source Tree 並不包含 Kernel 的部分,因此當你想對 Kernel 作修改時 必須另外下載 Kernel 的部分

這篇也是照著 Google 提示的操作

先掛載 android.dmg 並移動到之前建立的 android 資料夾中,建立新資料夾(Android_KERNEL)以放置 Kernel 原始碼,如果想針對不同廠商核心編譯可以再建立方便識別的資料夾(panda)

使用 git 下載 Kernel
git clone https://android.googlesource.com/device/ti/panda

移動到 panda資料夾
cd panda
取得 commit message
git log --max-count=1 kernel
出現的訊息會類似下圖,我們需要的部分是 Built from kernel 後面那一串訊息
(cb5fc502c60be9305c5a007be335e860d9e7c0cb)
下載想編譯的kernel ,以google的例子下載 omap
$ git clone https://android.googlesource.com/kernel/common.git
$ git clone https://android.googlesource.com/kernel/exynos.git
$ git clone https://android.googlesource.com/kernel/goldfish.git
$ git clone https://android.googlesource.com/kernel/msm.git
$ git clone https://android.googlesource.com/kernel/omap.git
$ git clone https://android.googlesource.com/kernel/samsung.git
$ git clone https://android.googlesource.com/kernel/tegra.git
確認prebuilts-gcc在path中
export PATH=$(pwd)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH
編譯,其中 commit_from_first_step 填入(cb5fc502c60be9305c5a007be335e860d9e7c0cb)
$ export ARCH=arm
$ export SUBARCH=arm
$ export CROSS_COMPILE=arm-eabi-
$ cd omap
$ git checkout <commit_from_first_step>
$ make panda_defconfig
$ make



MacBook Pro 建立 Android Source Environment (不需 Ubuntu)


由於工作會轉移到 Android BSP ,先來建立環境熟悉一下,注意此篇不需建立 Ubuntu

規格: MacBook Pro (Lion) , Mac OS X 10.7 , Xcode 4.6.1

參考資料:AOSP官網




步驟直接從 Setting up Mac OS X build environment 開始即可

1.
建立 case-sensitive disk image

首先提到 Mac OS 是 case-insensitive (不區分大小寫) 但這會造成部分 git 指令的錯誤
所以建議我們製作 case-sensitive 的 disk image

你可以使用

A.launch Disk Utility and select "New Image". A size of 25GB is the minimum to complete the build, larger numbers are more future-proof. Using sparse images saves space while allowing to grow later as the need arises. Be sure to select "case sensitive, journaled" as the volume format.

或者是

B.開啓終端機,輸入以下指令
# hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg
(強烈建議指令用複製貼上)

完成後在 /User/使用者 會出現 android.dmg.sparseimage ,當掛載這個disk Image 在桌面上便會出現一個磁碟空間

預設掛載disk image後出現的磁碟空間名稱為 untitled ,可改為 android


2.
編輯 ~/.bash_profile
開啓終端機輸入

vi ~/.bash_profile

並加入以下內容
(注意 android.dmg 要看實際的名稱修改,有可能是android.dmg.sparsefile
而 /Volumes/android 中的android也是一樣,視情況修改)
# mount the android file image
function mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }

提示: 操作的步驟為先按 a 進入INSERT模式,再貼上,離開時先按esc結束編輯,再輸入:wq 儲存離開


3.
安裝需要的套件

3-1.
首先安裝 Xcode ,建議 Xcode 版本需要 3.1.4(含)以上, 到 Apple Developer Site 下載
如果已經安裝的 Xcode 版本太高(e.g. 4.x),還需要 Mac OS 10.5 SDK

Mac OS X 10.5 SDK 安裝方式為:先到這裡左邊搜尋框輸入 xcode 3.1.4 並下載,下載完成後點擊 xcode314_2809_developerdvd.dmg
接著在桌面上會出現 Xcode Tools -> Packages -> MacOSX10.5.pkg ,點擊後更改安裝位置選擇 Developer ,完成後可以看到 Developer/SDKs 中多了  MacOSX10.5.sdk

3-2.
安裝 MacPorts,這部分也是照著google的提示
先把
export PATH=/opt/local/bin:$PATH
加到 ~/.bach_profile 中
接著取得 make , git , gpg packages
開啓終端機輸入
$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg
如果系統是 MacOS 10.4,還要加入以下指令
$ POSIXLY_CORRECT=1 sudo port install bison

3-3.
為了消除 gmake 3.82 的bug, 建議安裝 gmake 3.81,
首先將以下指令加入 /opt/local/etc/macports/sources.conf 
file:///Users/Shared/dports
建立目錄
$ mkdir /Users/Shared/dports
移動到 /Users/Shared/dports 中,輸入
$ svn co --revision 50980 http://svn.macports.org/repository/macports/trunk/dports/devel/gmake/ devel/gmake/
輸入
$ portindex /Users/Shared/dports
最後安裝 gmake 3.81
$ sudo port install gmake @3.81


4.
解除 file descriptor limit
在 ~/.bash_profile 加入
# set the number of open files to be 1024
ulimit -S -n 1024


5.
下載 Android Source Tree

5-1.
安裝 Repo
開啓終端機輸入
$ mkdir ~/bin
$ PATH=~/bin:$PATH
下載 Repo
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

5-2.
初始化 Repo

先掛載步驟1.建立的disk image,接著桌面上會出現一個磁碟空間
開啓終端機輸入指令移動到該磁碟空間中並建立一個空的目錄(WORKING_DIRECTORY)
$ mkdir WORKING_DIRECTORY
$ cd WORKING_DIRECTORY
(WORKING_DIRECTORY,名稱可自取)

接著輸入初始化指令(這個是下載 master 版本,如果Mac OS 版本為10.7 強烈建議選擇)
$ repo init -u https://android.googlesource.com/platform/manifest

也可以看看別的分支版本,使用 -b 指定版本(這個是下載指定版本 android-4.0.1_r1)
$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1
在過程中會出現輸入名字和email以及顏色測試,就按照需求輸入吧
(使用 repo 指令若出現 command not found,請輸入整個路徑如 ~/bin/repo init ....)


5-3.
下載 Android Source Tree (此下載時間相當久,3m速度大概要3~4小時)
終端機輸入
$ repo sync


6.
建立和執行

6-1.
初始化環境,終端機輸入
$ source build/envsetup.sh
6-2.
選擇 Target
終端機輸入
$ lunch full-eng
可以自由選擇輸入的參數
Build nameDeviceNotes
fullemulatorfully configured with all languages, apps, input methods
full_maguromagurofull build running on Galaxy Nexus GSM/HSPA+ ("maguro")
full_pandapandafull build running on PandaBoard ("panda")
and the BUILDTYPE is one of the following:
BuildtypeUse
userlimited access; suited for production
userdebuglike "user" but with root access and debuggability; preferred for debugging
engdevelopment configuration with additional debugging tools
6-3.
編譯
終端機輸入
$ make -j4
(4代表行程數)


7.
錯誤處理
第一次編譯會出現 strnlen 錯誤,



搜尋發現 此篇 有提到解決方法
簡單的說就是修改 ./external/elfutils/config-compat-darwin.h 中的 strnlen 方法為

#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
static inline size_t strnlen (const char *__string, size_t __maxlen)
{
int len = 0;
while (__maxlen-- && *__string++)
len++;
return len;

}
#endif

修正以後重新編譯會得到第二次錯誤
這次的錯誤是在 ld: illegal text-relocoation 開始,google發現老外有一樣的錯誤,原因眾說紛紜,有人說也許跟 Android Source 版本不同有關,這次只好選擇下載master版本

使用以下指令來取得 master 版本(原先發生錯誤版本為 Android 4.0.1_r1)
$ repo init -u https://android.googlesource.com/platform/manifest
一樣重複下載...(3~4個小時)
$ repo sync
初始化
$ source build/envsetup.sh
選擇 Target
$ lunch full-eng
編譯
$ make -j4

編譯完成!!!
跑模擬器
終端機輸入
$ emulator

基本上建立環境並不難,只是步驟稍微多了點,請先注意本地端Mac OS SDK版本,還有在
下載 Android Source Tree 以及編譯的時候通常都要2~3個小時,時間的花費相當驚人@@

下一篇會介紹 MacBook Pro 編譯 Android kernel



開啟手機閃光燈(手電筒)(Camera & Camera.Parameters)


開啟閃光燈相當簡單,因為閃光燈是 Camera 類別的功能,所以必須先建立 Camera 物件再搭配 Camera.Parameters以控制 Camera 的設定,如下

   1:      Camera c;
   2:      Parameters p;
   3:      
   4:      @Override
   5:      public void onCreate(Bundle savedInstanceState) {
   6:          super.onCreate(savedInstanceState);
   7:          setContentView(R.layout.activity_main);
   8:          
   9:          c = Camera.open();
  10:   
  11:          p = c.getParameters();
  12:          p.setFlashMode(Parameters.FLASH_MODE_TORCH);
  13:          
  14:          c.setParameters(p);
  15:         
  16:      }

事實上打開閃光燈是靠著第 12 行來達成,之後的關閉閃光燈也是類似的做法

關閉(切換)閃光燈

   1:              String s = p.getFlashMode();
   2:              if(s.equals(Parameters.FLASH_MODE_TORCH)){
   3:                  p.setFlashMode(Parameters.FLASH_MODE_OFF);
   4:              }
   5:              else if(s.equals(Parameters.FLASH_MODE_OFF)){
   6:                  p.setFlashMode(Parameters.FLASH_MODE_TORCH);
   7:              }
   8:   
   9:                  c.setParameters(p);

藉由 setFlashMode 方法來切換閃光燈的開關(第 3 , 6行)

調整閃光燈強度為弱光可以使用

   1:  p.setFocusMode("macro");//調整為弱光
   2:   
   3:  p.setFocusMode("auto");//恢復正常亮度

來切換

測試結果 samsung s2 可以使用, 不過 htc incredible s 卻沒有 macro 可以使用,應該有其它的方法可以控制才對










製作狀態列的提醒內容(Notification)


狀態列在手機畫面的最上方,作用是提醒或通知使用者一些訊息,如下圖




只要使用 Notification 這個類別,你也可以製作自己的狀態列訊息,基本的程式碼如下

   1:          Intent it = new Intent(this,Table_Flow.class);
   2:          it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3:          PendingIntent pi = PendingIntent.getActivity(All_List.this, 0, it, 0);
   4:          
   5:          Notification nn = new Notification();
   6:          nn.icon = R.drawable.notpic;
   7:          nn.tickerText = "歡迎使用極簡黑記帳本!!!";
   8:          nn.defaults = Notification.DEFAULT_ALL;
   9:          nn.setLatestEventInfo(All_List.this, "極簡黑記帳本", "歡迎使用極簡黑記帳本!!!", pi);
  10:   
  11:          NotificationManager nm;
  12:          nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
  13:          nm.notify(0, nn);

第 1 行第 1 個參數為目前的類別,第 2 個參數為點選狀態列的訊息執行的類別
第 2 行設定 Flags
第 3 行設定 PendingIntent , 第 1 個參數為目前類別,第 2 個參數為 requsetcode , 第 3 個參數為 intent , 第 4 個參數為 flag
第 5 ~ 8 行就是狀態列的顯示內容
第 6 行為顯示圖形,尺寸為 30x30
第 7 行為顯示內容
第 8 行為出現訊息時的預設行為,包括手機震動,音效,指示燈
第 9 行為點選狀態列之後出現的內容
第 11 ~ 13 行發送剛剛的 Notification

上面的內容可以在應用程式離開前使用

結果為
結束應用程式後





點選狀態列





























上架 google play(android market) 的準備


1.先來做 icon 吧, Android 支援各種不同的尺寸,可以製作 96x96(x), 72x72(h), 48x48(m), 36x36(l), 4種不同尺寸的 icon 圖, 我使用 firework 來作圖, 先製作 96x96 的 icon , 之後的尺寸再調整就可以了
先製作 icon 底圖, 底圖最好小於該尺寸 10 個單位,以 96x96 為例,下面底圖最好是 86x86


 




接著就根據自己的喜好,加上圖案吧,設計完成後,再調整各個尺寸,如 72x72 的 icon 就設定為 62x62 ,接著到 專案\res\drawable-xhdpi , res\drawable-hdpi , res\drawable-mdpi , res\drawable-ldpi, 替換原先的 ic_launcher.png


2.更改應用程式名稱,到 AndroidManifest.xml 中尋找 <application 中的 android : label ,修改其內容

3.製作 apk 檔, 製作 apk 檔之前必須先製作金鑰檔,上架時上傳的 apk 必須先經過金鑰來簽名,製作金鑰檔的方式為

開啟命令提示字元 -> 輸入 keytool ,會顯示一連串可用的命令如下












接著輸入

keytool -genkey -v -keystore testkey.store -alias testkey.keystore -keyalg RSA -validity 20000
-genkey 為產生key , testkey.store 為 金鑰檔 -keyalg 為演算法, -validity 為有效日 50年(最好超過)

接下來會出現一些填資料的畫面如下














最後會產生 1 個名稱為 testkey.store 的金鑰檔,回到 eclipse,在專案上點選右鍵,



















在必要的地方填入剛剛設定的密碼















最後選擇位置















製作 apk 檔完成!!!

最後就是登入後台並上傳檔案,當然在後台還有一些資料需要設定,不過大部分都是圖案等等


如何製作上鎖功能(EditText + SharedPreferences)


上鎖功能相當簡單,基本上只需要 EditText 和 SharedPreferences(也可以使用其它的儲存類別如 fileoutputstream,SQLite) 就能完成,,不過為了操作的方便,我還加上了 button 和 textview ,基本介面如下
開鎖畫面


















輸入密碼畫面


















而程式碼的實作原理也相當簡單,為了不把主流程複雜化,我把解鎖(UnLock_Flow.java)和加鎖(Lock_Flow.java)分開成2個類別,首先在主流程開始前先判斷是否有密碼鎖,有就先進解鎖,沒有就直接開始主流程,而在主流程中會有個選項是加入密碼鎖的選擇,點選進入 Lock_Flow.java,相當簡單吧

首先在主流程中判斷的方法如下

   1:      void lock() {
   2:          // get data for accountdetail
   3:          SharedPreferences sp = getSharedPreferences("bcn", 0);
   4:   
   5:          // get accountdetail count
   6:          String passstr = sp.getString("adlock", "");
   7:          
   8:          // no lock
   9:          if(passstr.equals("")){
  10:              
  11:          }
  12:          //lock exist
  13:          else {
  14:              
  15:          //call Lock_Flow
  16:              Intent inte = new Intent();
  17:              inte.setClass(All_List.this, UnLock_Flow.class);
  18:              
  19:              startActivityForResult(inte, 3);
  20:              overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
  21:          }
  22:      }


其中 SharedPreferences 的用法請參考這篇,本篇不再多加詳述
第 9 行判斷內容是否為空,是的話代表沒有密碼鎖直接進入主流程,否的話就呼叫解鎖類別(16 ~ 20 行)

解鎖類別(UnLock_Flow.java)如下

   1:  package com.example.helloworld;
   2:   
   3:  import FoXxLib.FP;
   4:  import android.annotation.SuppressLint;
   5:  import android.app.Activity;
   6:  import android.app.AlertDialog;
   7:  import android.content.DialogInterface;
   8:  import android.content.SharedPreferences;
   9:  import android.os.Bundle;
  10:  import android.view.KeyEvent;
  11:  import android.view.View;
  12:  import android.view.View.OnClickListener;
  13:  import android.widget.Button;
  14:  import android.widget.EditText;
  15:  import android.widget.TextView;
  16:  import android.widget.Toast;
  17:   
  18:  @SuppressLint("NewApi")
  19:  public class UnLock_Flow extends Activity {
  20:   
  21:      EditText et;
  22:      Button byes;
  23:      Button bno;
  24:   
  25:      TextView tv;
  26:   
  27:      int tryNum = 2;
  28:   
  29:      public void onCreate(Bundle savedInstanceState) {
  30:          super.onCreate(savedInstanceState);
  31:   
  32:          initXml();
  33:   
  34:      }
  35:   
  36:      void initXml() {
  37:          setContentView(R.layout.unlockflow);
  38:   
  39:          tv = (TextView) findViewById(R.id.textView1);
  40:   
  41:          tv.setText("請輸入密碼解鎖");
  42:   
  43:          et = (EditText) findViewById(R.id.username_edit);
  44:          et.setHint("輸入密碼");
  45:   
  46:          byes = (Button) findViewById(R.id.buttonYes);
  47:          byes.setOnClickListener(new OnClickListener() {
  48:   
  49:              @Override
  50:              public void onClick(View v) {
  51:                  // TODO Auto-generated method stub
  52:   
  53:                  checkPassWord();
  54:              }
  55:          });
  56:   
  57:          bno = (Button) findViewById(R.id.buttonNo);
  58:          bno.setOnClickListener(new OnClickListener() {
  59:   
  60:              @Override
  61:              public void onClick(View v) {
  62:                  // TODO Auto-generated method stub
  63:   
  64:                  // use AlertDialog
  65:                  AlertDialog ad = new AlertDialog.Builder(UnLock_Flow.this,
  66:                          AlertDialog.THEME_TRADITIONAL).create();
  67:                  ad.setTitle("警告!!");// 設定警告標題
  68:                  ad.setMessage("確定離開程序??");
  69:   
  70:                  ad.setButton2("確定", new DialogInterface.OnClickListener() {// 設定按鈕2
  71:   
  72:                              @Override
  73:                              public void onClick(DialogInterface dialog,
  74:                                      int which) {
  75:   
  76:                                  // 點選按鈕2後執行的動作
  77:                                  finishEdit(1);
  78:                              }
  79:                          });
  80:                  ad.setButton("取消", new DialogInterface.OnClickListener() {// 設定按鈕2
  81:   
  82:                              @Override
  83:                              public void onClick(DialogInterface dialog,
  84:                                      int which) {
  85:   
  86:                                  // 點選按鈕2後執行的動作
  87:   
  88:                              }
  89:                          });
  90:   
  91:                  ad.setCanceledOnTouchOutside(true);// 當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
  92:   
  93:                  ad.setCancelable(true);// 當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
  94:   
  95:                  ad.show();
  96:   
  97:              }
  98:          });
  99:      }
 100:   
 101:      void checkPassWord() {
 102:   
 103:          if (et.getText() == null) {
 104:              // use Toast
 105:              tryNum--;
 106:              Toast.makeText(UnLock_Flow.this, "未輸入密碼!!!" + "還剩" + tryNum + "次",
 107:                      Toast.LENGTH_SHORT).show();
 108:   
 109:              et.setText("");
 110:          } else {
 111:   
 112:              String tempstr = et.getText().toString();
 113:   
 114:              // get data for accountdetail
 115:              SharedPreferences sp = getSharedPreferences("bcn", 0);
 116:   
 117:              // get accountdetail count
 118:              String passstr = sp.getString("adlock", "");
 119:   
 120:              if (tempstr.equals(passstr)) {
 121:                  Toast.makeText(UnLock_Flow.this, "密碼正確!!!", Toast.LENGTH_SHORT)
 122:                          .show();
 123:                  finishEdit(0);
 124:              } else {
 125:                  Toast.makeText(UnLock_Flow.this,
 126:                          "密碼錯誤!!!" + "還剩" + tryNum + "次", Toast.LENGTH_SHORT)
 127:                          .show();
 128:                  tryNum--;
 129:              }
 130:   
 131:          }
 132:   
 133:          if (tryNum < 0) {
 134:   
 135:              finishEdit(1);
 136:          }
 137:      }
 138:   
 139:      public boolean onKeyDown(int keycode, KeyEvent event) {
 140:   
 141:          FP.p("keycode:" + keycode);
 142:          FP.p("event:" + event.getAction());
 143:   
 144:          finishEdit(1);
 145:   
 146:          switch (keycode) {
 147:   
 148:          // menu key
 149:          case 82:
 150:   
 151:              break;
 152:          }
 153:   
 154:          return super.onKeyDown(keycode, event);
 155:      }
 156:   
 157:      /**
 158:       * 
 159:       * @param result
 160:       *            0 ok
 161:       */
 162:      void finishEdit(int result) {
 163:   
 164:          if (result == 0) {
 165:              UnLock_Flow.this.setResult(0);
 166:   
 167:              UnLock_Flow.this.finish();
 168:   
 169:              overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
 170:          } else if (result == 1) {
 171:   
 172:              UnLock_Flow.this.setResult(1);
 173:   
 174:              UnLock_Flow.this.finish();
 175:   
 176:          }
 177:      }
 178:   
 179:  }

其中比較重要的為 101 行的 checkPassWord() 方法,會取得 在 et 中輸入的字串內容並與 passstr 字串做比較(120行),相同則解鎖成功(finishEdit(0)),失敗則嘗試次數減少,當嘗試次數減為 0 ,那麼會直接回到主程序再結束 (finishEdit(1))

以上是解鎖的部分,接下來是上鎖的部分,在主程序中會有個按鈕,用來觸發加鎖動作,如下

   1:  //call Lock_Flow
   2:                      Intent inte = new Intent();
   3:                      inte.setClass(All_List.this, Lock_Flow.class);
   4:                      
   5:                      startActivityForResult(inte, 4);
   6:                      overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);

接著是 Lock_Flow.java的內容,必須注意在沒有上鎖的情況下,可以直接設定密碼,完成上鎖,但相反的若已經有上鎖過,則必須先輸入原先的密碼以解鎖,再上鎖,如下

   1:  package com.example.helloworld;
   2:   
   3:  import FoXxLib.FP;
   4:  import android.annotation.SuppressLint;
   5:  import android.app.Activity;
   6:  import android.app.AlertDialog;
   7:  import android.content.DialogInterface;
   8:  import android.content.SharedPreferences;
   9:  import android.os.Bundle;
  10:  import android.view.KeyEvent;
  11:  import android.view.View;
  12:  import android.view.View.OnClickListener;
  13:  import android.widget.Button;
  14:  import android.widget.EditText;
  15:  import android.widget.TextView;
  16:  import android.widget.Toast;
  17:   
  18:  @SuppressLint("NewApi")
  19:  public class Lock_Flow extends Activity{
  20:   
  21:      EditText et;
  22:      Button byes;
  23:      Button bno;
  24:      
  25:      TextView tv;
  26:      
  27:      int tryNum =2;
  28:      
  29:      //0:lock exist 1:no lock
  30:      int flow =0;
  31:      
  32:      public void onCreate(Bundle savedInstanceState){
  33:          super.onCreate(savedInstanceState);
  34:          
  35:          initXml();
  36:          
  37:      }
  38:      
  39:      void initXml(){
  40:          
  41:          setContentView(R.layout.lockflow);
  42:          
  43:          tv = (TextView)findViewById(R.id.textView1);
  44:          
  45:          // get data for accountdetail
  46:          SharedPreferences sp = getSharedPreferences("bcn", 0);
  47:   
  48:          // get accountdetail count
  49:          String passstr = sp.getString("adlock", "");
  50:          
  51:          //no lock
  52:          if(passstr.equals("")){
  53:              flow =1;
  54:              tv.setText("請輸入密碼:");
  55:          }
  56:          //lock exist
  57:          else{
  58:              flow =0;
  59:              tv.setText("請輸入原始密碼:");
  60:              
  61:          }
  62:          
  63:          et = (EditText)findViewById(R.id.username_edit);
  64:          et.setHint("輸入密碼");
  65:          
  66:          byes = (Button)findViewById(R.id.buttonYes);
  67:          byes.setOnClickListener(new OnClickListener() {
  68:              
  69:              @Override
  70:              public void onClick(View v) {
  71:                  // TODO Auto-generated method stub
  72:                  
  73:                  checkPassWord();
  74:              }
  75:          });
  76:          
  77:          
  78:          bno = (Button)findViewById(R.id.buttonNo);
  79:          bno.setOnClickListener(new OnClickListener() {
  80:              
  81:              @Override
  82:              public void onClick(View v) {
  83:                  // TODO Auto-generated method stub
  84:                  
  85:                  //use AlertDialog
  86:                  AlertDialog ad = new AlertDialog.Builder(Lock_Flow.this,AlertDialog.THEME_TRADITIONAL).create();
  87:                  ad.setTitle("警告!!");//設定警告標題
  88:                  ad.setMessage("未上鎖,確定返回程序??");
  89:                  
  90:                  ad.setButton2("確定", new DialogInterface.OnClickListener() {// 設定按鈕2
  91:   
  92:                              @Override
  93:                              public void onClick(DialogInterface dialog, int which) {
  94:   
  95:                                  // 點選按鈕2後執行的動作
  96:                                  finishEdit(1);
  97:                              }
  98:                          });
  99:                  ad.setButton("取消", new DialogInterface.OnClickListener() {// 設定按鈕2
 100:   
 101:                      @Override
 102:                      public void onClick(DialogInterface dialog, int which) {
 103:   
 104:                          // 點選按鈕2後執行的動作
 105:                          
 106:                      }
 107:                  });
 108:                  
 109:                  ad.setCanceledOnTouchOutside(true);//當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
 110:                  
 111:                  ad.setCancelable(true);//當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
 112:                  
 113:                  ad.show();
 114:                  
 115:                  
 116:                  
 117:              }
 118:          });
 119:      }
 120:      
 121:      void checkPassWord(){
 122:          
 123:          if(flow==0){
 124:              if(et.getText().toString().equals("")){
 125:                  // use Toast
 126:                  
 127:                  Toast.makeText(Lock_Flow.this, "未輸入密碼!!!"+"還剩"+tryNum+"次",Toast.LENGTH_SHORT).show();
 128:                  tryNum--;
 129:                  et.setText("");
 130:              }
 131:              else{
 132:                  
 133:                  String tempstr = et.getText().toString();
 134:                  
 135:                  // get data for accountdetail
 136:                  SharedPreferences sp = getSharedPreferences("bcn", 0);
 137:   
 138:                  // get accountdetail count
 139:                  String passstr = sp.getString("adlock","");
 140:                  
 141:                  if(tempstr.equals(passstr)){
 142:                      Toast.makeText(Lock_Flow.this, "密碼正確!!!",Toast.LENGTH_SHORT).show();
 143:                      flow =1;
 144:                      
 145:                      tv.setText("輸入新密碼:");
 146:                  }
 147:                  else{
 148:                      Toast.makeText(Lock_Flow.this, "密碼錯誤!!!"+"還剩"+tryNum+"次",Toast.LENGTH_SHORT).show();
 149:                      tryNum--;
 150:                  }
 151:                  
 152:              }
 153:              
 154:              if(tryNum<0){
 155:                  
 156:                  //use AlertDialog
 157:                  AlertDialog ad = new AlertDialog.Builder(Lock_Flow.this,AlertDialog.THEME_TRADITIONAL).create();
 158:                  ad.setTitle("更改密碼失敗!!");//設定警告標題
 159:                  ad.setMessage("原始密碼不正確");
 160:                  
 161:                  ad.setButton("返回", new DialogInterface.OnClickListener() {// 設定按鈕2
 162:   
 163:                      @Override
 164:                      public void onClick(DialogInterface dialog, int which) {
 165:                          finishEdit(0);
 166:                      }
 167:                  });
 168:                  
 169:                  ad.setCanceledOnTouchOutside(false);//當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
 170:                  
 171:                  ad.setCancelable(false);//當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
 172:                  
 173:                  ad.show();
 174:                  
 175:              }
 176:          }
 177:          else if(flow==1){
 178:              if(et.getText().toString().equals("")){
 179:                  // use Toast
 180:                  Toast.makeText(Lock_Flow.this, "未輸入密碼!!!",Toast.LENGTH_SHORT).show();
 181:                  
 182:                  et.setText("");
 183:              }
 184:              else{
 185:                  
 186:                  String tempstr = et.getText().toString();
 187:                  
 188:                  // get data for accountdetail
 189:                  SharedPreferences sp = getSharedPreferences("bcn", 0);
 190:                  SharedPreferences.Editor spe = sp.edit();
 191:                  
 192:                  spe.putString("adlock", tempstr);// for more putXXX
 193:                  spe.commit();
 194:   
 195:                  //use AlertDialog
 196:                  AlertDialog ad = new AlertDialog.Builder(Lock_Flow.this,AlertDialog.THEME_TRADITIONAL).create();
 197:                  ad.setTitle("上鎖完成!!");//設定警告標題
 198:                  ad.setMessage("密碼為"+tempstr);
 199:                  
 200:                  ad.setButton("返回", new DialogInterface.OnClickListener() {// 設定按鈕2
 201:   
 202:                      @Override
 203:                      public void onClick(DialogInterface dialog, int which) {
 204:                          finishEdit(1);
 205:                      }
 206:                  });
 207:                  
 208:                  ad.setCanceledOnTouchOutside(false);//當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
 209:                  
 210:                  ad.setCancelable(false);//當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
 211:                  
 212:                  ad.show();
 213:                  
 214:              }
 215:          }
 216:          
 217:          
 218:      }
 219:      
 220:      public boolean onKeyDown(int keycode, KeyEvent event){
 221:          
 222:          FP.p("keycode:"+keycode);
 223:          FP.p("event:"+event.getAction());
 224:          
 225:          finishEdit(1);
 226:          
 227:          switch(keycode){
 228:              
 229:          // menu key
 230:          case 82:
 231:              
 232:              break;
 233:          }
 234:          
 235:          return super.onKeyDown(keycode, event);
 236:      }
 237:      
 238:      /**
 239:       * 
 240:       * @param result 0 ok
 241:       */
 242:      void finishEdit(int result){
 243:          
 244:          if(result==0){
 245:              Lock_Flow.this.setResult(0);
 246:              
 247:              Lock_Flow.this.finish();
 248:              
 249:              overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
 250:          }
 251:          else if(result==1){
 252:              
 253:              Lock_Flow.this.setResult(1);
 254:              
 255:              Lock_Flow.this.finish();
 256:              
 257:              overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
 258:          }
 259:      }
 260:      
 261:      
 262:  }

第 30 行 flow=0代表已經有鎖, 必須先解鎖,而flow=1,代表沒有鎖,可以直接輸入密碼上鎖

結果為




















Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Affiliate Network Reviews