在我们APP的开发中,往往都会遇到版本的升级,因为不可能有任何一个应用做的完美无缺,所以版本升级对APP应用来说是不可缺少的一部分.像新浪微博等一些应用软件,三天两头提醒我升级.不过这样也很正常,就像Android 升级一样,为了给用户提供更方便更人性化的操作.说下具体实现吧,不过我是参考别人的。不管对你们有没有帮助,总之对我有帮助啊,如果日后用到就直接copy了.哈哈,不扯了。
首先看一个文件manifest文件.
1.<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2. package="com.jj.upgrade"
3. android:versionCode="1"
4. android:versionName="1.0" >
我们可以很清楚的看到versionCode和versionName,我们一般用versionCode来实现,
实现原理很简单:服务器端有个serverVersion,我们本地有个localVersion.服务器端serverVersion>localVersion,这个时候我们就需要进行升级版本.原理大致就是这样。具体实现请看下面.
1.package com.jj.upgrade;
2.
3.import com.jj.Service.UpdateService;
4.
5.import android.app.AlertDialog;
6.import android.app.Application;
7.import android.content.DialogInterface;
8.import android.content.Intent;
9.import android.content.pm.PackageInfo;
10.import android.content.pm.PackageManager.NameNotFoundException;
11.
12./***
13. * MyApplication
14. *
15. * @author zhangjia
16. *
17. */
18.public class MyApplication extends Application {
19.
20. public static int localVersion = 0;// 本地安装版本
21.
22. public static int serverVersion = 2;// 服务器版本
23.
24. public static String downloadDir = "jj/";// 安装目录
25.
26. @Override
27. public void onCreate() {
28. super.onCreate();
29. try {
30. PackageInfo packageInfo = getApplicationContext()
31. .getPackageManager().getPackageInfo(getPackageName(), 0);
32. localVersion = packageInfo.versionCode;
33. } catch (NameNotFoundException e) {
34. e.printStackTrace();
35. }
36.
37. /***
38. * 在这里写一个方法用于请求获取服务器端的serverVersion.
39. */
40.
41. }
42.
43.}
我们一般把全局的东西放到application里面
1.public class MainActivity extends Activity {
2. private MyApplication myApplication;
3.
4. @Override
5. public void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.main);
8.
9. checkVersion();
10. }
11.
12. /***
13. * 检查是否更新版本
14. */
15. public void checkVersion() {
16. myApplication = (MyApplication) getApplication();
17. if (myApplication.localVersion < myApplication.serverVersion) {
18.
19. // 发现新版本,提示用户更新
20. AlertDialog.Builder alert = new AlertDialog.Builder(this);
21. alert.setTitle("软件升级")
22. .setMessage("发现新版本,建议立即更新使用.")
23. .setPositiveButton("更新",
24. new DialogInterface.OnClickListener() {
25. public void onClick(DialogInterface dialog,
26. int which) {
27. Intent updateIntent = new Intent(
28. MainActivity.this,
29. UpdateService.class);
30. updateIntent.putExtra(
31. "app_name",
32. getResources().getString(
33. R.string.app_name));
34. startService(updateIntent);
35. }
36. })
37. .setNegativeButton("取消",
38. new DialogInterface.OnClickListener() {
39. public void onClick(DialogInterface dialog,
40. int which) {
41. dialog.dismiss();
42. }
43. });
44. alert.create().show();
45.
46. }
47. }
48.}
我们在运行应用的时候要checkVersion();进行检查版本是否要进行升级.
最主要的是UpdateService服务类,
1.@Override
2. public int onStartCommand(Intent intent, int flags, int startId) {
3.
4. app_name = intent.getStringExtra("app_name");
5. // 创建文件
6. FileUtil.createFile(app_name);// 创建文件
7.
8. createNotification();// 首次创建
9.
10. createThread();// 线程下载
11.
12. return super.onStartCommand(intent, flags, startId);
13.
14. }
创建路径及文件,这里就不介绍了,不明白了下载源码看.
首先我们先 看createNotification().这个方法:
1./***
2. * 创建通知栏
3. */
4. RemoteViews contentView;
5. public void createNotification() {
6. notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
7. notification = new Notification();
8. notification.icon = R.drawable.ic_launcher;// 这个图标必须要设置,不然下面那个RemoteViews不起作用.
9. // 这个参数是通知提示闪出来的值.
10. notification.tickerText = "开始下载";
11. //
12. // updateIntent = new Intent(this, MainActivity.class);
13. // pendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);
14. //
15. // // 这里面的参数是通知栏view显示的内容
16. // notification.setLatestEventInfo(this, app_name, "下载:0%",
17. // pendingIntent);
18. //
19. // notificationManager.notify(notification_id, notification);
20.
21. /***
22. * 在这里我们用自定的view来显示Notification
23. */
24. contentView = new RemoteViews(getPackageName(),
25. R.layout.notification_item);
26. contentView.setTextViewText(R.id.notificationTitle, "正在下载");
27. contentView.setTextViewText(R.id.notificationPercent, "0%");
28. contentView.setProgressBar(R.id.notificationProgress, 100, 0, false);
29.
30. notification.contentView = contentView;
31.
32. updateIntent = new Intent(this, MainActivity.class);
33. updateIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
34. pendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);
35.
36. notification.contentIntent = pendingIntent;
37.
38. notificationManager.notify(notification_id, notification);
39.
40. }
上面实现的也不难理解.(主要是初始化Notification,用于提醒用户开始下载)
接着我们要看createThread方法
1./***
2. * 开线程下载
3. */
4. public void createThread() {
5. /***
6. * 更新UI
7. */
8. final Handler handler = new Handler() {
9. @Override
10. public void handleMessage(Message msg) {
11. switch (msg.what) {
12. case DOWN_OK:
13. // 下载完成,点击安装
14. Uri uri = Uri.fromFile(FileUtil.updateFile);
15. Intent intent = new Intent(Intent.ACTION_VIEW);
16. intent.setDataAndType(uri,
17. "application/vnd.android.package-archive");
18.
19. pendingIntent = PendingIntent.getActivity(
20. UpdateService.this, 0, intent, 0);
21.
22. notification.setLatestEventInfo(UpdateService.this,
23. app_name, "下载成功,点击安装", pendingIntent);
24.
25. notificationManager.notify(notification_id, notification);
26.
27. stopSelf();
28. break;
29. case DOWN_ERROR:
30. notification.setLatestEventInfo(UpdateService.this,
31. app_name, "下载失败", pendingIntent);
32. break;
33.
34. default:
35. stopSelf();
36. break;
37. }
38.
39. }
40.
41. };
42.
43. final Message message = new Message();
44.
45. new Thread(new Runnable() {
46. @Override
47. public void run() {
48.
49. try {
50. long downloadSize = downloadUpdateFile(down_url,
51. FileUtil.updateFile.toString());
52. if (downloadSize > 0) {
53. // 下载成功
54. message.what = DOWN_OK;
55. handler.sendMessage(message);
56. }
57.
58. } catch (Exception e) {
59. e.printStackTrace();
60. message.what = DOWN_ERROR;
61. handler.sendMessage(message);
62. }
63.
64. }
65. }).start();
66. }
这个方法有点小多,不过我想大家都看的明白,我在这里简单说名一下:首先我们创建一个handler用于检测最后下载ok还是not ok.
下面我们开启了线程进行下载数据。
我们接着看downloadUpdateFile这个方法:
1./***
2. * 下载文件
3. *
4. * @return
5. * @throws MalformedURLException
6. */
7. public long downloadUpdateFile(String down_url, String file)
8. throws Exception {
9. int down_step = 5;// 提示step
10. int totalSize;// 文件总大小
11. int downloadCount = 0;// 已经下载好的大小
12. int updateCount = 0;// 已经上传的文件大小
13. InputStream inputStream;
14. OutputStream outputStream;
15.
16. URL url = new URL(down_url);
17. HttpURLConnection httpURLConnection = (HttpURLConnection) url
18. .openConnection();
19. httpURLConnection.setConnectTimeout(TIMEOUT);
20. httpURLConnection.setReadTimeout(TIMEOUT);
21. // 获取下载文件的size
22. totalSize = httpURLConnection.getContentLength();
23. if (httpURLConnection.getResponseCode() == 404) {
24. throw new Exception("fail!");
25. }
26. inputStream = httpURLConnection.getInputStream();
27. outputStream = new FileOutputStream(file, false);// 文件存在则覆盖掉
28. byte buffer[] = new byte[1024];
29. int readsize = 0;
30. while ((readsize = inputStream.read(buffer)) != -1) {
31. outputStream.write(buffer, 0, readsize);
32. downloadCount += readsize;// 时时获取下载到的大小
33. /**
34. * 每次增张5%
35. */
36. if (updateCount == 0
37. || (downloadCount * 100 / totalSize - down_step) >= updateCount) {
38. updateCount += down_step;
39. // 改变通知栏
40. // notification.setLatestEventInfo(this, "正在下载...", updateCount
41. // + "%" + "", pendingIntent);
42. contentView.setTextViewText(R.id.notificationPercent,
43. updateCount + "%");
44. contentView.setProgressBar(R.id.notificationProgress, 100,
45. updateCount, false);
46. // show_view
47. notificationManager.notify(notification_id, notification);
48.
49. }
50.
51. }
52. if (httpURLConnection != null) {
53. httpURLConnection.disconnect();
54. }
55. inputStream.close();
56. outputStream.close();
57.
58. return downloadCount;
59.
60. }
注释已经写的很详细,相信大家都看的明白,如果哪里有不足的地方,请留您吉言指出.
这里我用别的app代替了,简单省事,正常的话,你要对你的APP进行数字签名.然后才可以进行升级应用.
示意图:
提示有新版 开始升级 升级下载中 下载完毕,点击安装
原文链接:http://www.linuxidc.com/Linux/2012-09/69774.htm