`
jaymsimusic
  • 浏览: 94616 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

为程序添加版本自动更新功能(转)

阅读更多
OverView :
程序 通过后台每天检查是否有最新版本,如果需要更新当前版本,将弹出对话框让用户选择是否在当前通过Market来更新软件 。
Knowledge Points:

SharedPreferences: 一个轻量级的存储方法,类似于经常使用的.ini文件 ,它也是通过检索关键字来取得相应的数值。之所以是成为轻量级,是因为它所能应用 的数值类型有限,对于存储较大数值,效率相对较低。官方参考
System.currentTimeMillis:将当前时间以毫秒作为单位来表示,用于比较两个时间的先后顺序。(其数值表示从1970-01-01 00:00:00直到当前时间的总毫秒数)官方参考
通过网络 来读取信息:在checkUpdate()方法中包含了通过制定的URL来读取网络资源 。具体操作步骤,请参考源代码 。
Runnable: 在其内部的Run()方法中实现所要执行的任何代码,当这个runnable interface被调用后可以视作为新的线程。
Source Code:


public class hello extends Activity  { 
        /** Called when the activity is first created. */ 
        private Handler mHandler; 
          
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
         
        mHandler = new Handler(); 

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

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

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

            /* Start Update */ 
         //   checkUpdate.start(); 
        } 
    } 

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

                int current = 0; 
                while((current = bis.read()) != -1){ 
                     baf.app end((byte)current); 
                } 

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

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

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

    /* This Runnable creates a Dialog and asks the user to open the Market */ 
    private Runnable showUpdate = new Runnable(){ 
           public void run(){ 
            new AlertDialog.Builder(hello.this) 
            .setIcon(R.drawable.ok) 
            .setTitle("Update Available") 
            .setMessage("An update for is available!\n\nOpen Android Market and see the details?") 
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
                    public void onClick(DialogInterface dialog, int whichButton) { 
                            /* User clicked OK so do some stuff */ 
                            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market ://search?q=pname:your.app.id")); 
                            startActivity(intent); 
                    } 
            }) 
            .setNegativeButton("No", new DialogInterface.OnClickListener() { 
                    public void onClick(DialogInterface dialog, int whichButton) { 
                            /* User clicked Cancel */ 
                    } 
            }) 
            .show(); 
           } 
    }; 
   
} 



分为三个部分:

置于onCreate()方法中的程序用于判断当前时间是否需要检查更新(如果距离上次更新时间大于1天,将启动检查更新)
当以上条件满足时,启动checkUpdate来检查当前程序是否为最新版本。
如果确定版本已过期,那么将登录market,并直接指向当前程序页面。
*******************************************************************************************
向上言:
     本人在论坛 曾经发过一关于此问题的求助 帖,虽然大至的思路和上文差不多,关键点是在于程序如何更新,现在看到它这里指出的更新方法居然是登录market。不过以后发布的程序都是在market中,问题就不存在。

                         
  Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:your.app.id")); 
                            startActivity(intent); 

大家都是在eclipse上开发 吧,在每次更新代码,运行 模拟 器时,大家是否有注意到console的提示信息:

[2009-06-06 19:53:50 - Hello] Android Launch! 
[2009-06-06 19:53:50 - Hello] adb is running normally. 
[2009-06-06 19:53:50 - Hello] Performing linhai.com.hello.hello activity launch 
[2009-06-06 19:53:50 - Hello] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD 'avd' 
[2009-06-06 19:53:50 - Hello] WARNING: Application does not specify an API level requirement! 
[2009-06-06 19:53:50 - Hello] Device API version is 3 (Android 1.5) 
[2009-06-06 19:53:50 - Hello] Uploading Hello.apk onto device 'emulator-5554' 
[2009-06-06 19:53:50 - Hello] Installing Hello.apk... 
[2009-06-06 19:54:05 - Hello] Application already exists. Attempting to re-install instead... 
[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

06-06 11:54:02.567: DEBUG/PackageParser(582): Scanning package: /data/app/vmdl12464.tmp 
06-06 11:54:08.048: INFO/PackageManager(582): Removing non-system package:linhai.com.hello 
06-06 11:54:08.187: DEBUG/PackageManager(582): Removing package linhai.com.hello 
06-06 11:54:08.286: DEBUG/PackageManager(582):   Activities: linhai.com.hello.hello 
06-06 11:54:11.136: DEBUG/PackageManager(582): Scanning package linhai.com.hello 
06-06 11:54:11.301: INFO/PackageManager(582): /data/app/vmdl12464.tmp changed; unpacking 
06-06 11:54:11.626: DEBUG/installd(555): DexInv: --- BEGIN '/data/app/vmdl12464.tmp' --- 
06-06 11:54:12.987: DEBUG/dalvikvm(7756): DexOpt: load 224ms, verify 265ms, opt 1ms 
06-06 11:54:13.047: DEBUG/installd(555): DexInv: --- END '/data/app/vmdl12464.tmp' (success) --- 
06-06 11:54:13.057: DEBUG/PackageManager(582):   Activities: linhai.com.hello.hello 
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 
06-06 11:54:15.737: DEBUG/PackageManager(582): New package installed in /data/app/linhai.com.hello.apk 


关于此类的自动更新的第三方管理软件已经有了叫aTrackDog ,其原理就是使用上面的方式。
关于得到版本号,使用:

int curVersion = getPackageManager().getPackageInfo("your.app.id", 0).versionCode; 

程序版本号的是放在AndroidManifest.xml文件中:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
        package="linhai.com.hello" android:versionCode="2" android:versionName="2.0.1"> 

主点是关于:getPackageManager()在这个下面有很多方法,你可以通过它得,得到当前终端安装的程序等。关于安装包的函数是:getPackageManager().installPackage(packageURI)

动手试验:
在dos状态下运行:

查看logcat下的信息,大致和刚才相同,分析流程:

06-06 12:18:58.827: INFO/jdwp(8368): received file descriptor 20 from ADB 
06-06 12:19:02.546: DEBUG/PackageParser(582): Scanning package: /data/app/vmdl12465.tmp 
06-06 12:19:07.738: INFO/PackageManager(582): /data/app/vmdl12465.tmp changed; unpacking 
06-06 12:19:07.978: DEBUG/installd(555): DexInv: --- BEGIN '/data/app/vmdl12465.tmp' --- 
06-06 12:19:09.617: DEBUG/dalvikvm(8378): DexOpt: load 254ms, verify 564ms, opt 3ms 
06-06 12:19:09.697: DEBUG/installd(555): DexInv: --- END '/data/app/vmdl12465.tmp' (success) --- 
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 
06-06 12:19:11.956: DEBUG/PackageManager(582): New package installed in /data/app/com.example.android.snake.apk 
06-06 12:19:14.746: DEBUG/dalvikvm(8368): VM cleaning up 
06-06 12:19:14.857: DEBUG/dalvikvm(8368): LinearAlloc 0x0 used 628420 of 4194304 (14%) 
06-06 12:19:15.897: DEBUG/dalvikvm(582): GC freed 17704 objects / 903984 bytes in 615ms 
06-06 12:19:15.936: DEBUG/HomeLoaders(625): application intent received: android.intent.action.PACKAGE_ADDED, replacing=false 
06-06 12:19:15.936: DEBUG/HomeLoaders(625):   --> package:com.example.android.snake 
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中的结构

看到此文件结构,应该可以想起linux下的文件系统 和它的权限管理,也就可以理解,为什么我们的程序无法在data下创建文件之类的问题了。


分享到:
评论

相关推荐

    WPF自动更新程序

    "圣殿骑士自动更新组件"是一个开源项目,它为.NET应用程序提供了方便的自动更新机制。通过这个组件,开发者可以在WPF应用中集成自动检查更新、下载更新、安装更新等功能。对于WPF应用程序,这种组件可以极大地简化...

    C#程序自动更新

    本示例("C#程序自动更新")探讨了如何在C#应用程序中实现一个简单的自动更新功能。 首先,我们要理解自动更新的基本流程。这个过程通常包括以下几个步骤: 1. **检查更新**:应用程序启动时或用户触发时,程序会...

    C#程序自动更新 可实现自身更新

    它可能是一个库或者框架,能够集成到你的C#应用中,帮助你轻松地添加自动更新功能。通过配置XML文件,开发者可以定义更新检查的频率、更新源、更新策略等参数,以满足不同的更新需求。 XML配置文件通常包含以下内容...

    visual c++源码 自动更新(在线更新)功能

    总的来说,为Visual C++程序添加自动更新功能是一项涉及网络编程、文件操作和用户界面设计的综合任务。正确实施后,它能够帮助开发者更有效地分发更新,提高用户满意度,并保持软件的安全性和稳定性。

    自动更新最新版本程序

    标题中的“自动更新最新版本程序”是指一种软件更新机制,它允许应用程序自动检测并下载最新的程序版本,确保用户始终运行的是软件的最新、最安全、功能最完善的版本。这种机制通常用于减少用户手动检查和安装更新的...

    Delphi 开发的程序自动更新控件

    在IT行业中,开发软件时确保程序能够自动更新是一项重要的任务,因为它可以帮助用户轻松获取软件的最新功能和安全修复。在Delphi编程环境中,有多种方法可以实现程序的自动更新,其中一个便是通过使用特定的更新控件...

    Winform自动更新程序源码(支持增量更新,删除文件操作)

    2. **自动更新**:自动更新功能允许应用程序在检测到新版本时,自动下载并安装更新,无需用户手动操作。这通常通过在应用程序启动时检查服务器上的版本信息,或者在后台定期进行检查来实现。 3. **增量更新**:增量...

    java 自动程序更新

    Java自动程序更新是一种常见于软件开发中的技术,用于在应用程序运行时或后台自动检查和安装新的更新,确保软件始终保持最新状态。以下是对这个过程的详细解释: 1. **检查目录**: 检查目录是存放新版本更新包的...

    自动更新程序版本号小工具

    通过更新这个文件中的版本号,开发者可以方便地在整个项目中同步更新版本信息。 "UpdateVersion.ini"是一个配置文件,可能包含了自动更新的相关设置,如更新检查的频率、服务器URL、版本信息等。开发者可以通过修改...

    WPF自动更新程序_C#_Java_下载.zip

    综上所述,这个压缩包提供了WPF应用程序自动更新功能的实现,无论是对于学习WPF应用开发还是对于想要为自己的C#项目添加自动更新功能的开发者来说,都是很有价值的资源。通过学习和研究其中的代码,可以深入理解自动...

    PB程序自动升级,检测版本自动更新程序

    更新PBD文件可以添加新功能、修复bug或提升性能,而无需用户手动卸载和重新安装整个应用程序。 2. **自动更新程序**:这种机制允许软件在后台检查并下载最新的可用版本,然后在用户下次启动应用程序时自动安装这些...

    delphi版的自动升级程序(自动更新软件)【全绿色的】

    总的来说,Delphi版的自动升级程序是一种便捷、高效的方式,能够帮助开发者轻松地为他们的软件添加自动更新功能,确保用户始终能够获得最新、最安全的软件体验。开发者可以根据自己的需求,调整和扩展这个基础框架,...

    版本自动升级程序修补版

    版本自动升级程序是软件开发中的一个重要组成部分,它允许软件在用户端自动检查并安装最新的更新,从而保持软件的性能和安全性。"版本自动升级程序修补版"标题表明这是一个已经修复了之前版本中存在问题的新版本,这...

    FTP 自动更新小程序

    在这个自动更新小程序中,开发者可能使用了TIdFTP组件的目录列举功能获取远程服务器的文件列表,然后比较这些文件与本地硬盘的对应目录,找出新版本或已更改的文件进行下载。 自动更新过程可能包括以下步骤: 1. ...

    android app自动更新功能的实现

    本篇文章将详细介绍如何在Android应用程序中实现自动更新功能,以及相关的技术要点。 一、Google Play服务与Firebase App Distribution Google Play服务提供了方便的自动更新机制,尤其是通过Google Play商店发布...

    如何使自己的程序自动更新(在线更新).zip

    随着技术的发展,自动更新功能已成为许多应用程序的标准配置,因为它允许用户轻松获取最新的修复、改进和新特性,而无需手动下载安装。在这个主题中,我们将深入探讨如何使用Visual C++(VC++)来创建一个能实现在线...

    WinForm 程序自动更新

    当你需要创建一个WinForm程序并实现自动更新功能时,这通常涉及到客户端和服务器端的交互,以确保用户始终运行的是最新版本的软件。以下是关于"WinForm程序自动更新"的知识点详细解释: 1. **自动更新原理**: - ...

    winform版本自动升级C#

    4. **自动启动**:版本升级完成后,源码会自动启动新的应用程序实例,关闭旧版本,确保用户立即享受到更新后的功能。这个过程可能涉及进程管理和权限控制。 5. **错误处理**:在整个升级过程中,良好的错误处理机制...

    自动更新程序

    1. **检测更新**:程序会定期检查服务器上是否有新的更新版本。这可以通过HTTP或HTTPS协议访问更新服务器,获取版本信息,对比当前系统的版本号来判断是否需要更新。 2. **下载更新**:当检测到有可用更新时,程序...

Global site tag (gtag.js) - Google Analytics