`

Android版本更新(Service下载 Notification进度条)

阅读更多

功能:版本更新、文件后台下载以及Notification显示进度条。

效果图:

主要代码:

package com.ljp.download;
 
import java.io.File;
 
import android.app.ActivityGroup;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
 
import com.ljp.download.service.AppUpgradeService;
import com.ljp.version.R;
 
public class MainActivity extends ActivityGroup {
 
    private Button button1;
 
    private String mDownloadUrl = "http://gdown.baidu.com/data/wisegame/ba226d3cf2cfc97b/baiduyinyue_4920.apk";
    private String apkUpdateMsg = "1.内容1\n2.内容2\n3.内容3";
    private Dialog updateVersionDialog;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_main);
        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }
    private void showDialog() {
        updateVersionDialog = new AlertDialog.Builder(MainActivity.this).setTitle("有新版本需要更新").setMessage(apkUpdateMsg)
                .setPositiveButton("现在更新", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        downLoadApk();
                    }
                }).setNegativeButton("以后再说", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                }).create();
        updateVersionDialog.show();
 
    }
 
    /**
     * 文件下载
     */
    private void downLoadApk() {
        Intent intent = new Intent(MainActivity.this, AppUpgradeService.class);
        intent.putExtra("mDownloadUrl", mDownloadUrl);
        startService(intent);
        updateVersionDialog.dismiss();
    }
 
 
}

 

package com.ljp.download.service;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
 
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;
 
import com.ljp.download.DownloadUtils;
import com.ljp.download.MainActivity;
import com.ljp.version.R;
/**
 * 程序版本更新Service
 * @author yingjun10627
 *
 */
public class AppUpgradeService extends Service {
    private NotificationManager mNotificationManager = null;
    private Notification mNotification = null;
    private PendingIntent mPendingIntent = null;
 
    private String mDownloadUrl;
    private File destDir = null;
    private File destFile = null;
 
    public static final String downloadPath = "/winner";
    public static final int mNotificationId = 111;
    private static final int DOWNLOAD_FAIL = -1;
    private static final int DOWNLOAD_SUCCESS = 0;
 
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case DOWNLOAD_SUCCESS:
                Toast.makeText(getApplicationContext(), "下载成功", Toast.LENGTH_LONG).show();
                install(destFile);
                mNotificationManager.cancel(mNotificationId);
                break;
            case DOWNLOAD_FAIL:
                Toast.makeText(getApplicationContext(), "下载失败", Toast.LENGTH_LONG).show();
                mNotificationManager.cancel(mNotificationId);
                break;
            default:
                break;
            }
        }
 
    };
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent==null){
             stopSelf();
             return super.onStartCommand(intent, flags, startId);
        }
        mDownloadUrl = intent.getStringExtra("mDownloadUrl");
        if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
            destDir = new File(Environment.getExternalStorageDirectory().getPath() + downloadPath);
            if (destDir.exists()) {
                File destFile = new File(destDir.getPath() + "/" + URLEncoder.encode(mDownloadUrl));
                if (destFile.exists() && destFile.isFile() && checkApkFile(destFile.getPath())) {
                    install(destFile);
                    stopSelf();
                    return super.onStartCommand(intent, flags, startId);
                }
            }
        } else {
            return super.onStartCommand(intent, flags, startId);
        }
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mNotification = new Notification();
        Intent completingIntent = new Intent();
        completingIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        completingIntent.setClass(getApplicationContext(), AppUpgradeService.class);
        // 创建Notifcation对象,设置图标,提示文字,策略
        mPendingIntent = PendingIntent.getActivity(AppUpgradeService.this, R.string.app_name, completingIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        mNotification.icon = R.drawable.ic_launcher;
        mNotification.tickerText = "开始下载";
        mNotification.contentIntent = mPendingIntent;
 
        mNotification.contentView = new RemoteViews(getPackageName(), R.layout.app_upgrade_notification);
        mNotification.contentView.setProgressBar(R.id.app_upgrade_progressbar, 100, 0, false);
        mNotification.contentView.setTextViewText(R.id.app_upgrade_title, "正在下载...");
        mNotification.contentView.setTextViewText(R.id.app_upgrade_text, "当前进度:0%");
        mNotificationManager.cancel(mNotificationId);
        mNotificationManager.notify(mNotificationId, mNotification);
        new AppUpgradeThread().start();
        return  super.onStartCommand(intent, flags, startId);
 
    }
 
     
    /**
     * 用于监听文件下载
     */
    private DownloadUtils.DownloadListener downloadListener = new DownloadUtils.DownloadListener() {
        @Override
        public void downloading(int progress) {
            System.out.println(progress);
            mNotification.contentView.setProgressBar(R.id.app_upgrade_progressbar, 100, progress, false);
            mNotification.contentView.setTextViewText(R.id.app_upgrade_text, "当前进度:" + progress + "%");
            mNotificationManager.notify(mNotificationId, mNotification);
        }
 
        @Override
        public void downloaded() {
            mNotification.contentView.setViewVisibility(R.id.app_upgrade_progressbar, View.GONE);
            mNotification.defaults = Notification.DEFAULT_SOUND;
            mNotification.contentIntent = mPendingIntent;
            mNotification.contentView.setTextViewText(R.id.app_upgrade_title, "下载完成");
            mNotificationManager.notify(mNotificationId, mNotification);
            if (destFile.exists() && destFile.isFile() && checkApkFile(destFile.getPath())) {
                Message msg = mHandler.obtainMessage();
                msg.what = DOWNLOAD_SUCCESS;
                mHandler.sendMessage(msg);
            }
            mNotificationManager.cancel(mNotificationId);
        }
    };
 
    /**
     * 用于文件下载线程
     * @author yingjun10627
     *
     */
    class AppUpgradeThread extends Thread {
        @Override
        public void run() {
            if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
                if (destDir == null) {
                    destDir = new File(Environment.getExternalStorageDirectory().getPath() + downloadPath);
                }
                if (destDir.exists() || destDir.mkdirs()) {
                    destFile = new File(destDir.getPath() + "/" + URLEncoder.encode(mDownloadUrl));
                    if (destFile.exists() && destFile.isFile() && checkApkFile(destFile.getPath())) {
                        install(destFile);
                    } else {
                        try {
                            DownloadUtils.download(mDownloadUrl, destFile, false, downloadListener);
                        } catch (Exception e) {
                            Message msg = mHandler.obtainMessage();
                            msg.what = DOWNLOAD_FAIL;
                            mHandler.sendMessage(msg);
                            e.printStackTrace();
                        }
                    }
                }
            }
            stopSelf();
        }
    }
 
    /**
     * apk文件安装
     * 
     * @param apkFile
     */
    public void install(File apkFile) {
        Uri uri = Uri.fromFile(apkFile);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        startActivity(intent);
    }
 
    /**
     * 判断文件是否完整
     * 
     * @param apkFilePath
     * @return
     */
    public boolean checkApkFile(String apkFilePath) {
        boolean result = false;
        try {
            PackageManager pManager = getPackageManager();
            PackageInfo pInfo = pManager.getPackageArchiveInfo(apkFilePath, PackageManager.GET_ACTIVITIES);
            if (pInfo == null) {
                result = false;
            } else {
                result = true;
            }
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        }
        return result;
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
 
}

 

package com.ljp.download;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
 
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
 
public class DownloadUtils {
    private static final int CONNECT_TIMEOUT = 10000;
    private static final int DATA_TIMEOUT = 40000;
    private final static int DATA_BUFFER = 8192;
 
     
     
    public interface DownloadListener {
        public void downloading(int progress);
        public void downloaded();
    }
 
    public static long download(String urlStr, File dest, boolean append, DownloadListener downloadListener) throws Exception {
        int downloadProgress = 0;
        long remoteSize = 0;
        int currentSize = 0;
        long totalSize = -1;
 
        if (!append && dest.exists() && dest.isFile()) {
            dest.delete();
        }
 
        if (append && dest.exists() && dest.exists()) {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(dest);
                currentSize = fis.available();
            } catch (IOException e) {
                throw e;
            } finally {
                if (fis != null) {
                    fis.close();
                }
            }
        }
 
        HttpGet request = new HttpGet(urlStr);
 
        if (currentSize > 0) {
            request.addHeader("RANGE", "bytes=" + currentSize + "-");
        }
 
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params, CONNECT_TIMEOUT);
        HttpConnectionParams.setSoTimeout(params, DATA_TIMEOUT);
        HttpClient httpClient = new DefaultHttpClient(params);
 
        InputStream is = null;
        FileOutputStream os = null;
        try {
            HttpResponse response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                is = response.getEntity().getContent();
                remoteSize = response.getEntity().getContentLength();
                Header contentEncoding = response.getFirstHeader("Content-Encoding");
                if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
                    is = new GZIPInputStream(is);
                }
                os = new FileOutputStream(dest, append);
                byte buffer[] = new byte[DATA_BUFFER];
                int readSize = 0;
                int temp=0;
                while ((readSize = is.read(buffer)) > 0) {
                    os.write(buffer, 0, readSize);
                    os.flush();
                    totalSize += readSize;
                    if (downloadListener != null) {
                        downloadProgress = (int) (totalSize * 100 / remoteSize);
                        if(downloadProgress>=temp){
                           temp++;
                           downloadListener.downloading(downloadProgress);
                        }
                    }
                }
                if (totalSize < 0) {
                    totalSize = 0;
                }
            }
        } finally {
            if (os != null) {
                os.close();
            }
            if (is != null) {
                is.close();
            }
        }
 
        if (totalSize < 0) {
            throw new Exception("Download file fail: " + urlStr);
        }
 
        if (downloadListener != null) {
            downloadListener.downloaded();
        }
 
        return totalSize;
    }
}

 

Service启动方式说明:

 

START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

 

START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

 

START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

 

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

 

  • 大小: 44.5 KB
分享到:
评论

相关推荐

    android实现Service后台下载Notification进度条

    本教程将详细讲解如何在Android中使用Service进行后台下载,并实时更新Notification的进度条。 首先,我们需要创建一个Service,通常继承自`IntentService`。`IntentService`是一个单线程的Service,自动管理工作...

    Notification中更新进度条

    "Notification中更新进度条"这个主题聚焦于如何在Notification上动态地显示任务的进度,比如下载、上传等操作。 首先,我们要了解`Notification`的基本结构。在Android中,`Notification`对象由`NotificationCompat...

    Android 自定义通知栏 更新通知栏进度条

    本文将深入探讨如何实现一个自定义的通知栏,以动态更新进度条来模拟下载过程。虽然这里并不涉及实际的下载逻辑,但我们会讨论如何创建一个能够展示进度的自定义通知。 首先,我们需要理解Android的通知系统。在...

    Android Notification更新

    在Android系统中,Notification是应用与用户交互的重要方式之一,特别是在后台运行时,它能将信息传达给用户,如消息提醒、下载进度等。本文将深入探讨如何利用Android的Notification API来实现动态下载过程的可视化...

    带有进度条的APP下载更新

    "带有进度条的APP下载更新"这一主题,聚焦于如何在应用程序中实现这样一个功能,使得用户在等待下载或更新过程中能清晰地看到进度,并通过通知(notification)来方便地管理和启动安装过程。 首先,我们需要理解APP...

    android通知栏常用方法以及进度条显示

    在Android开发中,通知栏(Notification)是一种向用户传达应用状态和信息的重要方式,而进度条(Progress Bar)则是展示任务执行进度的关键组件。本文将深入探讨如何在Android通知栏中使用常见方法以及如何显示...

    Android Service 实现下载,前台、通知栏同步更新

    本教程将详细介绍如何使用Android Service来实现文件下载,并在前台显示进度,同时通过通知栏同步更新下载进度。 首先,我们需要创建一个服务类(Service)来处理下载任务。在Android Studio中,可以通过右键点击...

    用服务更新软件的安装包配合notification更新进度条

    "用服务更新软件的安装包配合notification更新进度条" 这一主题主要涉及到如何在后台执行文件下载,并通过服务(Service)来监控下载进度,同时利用Notification向用户反馈下载状态。以下是对这一主题的详细阐述: ...

    Android 下载 Notification通知栏显示

    综上所述,解决"Android 2.3版本Notification通知栏不显示的Bug"需要正确创建和更新Notification,同时结合Service和断点续传技术来实现后台下载。通过多线程下载,可以进一步提升用户体验。注意在不同Android版本上...

    下载的进度条功能实现的Demo

    这个“下载的进度条功能实现的Demo”就是针对这一需求的具体实现,它允许开发者在Android的通知栏展示一个动态更新的进度条,让用户能够实时了解后台任务的进展。 首先,我们要理解Android的通知系统。Android的...

    安卓进度条loadingprogress相关-Android多文件下载进度条.rar

    7. **通知栏更新**: 可以结合`Notification`,在通知栏显示下载进度,这样用户可以在不打开应用的情况下监控下载状态。 8. **线程同步**: 为了确保数据一致性,需要正确处理线程间的同步,例如在更新UI进度时使用`...

    Android高级应用源码-app更新,实现service下载.zip

    本示例“Android高级应用源码-app更新,实现service下载.zip”提供了一个使用服务(Service)进行后台下载更新的解决方案。以下是关于这个主题的详细知识点: 1. **Android Service**: 在Android系统中,Service是...

    Android实现Service下载文件,Notification显示下载进度的示例

    以上就是一个基本的Android Service下载文件并显示Notification进度的例子。它展示了如何在后台执行耗时操作,如文件下载,并通过Notification向用户反馈进度。请注意,实际的下载任务可能需要处理更多细节,例如...

    android文件下载进度条实现

    在Android开发中,实现文件下载进度条是一项常见的需求,它能提供用户友好的界面体验,让用户了解文件下载的状态。本文将详细讲解如何在Android中实现文件下载并展示进度条。 首先,我们需要创建一个用于下载任务的...

    Android7.0下载文件,状态栏进度条显示加载进度,点击文件则打开文件

    在Android 7.0系统中,开发者可以利用API来实现文件下载和上传过程中状态栏进度条的显示,以及用户点击文件后直接打开的功能。这一特性极大地提升了用户体验,使得用户能够实时了解文件操作的状态,并且方便地访问已...

    在状态栏中显示进度条的下载更新

    本教程将详细讲解如何在Android的状态栏中显示进度条,并同步更新到当前Activity中的进度条,确保用户能够直观地了解操作的进度。 首先,我们需要在AndroidManifest.xml中为应用请求显示系统通知的权限: ```xml ...

    Service下载apk通过notification显示下载进度

    "Service下载apk通过notification显示下载进度"这个主题涉及到的是如何利用Service来下载APK,并且通过通知栏(Notification)实时更新下载进度,下载完成后自动安装APK。这里将详细讲解这一过程的关键知识点。 ...

    android线程和服务两种方式下载,广播通知栏同步更新进度

    本篇将深入探讨如何通过线程和服务两种方式实现网络下载,并利用广播来同步更新进度条和通知栏。这两种方法都是为了优化用户体验,确保用户能够实时了解下载状态。 首先,我们来看线程下载。在Android中,由于主线...

Global site tag (gtag.js) - Google Analytics