Android SDK 版本號與版本名稱對照及一個編程小技巧 VERSION_CODES

前幾天,爲了解決一個問題,逆了一個小工具軟件。在這個過程發現了一些很有用的東西,在此跟大家分享一下。首先聲明幾點:1、逆出來的代碼,需要大量的人工分析,我現在只看了一點點;2、代碼不會公開,請不要向我要代碼,我怕麻煩~~~唉,做了這件壞事,內心忐~~~忑~~~啊!

一、通過編程實現對GPS的開關


  在Android手機和模擬器上有一個管理GPS開關的設置界面,如下:


    


  通過這個管理界面,我們可以對GPS進行管理,以實現我們的手機定位功能。曾經在網上搜集資料,希望找到通過代碼對GPS進行管理的源碼,也確實找到了一份代碼(稍後附上代碼),但是這份代碼在SDK 2.3及以上的版本中,始終不能運行。於是,產生了一個逆向的邪念~


  在分析上面提到的小工具之後,發現了其對GPS管理的功能模塊,經過簡單的分析之後,發現在Android SDK版本不同的情況下,對GPS控制的代碼還不一樣。首先附上在2.2版本及以前版本的GPS控制代碼:



/** * 實現了一個GPS的開關,當前關閉則打開,當前打開則關閉 * 適用版本號: * 1.6 / 2.1 / 2.2 * * Uri.parse()的參數"custom:3"中的數字3的枚舉值如下: * private static final int BUTTON_BLUETOOTH = 4; * private static final int BUTTON_BRIGHTNESS = 1; * private static final int BUTTON_GPS = 3; * private static final int BUTTON_SYNC = 2; * private static final int BUTTON_WIFI = 0; * */ private void toggleGPS() { // 當SDK版本號爲2.3以下版本時 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { Intent gpsIntent = new Intent(); gpsIntent.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); gpsIntent.addCategory("android.intent.category.ALTERNATIVE"); gpsIntent.setData(Uri.parse("custom:3")); try { PendingIntent.getBroadcast(this, 0, gpsIntent, 0).send(); } catch (CanceledException e) { e.printStackTrace(); } } }


  以上這段代碼,是利用Android平臺自帶的Widget插件對各種開關進行管理的。實現的是一個GPS的開關,如果當前GPS處於關閉狀態,則將其打開;如果GPS處於打開狀態,則將其關閉。


  大家可能已經注意到函數體內部的第一行註釋“當SDK版本號爲2.3一下版本時”,的確我們在這裏做了一個針對SDK版本的判斷。這一個判斷也是我們下一個小節要重點介紹的內容,暫時放在一邊,不要在這一節裏面跑偏了。


  在SDK 2.3及之後的版本中,那個小工具利用了SDK中的類Settings.Secure的一個靜態方法:


public static final void setLocationProviderEnabled (ContentResolver cr, String provider, boolean enabled)


Since: API Level 8


Thread-safe method for enabling or disabling a single location provider.



Parameters



cr


the content resolver to use


provider


the location provider to enable or disable


enabled


true if the provider should be enabled




  這個方法從API Level 8纔開始提供,API Level 8對應的SDK版本是2.2,OK!那按照正常情況來說,這個函數應該是支持SDK2.3的。不妨寫個函數來試試。(這個代碼比較簡單,我就不再貼代碼了)結果卻令人意外,沒有給用戶分配權限"android.permission.WRITE_SETTINGS";好嘛,那就加上權限;又提示沒有權限“android.permission.WRITE_SECURE_SETTINGS”,好說,再加上這個權限。接下來,見證悲催的時刻到了,還是提示沒有“android.permission.WRITE_SECURE_SETTINGS”的權限。明明已經加上了權限,爲何還是提示。最後也是在各種大小論壇裏面查找資料,說是在2.3版本里面,Google把這個權限完全鎖住了,好吧,悲劇了,除非你自己改Android代碼,否則就真的沒有別的辦法了。


  所以,在第一節結束的時候,提醒各位童鞋,如果想在SDK2.3版本管理GPS,還是乖乖的用你的Intent打開系統默認的管理GPS的Activity吧。


二、SDK版本對照


  爲了下載android SDK的源碼,我到處找鏈接,好不容易一個鏈接,發現文件名後面怎麼還有一個類似英文名的東西?


                


  的確,像我這樣的初學者,是不知道這個英文單詞代表什麼意思的。但是在逆代碼的過程,發現了Android API給我們提供了這樣個類android.os.Build,在這個類中定義了Android SDK每個版本的版本號,版本名,以後其他一些信息,感興趣的同學可以去開發文檔中看看。


  這裏的英文單詞,就是每個SDK版本的版本名稱。


VERSION_CODES

/** * Enumeration of the currently known SDK version codes. These are the * values that can be found in {@link VERSION#SDK}. Version numbers * increment monotonically with each official platform release. */ public static class VERSION_CODES { /** * Magic version number for a current development build, which has * not yet turned into an official release. */ public static final int CUR_DEVELOPMENT = 10000; /** * October 2008: The original, first, version of Android. Yay! */ public static final int BASE = 1; /** * February 2009: First Android update, officially called 1.1. */ public static final int BASE_1_1 = 2; /** * May 2009: Android 1.5. */ public static final int CUPCAKE = 3; /** * September 2009: Android 1.6. * * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> * <li> They must explicitly request the * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission to be * able to modify the contents of the SD card. (Apps targeting * earlier versions will always request the permission.) * <li> They must explicitly request the * {@link android.Manifest.permission#READ_PHONE_STATE} permission to be * able to be able to retrieve phone state info. (Apps targeting * earlier versions will always request the permission.) * <li> They are assumed to support different screen densities and * sizes. (Apps targeting earlier versions are assumed to only support * medium density normal size screens unless otherwise indicated). * They can still explicitly specify screen support either way with the * supports-screens manifest tag. * </ul> */ public static final int DONUT = 4; /** * November 2009: Android 2.0 * * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> * <li> The {@link android.app.Service#onStartCommand * Service.onStartCommand} function will return the new * {@link android.app.Service#START_STICKY} behavior instead of the * old compatibility {@link android.app.Service#START_STICKY_COMPATIBILITY}. * <li> The {@link android.app.Activity} class will now execute back * key presses on the key up instead of key down, to be able to detect * canceled presses from virtual keys. * <li> The {@link android.widget.TabWidget} class will use a new color scheme * for tabs. In the new scheme, the foreground tab has a medium gray background * the background tabs have a dark gray background. * </ul> */ public static final int ECLAIR = 5; /** * December 2009: Android 2.0.1 */ public static final int ECLAIR_0_1 = 6; /** * January 2010: Android 2.1 */ public static final int ECLAIR_MR1 = 7; /** * June 2010: Android 2.2 */ public static final int FROYO = 8; /** * Newest version of Android, version 2.3. */ public static final int GINGERBREAD = 9; }



  Android 1.5:Cupcake(杯子蛋糕)
  Android 1.6:Donut(甜甜圈)
  Android 2.0 / 2.1:Eclair(閃電泡芙)
  Android 2.2:Froyo(冷凍憂格)
  Android 2.3:Gingerbread(薑餅)
  Android 3.0:Honeycomb(蜂巢)


  有時候在編碼過程,的確會遇到在不同的SDK版本下,某一個功能的實現方案不一樣的情況,這時就需要大家判斷SDK的版本,採取不同的實現方案,這樣才能讓我們的App保證良好的兼容性。所以相信下面這個簡單的判斷語句對你來說,會非常有用:



if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { ...... }


  如果想對這個有一個更加深入的瞭解,建議仔細看看Class android.os.Build,開發文檔始終使我們學習的利器。


  希望以上的這些東西對大家會有用!與大家共勉!


from: http://www.byywee.com/page/M0/S527/527151.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章