小菜毛毛技術(shù)分享

          與大家共同成長(zhǎng)

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks
          OverView:
          程序通過后臺(tái)每天檢查是否有最新版本,如果需要更新當(dāng)前版本,將彈出對(duì)話框讓用戶選擇是否在當(dāng)前通過Market來更新軟件
          Knowledge Points:
          • SharedPreferences: 一個(gè)輕量級(jí)的存儲(chǔ)方法,類似于經(jīng)常使用的.ini文件,它也是通過檢索關(guān)鍵字來取得相應(yīng)的數(shù)值。之所以是成為輕量級(jí),是因?yàn)樗?span class="t_tag">應(yīng)用的數(shù)值類型有限,對(duì)于存儲(chǔ)較大數(shù)值,效率相對(duì)較低。官方參考
          • System.currentTimeMillis:將當(dāng)前時(shí)間以毫秒作為單位來表示,用于比較兩個(gè)時(shí)間的先后順序。(其數(shù)值表示從1970-01-01 00:00:00直到當(dāng)前時(shí)間的總毫秒數(shù))官方參考
          • 通過網(wǎng)絡(luò)來讀取信息:在checkUpdate()方法中包含了通過制定的URL來讀取網(wǎng)絡(luò)資源。具體操作步驟,請(qǐng)參考源代碼
          • Runnable: 在其內(nèi)部的Run()方法中實(shí)現(xiàn)所要執(zhí)行的任何代碼,當(dāng)這個(gè)runnable interface被調(diào)用后可以視作為新的線程。
          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. }
          復(fù)制代碼


          分為三個(gè)部分:
          • 置于onCreate()方法中的程序用于判斷當(dāng)前時(shí)間是否需要檢查更新(如果距離上次更新時(shí)間大于1天,將啟動(dòng)檢查更新)
          • 當(dāng)以上條件滿足時(shí),啟動(dòng)checkUpdate來檢查當(dāng)前程序是否為最新版本。
          • 如果確定版本已過期,那么將登錄market,并直接指向當(dāng)前程序頁(yè)面。
          *******************************************************************************************
          向上言:
               本人在論壇曾經(jīng)發(fā)過一關(guān)于此問題的求助帖,雖然大至的思路和上文差不多,關(guān)鍵點(diǎn)是在于程序如何更新,現(xiàn)在看到它這里指出的更新方法居然是登錄market。不過以后發(fā)布的程序都是在market中,問題就不存在。
          1.                             Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:your.app.id"));
          2.                             startActivity(intent);
          復(fù)制代碼
          大家都是在eclipse上開發(fā)吧,在每次更新代碼,運(yùn)行模擬器時(shí),大家是否有注意到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!
          復(fù)制代碼
          分析:
          1。android正常運(yùn)行
          2。通過配置文件AndroidManifest.xml中運(yùn)行我們的程序
          3。Uploading Hello.apk onto device 'emulator-5554'這句是關(guān)鍵,更新我們的程序
          4。Installing Hello.apk...
          5。Application already exists. Attempting to re-install instead...//程序已經(jīng)存在,嘗試重新安裝

          所以如果我們的程序要自動(dòng)更新,本人初步猜想是和上面的步驟是一樣的。
          詳看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
          復(fù)制代碼
          關(guān)于此類的自動(dòng)更新的第三方管理軟件已經(jīng)有了叫aTrackDog,其原理就是使用上面的方式。
          關(guān)于得到版本號(hào),使用:
          1. int curVersion = getPackageManager().getPackageInfo("your.app.id", 0).versionCode;
          復(fù)制代碼
          程序版本號(hào)的是放在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">
          復(fù)制代碼
          主點(diǎn)是關(guān)于:getPackageManager()在這個(gè)下面有很多方法,你可以通過它得,得到當(dāng)前終端安裝的程序等。關(guān)于安裝包的函數(shù)是:getPackageManager().installPackage(packageURI)

          動(dòng)手試驗(yàn):
          在dos狀態(tài)下運(yùn)行:
          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
          復(fù)制代碼
          1。接收數(shù)據(jù),保存到臨時(shí)文件中/data/app/vmdl12465.tmp
          2。解壓此文件,注意路徑/data/dalvik-cache/data@app@vmdl12465.tmp@classes.dex
          它是在data下的dalvik-cache下
          3.安裝文件[這個(gè)步驟還包括查找程序是否已經(jīng)安裝等]
          4.使用GC清理內(nèi)存

          查看DDMS中的結(jié)構(gòu)
          2.JPG
          看到此文件結(jié)構(gòu),應(yīng)該可以想起linux下的文件系統(tǒng)和它的權(quán)限管理,也就可以理解,為什么我們的程序無法在data下創(chuàng)建文件之類的問題了。
          轉(zhuǎn)載:http://www.androidres.com/?p=349
          posted on 2010-11-23 11:07 小菜毛毛 閱讀(401) 評(píng)論(0)  編輯  收藏 所屬分類: andriod
          主站蜘蛛池模板: 罗平县| 嘉峪关市| 蓬莱市| 时尚| 漯河市| 洪湖市| 峨眉山市| 东方市| 托里县| 宁海县| 临海市| 论坛| 涞水县| 乐陵市| 兴国县| 乐安县| 建湖县| 大同县| 康乐县| 余庆县| 十堰市| 西乌珠穆沁旗| 罗源县| 苍南县| 白银市| 金昌市| 恩施市| 新田县| 开鲁县| 白沙| 沂南县| 石景山区| 乌审旗| 神农架林区| 寿光市| 汕头市| 青神县| 山阳县| 华亭县| 城步| 景宁|