android程序自动升级,android应用程序自动升级功能(根据时间)

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 {

private

Handler mHandler;

@Override

public void

onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mHandler =

new Handler();

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));

if

((lastUpdateTime + (24 * 60 * 60 * 1000)) <

System.currentTimeMillis()) {

lastUpdateTime

= System.currentTimeMillis();

SharedPreferences.Editor editor =

getPreferences(0).edit();

editor.putLong("lastUpdateTime",

lastUpdateTime);

editor.commit();

// checkUpdate.start();

}

}

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.append((byte)current);

}

final

String s = new String(baf.toByteArray());

int

curVersion = getPackageManager().getPackageInfo("your.app.id",

0).versionCode;

int

newVersion = Integer.valueOf(s);

if

(newVersion > curVersion) {

mHandler.post(showUpdate);

}

} catch

(Exception e) {

}

}

};

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) {

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) {

}

})

.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文件中:

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状态下运行:blog_4a4f9fb50100sglx.html

2009-6-6 20:39 上传

查看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中的结构blog_4a4f9fb50100sglx.html

2009-6-6 20:39 上传

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值