小菜毛毛技術分享

          與大家共同成長

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks

          #

          從零開始Android游戲編程
          五子棋源碼
          Read RSS on OPhone
          俄羅斯方塊
          空戰游戲1945
          加速傳感器演示
          演示如何使用Location和Google Map
          個股寶典
          連連看
          策略游戲——回到戰國 android源代碼
          滾屏動作游戲——太空保衛戰 android源代碼
          冒險游戲——勝利大逃亡 android源代碼
          體育游戲——瘋狂足球 android源代碼 附件
          水波效應android源碼
          Android 下3D賽車游戲
          掃雷游戲,android源碼,有注解
          MP3切割器
          Android國際象棋源碼
          旅行記錄軟件源碼
          DroidReader 源碼
          Android下的VOIP客戶端源碼
          Android下的FTP服務器源碼
          Android下俄羅斯方塊源碼
          posted @ 2010-12-03 12:39 小菜毛毛 閱讀(527) | 評論 (0)編輯 收藏

               摘要: 轉自:http://blog.csdn.net/Android_Tutor/archive/2010/04/20/5508615.aspx 今天我們的教程是根據前面一節擴展進行的,如果你沒有看,請點擊 Android高手進階教程(三) 查看第三課,這樣跟容易方便你的理解! 在xml 文件里定義控件的屬性,我們已經習慣了android:attrs="" ,那么我們能不能定...  閱讀全文
          posted @ 2010-11-23 15:22 小菜毛毛 閱讀(428) | 評論 (0)編輯 收藏

               摘要: 轉自:http://blog.csdn.net/Android_Tutor/archive/2010/04/21/5513869.aspx 大家好我們這一節講的是LayoutInflater的使用,在實際開發種LayoutInflater這個類還是非常有用的,它的作用類似于 findViewById(), 不同點是LayoutInflater是用來找layout下xml布局文件,并且實例化...  閱讀全文
          posted @ 2010-11-23 15:20 小菜毛毛 閱讀(366) | 評論 (0)編輯 收藏

          OverView:
          程序通過后臺每天檢查是否有最新版本,如果需要更新當前版本,將彈出對話框讓用戶選擇是否在當前通過Market來更新軟件
          Knowledge Points:
          • SharedPreferences: 一個輕量級的存儲方法,類似于經常使用的.ini文件,它也是通過檢索關鍵字來取得相應的數值。之所以是成為輕量級,是因為它所能應用的數值類型有限,對于存儲較大數值,效率相對較低。官方參考
          • System.currentTimeMillis:將當前時間以毫秒作為單位來表示,用于比較兩個時間的先后順序。(其數值表示從1970-01-01 00:00:00直到當前時間的總毫秒數)官方參考
          • 通過網絡來讀取信息:在checkUpdate()方法中包含了通過制定的URL來讀取網絡資源。具體操作步驟,請參考源代碼
          • Runnable: 在其內部的Run()方法中實現所要執行的任何代碼,當這個runnable interface被調用后可以視作為新的線程。
          Source Code:
          1. public class hello extends Activity  {
          2.         /** Called when the activity is first created. */
          3.         private Handler mHandler;
          4.          
          5.     @Override
          6.     public void onCreate(Bundle savedInstanceState) {
          7.         super.onCreate(savedInstanceState);
          8.         setContentView(R.layout.main);
          9.         
          10.         mHandler = new Handler();

          11.         /* Get Last Update Time from Preferences */
          12.         SharedPreferences prefs = getPreferences(0);
          13.         long lastUpdateTime =  prefs.getLong("lastUpdateTime", System.currentTimeMillis());

          14.         int curVersion = 0;
          15.                 try {
          16.                         curVersion = getPackageManager().getPackageInfo("linhai.com.hello", 0).versionCode;
          17.                 } catch (NameNotFoundException e) {
          18.                         // TODO Auto-generated catch block
          19.                         e.printStackTrace();
          20.                 }
          21.         Log.i("DEMO",String.valueOf(curVersion));
          22.         /* Should Activity Check for Updates Now? */
          23.         if ((lastUpdateTime + (24 * 60 * 60 * 1000)) < System.currentTimeMillis()) {

          24.             /* Save current timestamp for next Check*/
          25.            lastUpdateTime = System.currentTimeMillis();
          26.             SharedPreferences.Editor editor = getPreferences(0).edit();
          27.             editor.putLong("lastUpdateTime", lastUpdateTime);
          28.             editor.commit();      

          29.             /* Start Update */
          30.          //   checkUpdate.start();
          31.         }
          32.     }

          33.     /* This Thread checks for Updates in the Background */
          34.     private Thread checkUpdate = new Thread()
          35.     {
          36.         public void run() {
          37.             try {
          38.                 URL updateURL = new URL("http://my.company.com/update");
          39.                 URLConnection conn = updateURL.openConnection();
          40.                 InputStream is = conn.getInputStream();
          41.                 BufferedInputStream bis = new BufferedInputStream(is);
          42.                 ByteArrayBuffer baf = new ByteArrayBuffer(50);

          43.                 int current = 0;
          44.                 while((current = bis.read()) != -1){
          45.                      baf.append((byte)current);
          46.                 }

          47.                 /* Convert the Bytes read to a String. */
          48.                 final String s = new String(baf.toByteArray());        

          49.                 /* Get current Version Number */
          50.                 int curVersion = getPackageManager().getPackageInfo("your.app.id", 0).versionCode;
          51.                 int newVersion = Integer.valueOf(s);

          52.                 /* Is a higher version than the current already out? */
          53.                 if (newVersion > curVersion) {
          54.                     /* Post a Handler for the UI to pick up and open the Dialog */
          55.                     mHandler.post(showUpdate);
          56.                 }
          57.             } catch (Exception e) {
          58.             }
          59.         }
          60.     };

          61.     /* This Runnable creates a Dialog and asks the user to open the Market */
          62.     private Runnable showUpdate = new Runnable(){
          63.            public void run(){
          64.             new AlertDialog.Builder(hello.this)
          65.             .setIcon(R.drawable.ok)
          66.             .setTitle("Update Available")
          67.             .setMessage("An update for is available!\n\nOpen Android Market and see the details?")
          68.             .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
          69.                     public void onClick(DialogInterface dialog, int whichButton) {
          70.                             /* User clicked OK so do some stuff */
          71.                             Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:your.app.id"));
          72.                             startActivity(intent);
          73.                     }
          74.             })
          75.             .setNegativeButton("No", new DialogInterface.OnClickListener() {
          76.                     public void onClick(DialogInterface dialog, int whichButton) {
          77.                             /* User clicked Cancel */
          78.                     }
          79.             })
          80.             .show();
          81.            }
          82.     };
          83.   
          84. }
          復制代碼


          分為三個部分:
          • 置于onCreate()方法中的程序用于判斷當前時間是否需要檢查更新(如果距離上次更新時間大于1天,將啟動檢查更新)
          • 當以上條件滿足時,啟動checkUpdate來檢查當前程序是否為最新版本。
          • 如果確定版本已過期,那么將登錄market,并直接指向當前程序頁面。
          *******************************************************************************************
          向上言:
               本人在論壇曾經發過一關于此問題的求助帖,雖然大至的思路和上文差不多,關鍵點是在于程序如何更新,現在看到它這里指出的更新方法居然是登錄market。不過以后發布的程序都是在market中,問題就不存在。
          1.                             Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:your.app.id"));
          2.                             startActivity(intent);
          復制代碼
          大家都是在eclipse上開發吧,在每次更新代碼,運行模擬器時,大家是否有注意到console的提示信息:
          1. [2009-06-06 19:53:50 - Hello] Android Launch!
          2. [2009-06-06 19:53:50 - Hello] adb is running normally.
          3. [2009-06-06 19:53:50 - Hello] Performing linhai.com.hello.hello activity launch
          4. [2009-06-06 19:53:50 - Hello] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD 'avd'
          5. [2009-06-06 19:53:50 - Hello] WARNING: Application does not specify an API level requirement!
          6. [2009-06-06 19:53:50 - Hello] Device API version is 3 (Android 1.5)
          7. [2009-06-06 19:53:50 - Hello] Uploading Hello.apk onto device 'emulator-5554'
          8. [2009-06-06 19:53:50 - Hello] Installing Hello.apk...
          9. [2009-06-06 19:54:05 - Hello] Application already exists. Attempting to re-install instead...
          10. [2009-06-06 19:54:31 - Hello] Success!
          復制代碼
          分析:
          1。android正常運行
          2。通過配置文件AndroidManifest.xml中運行我們的程序
          3。Uploading Hello.apk onto device 'emulator-5554'這句是關鍵,更新我們的程序
          4。Installing Hello.apk...
          5。Application already exists. Attempting to re-install instead...//程序已經存在,嘗試重新安裝

          所以如果我們的程序要自動更新,本人初步猜想是和上面的步驟是一樣的。
          詳看logcat中的log
          1. 06-06 11:54:02.567: DEBUG/PackageParser(582): Scanning package: /data/app/vmdl12464.tmp
          2. 06-06 11:54:08.048: INFO/PackageManager(582): Removing non-system package:linhai.com.hello
          3. 06-06 11:54:08.187: DEBUG/PackageManager(582): Removing package linhai.com.hello
          4. 06-06 11:54:08.286: DEBUG/PackageManager(582):   Activities: linhai.com.hello.hello
          5. 06-06 11:54:11.136: DEBUG/PackageManager(582): Scanning package linhai.com.hello
          6. 06-06 11:54:11.301: INFO/PackageManager(582): /data/app/vmdl12464.tmp changed; unpacking
          7. 06-06 11:54:11.626: DEBUG/installd(555): DexInv: --- BEGIN '/data/app/vmdl12464.tmp' ---
          8. 06-06 11:54:12.987: DEBUG/dalvikvm(7756): DexOpt: load 224ms, verify 265ms, opt 1ms
          9. 06-06 11:54:13.047: DEBUG/installd(555): DexInv: --- END '/data/app/vmdl12464.tmp' (success) ---
          10. 06-06 11:54:13.057: DEBUG/PackageManager(582):   Activities: linhai.com.hello.hello
          11. 06-06 11:54:15.608: INFO/installd(555): move /data/dalvik-cache/data@app@vmdl12464.tmp@classes.dex -> /data/dalvik-cache/data@app@linhai.com.hello.apk@classes.dex
          12. 06-06 11:54:15.737: DEBUG/PackageManager(582): New package installed in /data/app/linhai.com.hello.apk
          復制代碼
          關于此類的自動更新的第三方管理軟件已經有了叫aTrackDog,其原理就是使用上面的方式。
          關于得到版本號,使用:
          1. int curVersion = getPackageManager().getPackageInfo("your.app.id", 0).versionCode;
          復制代碼
          程序版本號的是放在AndroidManifest.xml文件中:
          1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          2.         package="linhai.com.hello" android:versionCode="2" android:versionName="2.0.1">
          復制代碼
          主點是關于:getPackageManager()在這個下面有很多方法,你可以通過它得,得到當前終端安裝的程序等。關于安裝包的函數是:getPackageManager().installPackage(packageURI)

          動手試驗:
          在dos狀態下運行:
          1.JPG
          查看logcat下的信息,大致和剛才相同,分析流程:
          1. 06-06 12:18:58.827: INFO/jdwp(8368): received file descriptor 20 from ADB
          2. 06-06 12:19:02.546: DEBUG/PackageParser(582): Scanning package: /data/app/vmdl12465.tmp
          3. 06-06 12:19:07.738: INFO/PackageManager(582): /data/app/vmdl12465.tmp changed; unpacking
          4. 06-06 12:19:07.978: DEBUG/installd(555): DexInv: --- BEGIN '/data/app/vmdl12465.tmp' ---
          5. 06-06 12:19:09.617: DEBUG/dalvikvm(8378): DexOpt: load 254ms, verify 564ms, opt 3ms
          6. 06-06 12:19:09.697: DEBUG/installd(555): DexInv: --- END '/data/app/vmdl12465.tmp' (success) ---
          7. 06-06 12:19:11.907: INFO/installd(555): move /data/dalvik-cache/data@app@vmdl12465.tmp@classes.dex -> /data/dalvik-cache/data@app@com.example.android.snake.apk@classes.dex
          8. 06-06 12:19:11.956: DEBUG/PackageManager(582): New package installed in /data/app/com.example.android.snake.apk
          9. 06-06 12:19:14.746: DEBUG/dalvikvm(8368): VM cleaning up
          10. 06-06 12:19:14.857: DEBUG/dalvikvm(8368): LinearAlloc 0x0 used 628420 of 4194304 (14%)
          11. 06-06 12:19:15.897: DEBUG/dalvikvm(582): GC freed 17704 objects / 903984 bytes in 615ms
          12. 06-06 12:19:15.936: DEBUG/HomeLoaders(625): application intent received: android.intent.action.PACKAGE_ADDED, replacing=false
          13. 06-06 12:19:15.936: DEBUG/HomeLoaders(625):   --> package:com.example.android.snake
          14. 06-06 12:19:15.936: DEBUG/HomeLoaders(625):   --> add package
          復制代碼
          1。接收數據,保存到臨時文件中/data/app/vmdl12465.tmp
          2。解壓此文件,注意路徑/data/dalvik-cache/data@app@vmdl12465.tmp@classes.dex
          它是在data下的dalvik-cache下
          3.安裝文件[這個步驟還包括查找程序是否已經安裝等]
          4.使用GC清理內存

          查看DDMS中的結構
          2.JPG
          看到此文件結構,應該可以想起linux下的文件系統和它的權限管理,也就可以理解,為什么我們的程序無法在data下創建文件之類的問題了。
          轉載:http://www.androidres.com/?p=349
          posted @ 2010-11-23 11:07 小菜毛毛 閱讀(392) | 評論 (0)編輯 收藏

          ndroid中,你的應用程序程序與View類組件有著一種固定的聯系,例如按鈕(Button)文本框(TextView), 可編輯文本框(EditText), 列表框(ListView), 復選框(CheckBox), 單選框(RadioButton), 滾動條(Gallery), 微調器(Spinner), 等等,還有一些比較先進的有著特殊用途的View組件,例如 AutoCompleteTextView, ImageSwitcherTextSwitcher。除此之外,種類繁多的像 線性布局(LinearLayout), 框架布局(FrameLayout), 這樣的布局組件(Layout)也被認為是View組件,他們是從View類派生過來的。

          你的應用程序就是這些控制組件和布局組件以某種方式結合顯示在屏幕上,一般來說這些組件對你來說基本夠用,但是你也應該知道你是可以通過類繼承創建 屬于自己的組件,一般可以繼承像View、Layouts(布局組件)這樣的組件,甚至可以是一些比較高級的控制類組件。下面我們說一下為什么要繼承:

          • 你可以為實現某種功能創建一個完全自定義風格的組件,例如用二維的圖形創建控制組件實現聲音的控制,就像電子控制一樣。
          • 你可以把幾種組件結合形成一個新的組件,你的組件可能同時包含ComboBox(一個能輸入的文本列表)和dual-pane selector control(左右兩個List窗口,你可以分配窗口每一項的從屬關系)等等。
          • 你可以創建自己的布局組件(Layout)。SDK中的布局組件已經提供了一系列的選項讓你打造屬于自己的應用程序,但是高級的開發人員會發現根據現有的Layout組件開發新的Layout組件是很有必要的,甚至是完全從底層開發新的組件。
          • 你可以覆蓋一個現有組件的顯示或功能。例如,改變EditText(可編輯文本)組件在屏幕上的顯示方式(可以參考Notepad的例子,里面教你如何創建一個下劃線的顯示頁面)。
          • 你可以捕獲像按鍵按下這樣的事件,以一些通用的方法來處理這些事件(一個游戲的例子)。

          為了實現某種目標你可能很有必要擴展一個已經存在的View組件,下面我們結合一些例子教你如何去做。

          內容:

          基本方法(The Basic Approach )
          完全自定義組件(Fully Customized Components )
          定制組件的例子(Customized Component Example )
          組件的混合(或者控制類的混合) (Compound Components (or Compound Controls) )
          修改現有組件(Tweaking an Existing Component )
          小結(Go Forth and Componentize )

          基本方法(The Basic Approach )

          下面的一些步驟都比較概括,教你如何創建自己的組件:

          1. 讓你的類(Class)繼承一個現有的View 類或View的子類。
          2. 重載父類的一些方法:需要重載的父類方法一般以‘on’開頭,如onDraw(), onMeasure()onKeyDown()等等。
            • 這個在Activity 或則 ListActivity 派生中同樣適用,你需要重載一些生命周期函數和一些其他功能性的HOOK函數。
          3. 使用你的繼承類:一旦你的繼承類創建完成,你可以在基類能夠使用的地方使用你的繼承類,但完成功能就是你自己編寫的了。

          繼承類能夠定義在activities里面,這樣你能夠方便的調用,但是這并不是必要的(或許在你的應用程序中你希望創建一個所有人都可以使用的組件)。

          完全自定義組件(Fully Customized Components)

          完全自定義組件的方法可以創建一些用于顯示的圖形組件(graphical components),也許是一個像電壓表的圖形計量器,或者想卡拉OK里面顯示歌詞的小球隨著音樂滾動。無論那種方式,你也不能單純的利用組件的結合完成,無論你怎么結合這些現有的組件。

          幸運的是,你可以以你自己的要求輕松地創建完全屬于自己的組件,你會發現不夠用的只是你的想象力、屏幕的尺寸和處理器的性能(記住你的應用程序最后只會在那些性能低于桌面電腦的平臺上面運行)。

          下面簡單介紹如何打造完全自定義的組件:

          1. 最為通用的VIEW類的父類毫無疑問是View類,因此,最開始你要創建一個基于此類的一個子類。
          2. 你可以寫一個構造函數從XML文件中提取屬性和參數,當然你也可以自己定義這些屬性和參數(也許是圖形計量器的顏色和尺寸,或者是指針的寬度和幅度等等)
          3. 你可能有必要寫自己的事件監聽器,屬性的訪問和修改函數和一些組件本身的功能上的代碼。
          4. 如果你希望組件能夠顯示什么東西,你很有可能會重載 onMeasure() 函數,因而你就不得不重載 onDraw() 函數。當兩個函數都用默認的,那么 onDraw() 函數將不會做任何事情,并且默認的 onMeasure() 函數自動的設置了一個100x100 —的尺寸,這個尺寸可能并不是你想要的。
          5. 其他有必要重載的on... 系列函數都需要重新寫一次。

          onDraw()onMeasure()

          onDraw()函數將會傳給你一個 Canvas 對象,通過它你可以在二維圖形上做任何事情,包括其他的一些標準和通用的組件、文本的格式,任何你可以想到的東西都可以通過它實現。

          注意: 這里不包括三維圖形如果你想使用三維的圖形,你應該把你的父類由View改為SurfaceView類,并且用一個單獨的線程。可以參考GLSurfaceViewActivity 的例子。

          onMeasure() 函數有點棘手,因為這個函數是體現組件和容器交互的關鍵部分,onMeasure()應該重載,讓它能夠有效而準確的表現它所包含部分的測量值。這就有點復雜了,因為我們不但要考慮父類的限制(通過onMeasure()傳過來的),同時我們應該知道一旦測量寬度和高度出來后,就要立即調用setMeasuredDimension() 方法。

          概括的來講,執行onMeasure()函數分為一下幾個階段:

          1. 重載的onMeasure()方法會被調用,高度和寬度參數同時也會涉及到(widthMeasureSpecheighMeasureSpec兩個參數都是整數類型),同時你應該考慮你產品的尺寸限制。這里詳細的內容可以參考View.onMeasure(int, int) (這個連接內容詳細的解釋了整個measurement操作)。
          2. 你的組件要通過onMeasure()計算得到必要的measurement長度和寬度從而來顯示你的組件,它應該與規格保持一致,盡管它可以實現一些規格以外的功能(在這個例子里,父類能夠選擇做什么,包括剪切、滑動、提交異常或者用不同的參數又一次調用onMeasure()函數)。
          3. 一旦高度和寬度計算出來之后,必須調用setMeasuredDimension(int width, int height),否則就會導致異常。

          一個自定義組件的例子(A Customized Component Example)

          API Demos 中的CustomView提供了以一個自定義組件的例子,這個自定義組件在 LabelView 類中定義。

          LabelView例子涉及到了自定義組件的方方面面:

          • 首先讓自定義組件從View類中派生出來。
          • 編寫帶參數的構造函數(參數可以來源于XML文件)。這里面的一些處理都已經在View父類中完成,但是任然有些Labelview使用的自定義組件特有的新的參數需要處理。
          • 一些標準的Public函數,例如setText(), setTextSize(), setTextColor()
          • 重載onMeasure()方法來確定組件的尺寸(注意:在LabelView中是通過一個私有函數measureWidth()來實現的)
          • 重載onDraw()函數把Lable顯示在提供的canvas上。

          在例子中,你可以通過custom_view_1.xml看到自定義組件LabelView的用法。在XML文件中特別要注意的是android:app:兩個參數的混合運用,app:參數表示應用程序中被認為是LabelView組件的個體,這些也會作為資源在R類中定義。

          組件混合技術Compound Components (or Compound Controls)

          如果你不想創建一個完全自定義的組件,而是由幾個現有組件的組合產生的新的組件,那么混合組件技術就更加適合。簡單的來 說,這樣把幾個現有的組件融合到一個邏輯組合里面可以封裝成一個新的組件。例如,一個Combo Box組件可以看作是是一個EditText和一個帶有彈出列表的Button組件的混合體。如果你點擊按鈕為列表選擇一項,

          在Android中,其實還有其他的兩個View類可以做到類似的效果: SpinnerAutoCompleteTextView,,但是Combo Box作為一個例子更容易讓人理解。

          下面簡單的介紹如何創建組合組件:

          1. 一般從Layout類開始,創建一個Layout類的派生類。也許在Combo box我們會選擇水平方向的LinearLayout作為父類。記住,其他的Layout類是可以嵌套到里面的,因此混合組件可以是任何組件的混合。注 意,正如Activity一樣,你既可以使用外部XML文件來聲明你的組件,也可以嵌套在代碼中。
          2. 在新的混合組件的構造函數中,首先,調用所有的父類的構造函數,傳入對應的參數。然后可以設置你的混合組件的其他的一些方面,在哪創建 EditText組件,又在哪創建PopupList組件。注意:你同時也可以在XML文件中引入一些自己的屬性和參數,這些屬性和參數也可以被你的混合 組件所使用。
          3. 你也可以創建時間監聽器去監聽新組件中View類觸發的事件,例如,對List選項單擊事件的監聽,你必須在此時間發生后更新你EditText的值。
          4. 你可能創建自己的一些屬性,帶有訪問和修改方法。例如,允許設置EditText初始值并且提供訪問它的方法。
          5. 在Layout的派生類中,你沒有必要去重載onDraw()onMeasure()方法,因為Layout會有比較好的默認處理。但是,如果你覺得有必要你也可以重載它。
          6. 你也可能重載一些on系列函數,例如通過onKeyDown()的重載,你可以通過按某個鍵去選擇列表中的對應的值。

          總之,把Layout類作為基類有下面幾個優點:

          • 正如activity一樣,你也可以通過XML文件去聲明你的新組件,或者你也可以在代碼中嵌套。
          • onDraw()函數和onMeasure()函數是沒有必要重載的,兩個函數已經做得很好了。
          • 你可以很快的創建你的混合組件,并且可以像單一組件那樣使用。

          混合組件的例子(Examples of Compound Controls)

          In the API Demos project 在API Demos工程中,有兩個List類的例子——Example 4和Example 6,里面的SpeechView組件是從LinearLayout類派生過來,實現顯示演講顯示功能,對應的原代碼是List4.javaList6.java

          調整現有組件(Tweaking an Existing Component)

          在某些情況下,你可能有更簡單的方法去創建你的組件。如果你應經有了一個非常類似的組件,你所要做的只是簡單的從這個組件派生出你的組件,重在其中 一些有必要修改的方法。通過完全自定義組件的方法你也可以同樣的實現,但通過沖View派生產生新的組件,你可以簡單獲取一些已經存在的處理機制,這些很 可能是你所想要的,而沒有必要從頭開始。

          例如,在SDK中有一個NotePad的例子(NotePad application )。該例子演示了很多Android平臺實用的細節,例如你會學到從EditView派生出能夠自動換行的記事本。這還不是一個完美的例子,因為相比早期的版本來說,這些API已經感變了很多,但它確實說明了一些問題。

          如果你還未查看該程序,現在你就可以在Eclipse中導入記事本例程(或僅通過提供的鏈接查看相應的源代碼)。特別是查看NoteEditor.java 中的MyEditText的定義。

          下面有幾點要注意的地方:

          1. 聲明(The Definition)

            這個類是通過下面一行代碼來定義的:

            public static class MyEditText extends EditText

            • 它是定義在NoteEditor activity類里面的,但是它是共有的(public),因此如果有必要,它可以通過NoteEditor.MyEditTextNoteEditor外面來調用。
            • 它是static類(靜態類),意味著不會出現所謂的通過父類訪問數據的“虛態方法”, 這樣就使該類成為一個可以不嚴重依賴NoteEditor的單獨類。對于不需要從外部類訪問的內聯類的創建,這是一個很清晰地思路,保證所產生的類很小,并且允許它可以被其他的類方便的調用。
            • 它是EditText類的擴展,它是我們選擇的用來自定義的父類。當我們完成以后,新的類就可以作為一個普通的EditText來使用。
          2. 類的初始化

            一般來說,父類是首先調用的。進一步來說,這不是一個默認的構造函數,而是一個帶參數的構造函數。因為EditText是使用從XML布局文件提取出來的參數進行創建,因此我們的構造函數也要取出參數并且將這些參數傳遞給父類。

          3. 方法重載

            在本例中,僅對onDraw()一個方法進行重載。但你可以很容易地為你的定制組件重載其他需要的方法。

            對于記事本例子來說,通過重載onDraw()方法我們可以在EidtView的畫布(canvas)上繪制藍色的線條(canvas類是通過重寫的onDraw()方法傳遞)。該函數快要結束時要調用super.onDraw()函數。父類的方法是應該調用,但是在這個例子里面,我們是在我們劃好了藍線之后調用的。

          4. 使用定制組件

            現在,我們已經有自己定制的組件了,但是應該怎樣使用它呢?在記事本例子中,定制的組件直接在預定義的布局文件中使用,讓我們看一看res/layout目錄中的note_editor.xml文件。

            <view xmlns:android="http://schemas.android.com/apk/res/android" 
            class="com.android.notepad.NoteEditor$MyEditText"
            id="@+id/note"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:drawable/empty"
            android:padding="10dip"
            android:scrollbars="vertical"
            android:fadingEdge="vertical" />
            • 該自定義組件在XML中是作為一個一般的View類來創建的,并且是通過全路徑包來描述的。注意這里內聯類是通過NoteEditor$MyEditText來表示的,這是Java編程中引用內聯類的標準方法。
            • 在定義中的其他屬性和參數將傳遞給定制組件的構造函數,然后才傳到EditText構造函數中,因此這些參數也是你使用EditText組件的參數。注意,這里你也可以增加你自己的參數,我們將在下面討論這個問題。

          這就是你全部需要做的,誠然這是一個簡單的例子。但問題的關鍵是:你的需求有多復雜,那么你的自定義組件就有多么復雜。

          一個更為復雜的組件可能需要重載更多的on系列函數,并且還要很多特有的函數來充分實現自定義組件的功能。唯一的限制就是你的想象力和你需要組件去執行什么工作。

          現在開始你的組件化之旅吧

          如你所見,Android提供了一種精巧而又強大的組件模型,讓你盡可能的完成你的工作。從簡單的組件調整到組件混合,甚至完全自定義組件,靈活的運用這些技術,你應該可以得到一個完全符合你外觀要求的的Android程序 

          posted @ 2010-11-23 10:19 小菜毛毛 閱讀(369) | 評論 (0)編輯 收藏

          http://apphu.com/androidmarket

          APP虎大講堂:
          android market就是程序應用商店。在2008年8月29日,谷歌推出了Android Market,為使用Android操作系統的手機用戶提供第三方應用。

          這個平臺相似于Apple的App Store,可以連接最新的Google在線 服務器。由于其本土化的設計,Android Market可以讓用戶下載和安裝支持Android系統的第三方軟件。

          Google作為Android Market的東道主,卻一再強調Android Market的扮演的角色僅僅是“軟件銷售和傳播的中心”而不是“軟件過濾器”。

          為什么Google選擇 android market 而不是Store?

          Google選擇“’Market’”這個詞而不是“Store”,是因為其覺得開發者需要的是一個開放的、毫無阻礙的環境來創造內容。Google希望 Android Market最終會像YouTube那樣,只需要注冊一個發行人資格和軟件的類別就可以發布軟件。
          Google并沒有表示會對android market進行監管,只是表示Android Market里的軟件將擁有反饋系統以及類似YouTube上的等級系統。Google 將通過追蹤工具獲得軟件的反饋,如果某個軟件有危險性,將會有標識提醒用戶注意。但是其中的隱私問題卻在前不久的SMobile 的分析報告>中顯露無疑,而且普通用戶很難注意到有些軟件會侵犯他們的隱私,況且讓谷歌android手機用戶去辨別生澀的專業名詞,實在太強人所難了。

          Android Market學習了App Store開創的軟件銷售模式,對iPhone以及App Store是一個沖擊;更重要的一方面是 Google選擇的Market模式與蘋果的App Store之間的差異會逐漸顯現出來。

          國內三大類android market知多少

          自從android在中國大大的火了一把之后,android market也如雨后春筍般的不斷涌現出來。總的來說android market有如下幾類:
          第一類: 谷歌創建的android market
          谷歌android market,只此一家,別無其他官方market。

          第二類: 國內有頭有臉的手機廠商和移動運營商創建的android market

          • MOTO的智件園:
            摩托羅拉也是通過去年轉型生產一系列android手機,才著實大賺了一把,流轉了不利局面,倒是Nokia遲緩的反應速度讓其市場份額半年幾乎損失過 半,雖然只在英國占有主導地位,可以在美國的市場份額遠不及iphone和android手機,MOTO的Milestone更是讓其重新站上歷史的舞 臺。不甘于被谷歌android market 控制的摩托羅拉自然在尋出路,建造自己的android market
          • 中移動的Mobile Market
          • 中移動的MM簡單來說是在android1.0/android1.5的基礎上改良版的android系統,雖然當時可以跑動大部分android 軟件,但是這個market仍處于不慍不火的狀態。不過不久前,中國移動在原來版本的基礎上進行了許多創新和改進,推出的OPhone2,0,還完全兼容 Android2.1,甚至三星“奧斯卡I7680”也搭載了OMS系統。目前MM已經初具規模,中國移動Mobile Market擁有16400款應用。

          • 聯通的UniStore
          • 聯通應用商店(UniStore)已經完成了漫長的“內測階段”,將于7月中旬正式發布,該應用商店在支付模式上將采用“中間賬戶”的模式,用戶注 冊聯通應用商店時會自動注冊“中間賬戶”,便可綁定話費支付或者支付寶、財付通等第三方支付工具。據悉,聯通應用商店將采用開放平臺的模式,也就是說不僅 支持中國聯通手機用戶使用,也支持中國移動和中國電信的手機用戶使用,目前僅有775款。

          • 中國電信的天翼軟件工廠
          • 中國電信的天翼空間更是時刻處在升級狀態,雖然使出渾身解數,也仍然難見起色,天翼空間擁有1054款

          • 酷派的Android Coolmart為了支撐新機器的上市,宇龍酷派也正在進行著Android Coolmart的招兵買馬中。

          第三類: 獨立第三方創建的android market

          雖然可用的谷歌android市場越來越多,但是同質化越來越嚴重的Market只能讓用戶無所適從,也無法產生類似App Store一樣的用戶黏性。怎么樣教育用戶用自家的market是最大的問題,讓我們期待中國的android市場是如何演繹他們自己的故事。當然APP 虎的軟件在各類市場都可以通過搜索APPhu下載。

          posted @ 2010-11-22 17:41 小菜毛毛 閱讀(338) | 評論 (0)編輯 收藏

          http://www.iteeyan.com/2010/07/play-android-app-on-emulator/

          前幾天,Jackeroo給大家介紹了一個Android模擬器,可以讓大家在PC機上玩Android 2.2。不過,該模擬器中少了一個精華的東西,那就是“Android Market(電子市場)”。目前,iPhone手機玩的是操控感、時尚,而Android手機玩的則是軟件,少了“Android Market”的Android模擬器,無異于自廢了一半的功力……

          其實,要想在Android 2.2模擬器中使用“Android Market(電子市場)”,認真說來還是有點麻煩。網上雖然也有地方介紹過,但很多細節部分語焉不詳。Jackeroo就以自己的實戰操作,幫助大家溫習一下。

          Step 01 新建Android 2.2虛擬機

          首先,安裝Android SDK,新建一臺Android 2.2虛擬機。不知道該去哪里下載Android SDK或者不清楚該如何使用虛擬機的朋友,請先閱讀“Google手機免費玩·在PC上裝Android 2.2”博文。

          PlayAndroidAppOnEmulator 01 393x500 PC上試玩Android Market

          Step 02 命令行方式啟動新建虛擬機

          把SDK包下的System.img文件(F:\android-sdk-windows\platforms\android-8\images)拷貝到的%UserProfile%\.android\avd\Android-2.2下。

          然后打開命令行窗口,切換到SDK包的Tools目錄下,加參數“-partition-size 96”啟動虛擬機,才能讓/system有足夠的空間安裝“Android Market(電子市場)”。

          cd /d f:\android-sdk-windows\tools

          emulator.exe -avd Android-2.2 -partition-size 96

          PlayAndroidAppOnEmulator 02 500x326 PC上試玩Android Market

          Step 03 讓Android啟動Checkin服務

          要正常使用“Android Market(電子市場)”,必須啟動Checkin服務。等Android 2.2虛擬機啟動完畢,看到正常的界面。

          PlayAndroidAppOnEmulator 03 500x354 PC上試玩Android Market

          這時候,我們可以把配置文件build.prop取回來編輯(如果你有真實的Android連在電腦上,一定要先取下來再進行以下操作)。

          cd /d f:\android-sdk-windows\tools

          adb pull /system/build.prop .

          PlayAndroidAppOnEmulator 04 500x326 PC上試玩Android Market

          注意:第一次執行adb指令,會加載adb相關服務,然后提示“device offline(設備不在線)”。此時,需要再次執行上面的adb指令就可以了。

          這樣一來,build.prop就放在了f:\android-sdk-windows\tools目錄下,用文本編輯軟件比如EmEditor、UltraEdit之類的打開它。將“ro.config.nocheckin=yes”前面加“#”號注釋掉。

          #ro.config.nocheckin=yes

          然后再傳到Android虛擬機上,重新啟動虛擬機,Checkin服務就啟動了(在上傳之前,需要執行“adb remount”指令使/system目錄可寫)。

          adb remount
          adb push build.prop /system/build.prop

          PlayAndroidAppOnEmulator 05 500x326 PC上試玩Android Market

          Step 04 安裝“Android  Market”到虛擬機

          首先,下載一個為各種手機開發的定制版Android 2.2,比如Jackeroo曾經用過的Android 2.2 for HTC。將它解壓縮,將system/app/GoogleServicesFramework.apk 和system/app/Vending.apk放到f:\android-sdk-windows\tools下。

          Android 2.2 for Legend :遠程下載

          然后執行以下指令安裝這兩個apk安裝包,并且刪除Android虛擬機上的SdkSetup.apk(注意大小寫):

          adb push GoogleServicesFramework.apk /system/app
          adb push Vending.apk /system/app
          adb shell rm /system/app/SdkSetup.apk

          PlayAndroidAppOnEmulator 06 500x326 PC上試玩Android Market

          Step 05 清理現場

          關閉虛擬機, 把產生的 image: userdata-qemu.img, userdata.img, cache.img都刪除,重新啟動虛擬機它就會自動初始化。

          Step 06 “Android Market”現身

          打開SDK Setup.exe,按照常規方式啟動剛才新創建的Android 2.2虛擬機,就可以看到“Android Market”。

          PlayAndroidAppOnEmulator 07 500x354 PC上試玩Android Market

          點擊“Market”,就需要進行Google登錄了,用你自己的Google賬號登錄吧。

          PlayAndroidAppOnEmulator 08 500x354 PC上試玩Android Market

          登錄以后,理論上說就可以使用“Android Market(電子市場)”嘗試各種軟件了,但由于網絡無法連接,暫時還搜索不到。

          有連接上的朋友,請告訴我解決方法。 

          posted @ 2010-11-22 16:56 小菜毛毛 閱讀(601) | 評論 (0)編輯 收藏

          http://dev.10086.cn/cmdn/bbs/thread-17136-1-1.html

          最近看論壇上有人問如何掛斷電話,實際上1.1版本后.Google已經把該API隱藏掉
          今天看資料,發現可以通過AIDL(Android遠程方法)及反射,調用hide API,廢話不多說了.附上過程

          一:在你的項目中新建包com.android.internal.telephony,因為要使用AIDL,該包與ITelephony.aidl一致
              在該包下新建文件ITelephony.aidl

          首先

          package com.android.internal.telephony;
          /* * Copyright (C) 2007 The Android Open Source Project
          * * Licensed under the Apache License, Version 2.0 (the "License");
          * you may not use this file except in compliance with the License.
          * You may obtain a copy of the License at
          * * [url=http://www.apache.org/licenses/LICENSE-2.0]http://www.apache.org/licenses/LICENSE-2.0[/url]
          * * Unless required by applicable law or agreed to in writing, software
          * distributed under the License is distributed on an "AS IS" BASIS,
          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          * See the License for the specific language governing permissions and
          * limitations under the License.
          */
          /**
          * Interface used to interact with the phone. Mostly this is used by the
          * TelephonyManager class. A few places are still using this directly.
          * Please clean them up if possible and use TelephonyManager insteadl.
          * * {@hide}
          */
          interface ITelephony {
          /** * End call or go to the Home screen *
          * @return whether it hung up
          */
          boolean endCall();
          /** * Answer the currently-ringing call.
          * * If there's already a current active call, that call will be
          * automatically put on hold. If both lines are currently in use, the
          * current active call will be ended. *
          * TODO: provide a flag to let the caller specify what policy to use
          * if both lines are in use. (The current behavior is hardwired to
          * "answer incoming, end ongoing", which is how the CALL button
          * is specced to behave.) *
          * TODO: this should be a oneway call (especially since it's called
          * directly from the key queue thread). */
          void answerRingingCall();
          }   
           
          之后會在gen下面自動生成ITelephony.java
          二.通過反射生成ITelephony實例
          TelephonyManager telMgr = (TelephonyManager)getSystemService(
          TELEPHONY_SERVICE);
          //初始化iTelephony
          Class <TelephonyManager> c = TelephonyManager.class;
          Method getITelephonyMethod = null;
          try {
                 getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);
                 getITelephonyMethod.setAccessible(true);
          } catch (SecurityException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          } catch (NoSuchMethodException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          }
          try {
                  iTelephony = (ITelephony) getITelephonyMethod.invoke(telMgr, (Object[])null);
          } catch (IllegalArgumentException e) {
          // TODO Auto-generated catch block
                e.printStackTrace();
          } catch (IllegalAccessException e) {
          // TODO Auto-generated catch block
                e.printStackTrace();
          } catch (InvocationTargetException e) {
          // TODO Auto-generated catch block
                e.printStackTrace();
          }
          這樣可以調用iTelephony的endCall()方法
          三.在AndroidManifest.xml中增加權限
            <uses-permission android:name="android.permission.CALL_PHONE"/>
          posted @ 2010-11-22 16:11 小菜毛毛 閱讀(1021) | 評論 (0)編輯 收藏

               摘要: http://blog.csdn.net/maxleng/archive/2010/04/15/5490770.aspx IPC框架分析 Binder,Service,Service manager   我首先從宏觀的角度觀察Binder,Service,Service Manager,并闡述各自的概念。從Linux的概念空間中,Android的設計Acti...  閱讀全文
          posted @ 2010-11-21 21:13 小菜毛毛 閱讀(955) | 評論 (0)編輯 收藏

               摘要: 建立AIDL服務的步驟(3) (4)編寫一個MyService類,代碼如下: package net.blogjava.mobile.complex.type.aidl;     import java.util.HashMap;   import java.util.Map; &nb...  閱讀全文
          posted @ 2010-11-19 17:09 小菜毛毛 閱讀(274) | 評論 (0)編輯 收藏

          僅列出標題
          共17頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 Last 
          主站蜘蛛池模板: 滦南县| 北流市| 密山市| 安乡县| 句容市| 葵青区| 靖西县| 鹿泉市| 屏山县| 莆田市| 会理县| 高阳县| 辽中县| 明溪县| 肥西县| 普陀区| 嘉兴市| 临江市| 论坛| 惠安县| 昌图县| 原平市| 竹北市| 株洲市| 木兰县| 汾阳市| 德保县| 永新县| 达尔| 保靖县| 奇台县| 长沙县| 石河子市| 三明市| 佛冈县| 兰州市| 肃宁县| 旬阳县| 湘潭县| 鲁甸县| 大埔区|