app版本更新下载服务

开发app 肯定要用到版本升级更新

对于小的bug一般都是使用热修复 对版本更新没有要求 所以还没研究 直接使用版本升级

大概思路就是 根据版本得code 或者版本名称之类得判断是否需要升级 如果需要就开启一个服务下载新版本 实现的流程就是在发现新版本后通过弹出提示框 提示下载 如果下载 会在手机通知栏有一个下载中得状态栏 效果一般 在下载完成后覆盖安装


import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

import com.xgs.financepay.R;
import com.xgs.utils.FileUtil;

/***
 * 升级服务
 */
public class UpdateService extends Service {

//    public static final String Install_Apk = "Install_Apk";
    /********
     * download progress step
     *********/
    private static final int down_step_custom = 3;

    private static final int TIMEOUT = 100 * 1000;// 超时
    private static String down_url;
    private static final int DOWN_OK = 1;
    private static final int DOWN_ERROR = 0;

    private String app_name;

    private NotificationManager notificationManager;
    private Notification.Builder builder;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        try {
            app_name = intent.getStringExtra("Key_App_Name");
            down_url = intent.getStringExtra("Key_Down_Url");
        } catch (Exception e) {
            Message message = new Message();
            message.what = DOWN_ERROR;
            handler.sendMessage(message);
        }
        // create file,应该在这个地方加一个返回值的判断SD卡是否准备好,文件是否创建成功,等等!
        FileUtil.createFile(app_name);

//        if (FileUtil.isCreateFileSucess == true) {
        createNotification();
        createThread();
//        } else {
//            Toast.makeText(this, "请插入SD", Toast.LENGTH_SHORT)
//                    .show();
//            /*************** stop service ************/
//            stopSelf();
//            createNotification();
//            createThread();
//        }
        return super.onStartCommand(intent, flags, startId);
    }


    @SuppressLint("HandlerLeak")
    private final Handler handler = new Handler() {
        @SuppressWarnings("deprecation")
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DOWN_OK:
                    /***** 安装APK ******/
                    builder.setContentText("下载成功,正在安装");
                    builder.setAutoCancel(true);
                    builder.getNotification().flags = Notification.FLAG_AUTO_CANCEL;
                    notificationManager.notify(R.layout.notification_item, builder.getNotification());
                    installApk();
                    stopSelf();
                    break;
                case DOWN_ERROR:
                    builder.setContentText("下载失败,请检查是否开启存储卡写入权限");
                    builder.setAutoCancel(true);
                    builder.getNotification().flags = Notification.FLAG_AUTO_CANCEL;
                    notificationManager.notify(R.layout.notification_item, builder.getNotification());
                    stopSelf();
                    /***stop service*****/
                    //onDestroy();
                    break;
                default:
                    break;
            }
        }
    };

    private void installApk() {
        /*********下载完成,点击安装***********/
        Uri uri = Uri.fromFile(FileUtil.updateFile);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        /**********加这个属性是因为使用ContextstartActivity方法的话,就需要开启一个新的task**********/
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        UpdateService.this.startActivity(intent);
    }


    public void createThread() {
        new DownLoadThread().start();
    }

    private class DownLoadThread extends Thread {
        @Override
        public void run() {
            Message message = new Message();
            try {
                long downloadSize = downloadUpdateFile(down_url,
                        FileUtil.updateFile.toString());
                if (downloadSize > 0) {
                    message.what = DOWN_OK;
                    handler.sendMessage(message);
                }
            } catch (Exception e) {
                message.what = DOWN_ERROR;
                handler.sendMessage(message);
            }
        }
    }


    public void createNotification() {
        builder = new Notification.Builder(this);
        //应用的图标
        builder.setSmallIcon(R.mipmap.login_logo).setOngoing(false)
                .setContentText("正在下载安装包")
                .setContentTitle("标题");
        builder.setAutoCancel(true);
        builder.setTicker("正在下载安装包");
        builder.setProgress(100, 0, true);
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(R.layout.notification_item, builder.getNotification());
    }


    public long downloadUpdateFile(String down_url, String file)
            throws Exception {

        long down_step = down_step_custom;// 提示step
        long totalSize;// 文件总大小
        long downloadCount = 0;// 已经下载好的大小
        int updateCount = 0;// 已经上传的文件大小

        InputStream inputStream;
        OutputStream outputStream;

        URL url = new URL(down_url);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url
                .openConnection();
        httpURLConnection.setConnectTimeout(TIMEOUT);
        httpURLConnection.setReadTimeout(TIMEOUT);
        // 获取下载文件的size
        totalSize = httpURLConnection.getContentLength();

        if (httpURLConnection.getResponseCode() == 404) {
            throw new Exception("download fail!");
        }

        inputStream = httpURLConnection.getInputStream();
        outputStream = new FileOutputStream(file, false);// 文件存在则覆盖掉

        byte buffer[] = new byte[1024];
        int readsize = 0;

        while ((readsize = inputStream.read(buffer)) != -1) {

            outputStream.write(buffer, 0, readsize);
            downloadCount += readsize;// 时时获取下载到的大小
            if (updateCount == 0 || (downloadCount * 100 / totalSize - down_step) >= updateCount) {
                updateCount += down_step;
                builder.setProgress(100, updateCount, true);
                notificationManager.notify(R.layout.notification_item, builder.getNotification());
            }
        }
        if (httpURLConnection != null) {
            httpURLConnection.disconnect();
        }
        inputStream.close();
        outputStream.close();

        return downloadCount;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}


<!-- 升级服务 -->
<service android:name=".service.UpdateService" />

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="3dp" >

    <ImageView
        android:id="@+id/notificationImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/stat_sys_download" 
        android:paddingLeft="16dp"/>

    <TextView
        android:id="@+id/notificationTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@id/notificationImage"
        android:paddingLeft="26dp"
        android:textColor="#FFFFFFFF" />
    <!-- android:textColor="#FF000000"  -->

    <TextView
        android:id="@+id/notificationPercent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/notificationImage"
        android:paddingTop="2dp"
        android:textColor="#FFFFFFFF" 
        android:paddingLeft="16dp"/>

    <ProgressBar
        android:id="@+id/notificationProgress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/notificationTitle"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@id/notificationPercent"
        android:layout_below="@id/notificationTitle"
        android:paddingLeft="26dp"
        android:paddingRight="3dp"
        android:paddingTop="2dp" />

</RelativeLayout>




/**
 * 类描述:FileUtil
 */
public class FileUtil {

    public static File updateDir = null;
    public static File updateFile = null;

    /***********
     * 保存升级APK的目录
     ***********/
    public static final String aaaa = "aaaa";

    public static boolean isCreateFileSucess;

    /**
     * 方法描述:createFile方法
     *
     * @return
     * @see FileUtil
     */
    public static void createFile(String app_name) {

//        if (Environment.MEDIA_MOUNTED.equals(Environment
//                .getExternalStorageState())) { //该方法为判断是否有外挂路径 但是有外挂无sd卡路径 无法创建
        if (!TextUtils.isEmpty(Environment.getExternalStorageDirectory().toString())) {
            updateDir = new File(Environment.getExternalStorageDirectory()
                    + "/" + aaaa + "/");
            isCreateFileSucess = true;
//            updateDir = new File(Environment.getDataDirectory()
//                    + "/" + aaaa + "/");//  获得根目录/data 内部存储路径 data路径读写失败 是不是权限问题?
            if (!updateDir.exists()) {
                updateDir.mkdirs();
            }
            updateFile = new File(updateDir + "/" + app_name + ".apk");
            Log.i("updateDir", "" + updateDir);
            if (!updateFile.exists()) {
                try {
                    updateFile.createNewFile();
                } catch (IOException e) {
                    isCreateFileSucess = false;
                    e.printStackTrace();
                }
            }
        } else {
            updateDir = new File(Environment.getDataDirectory()
                    + "/" + aaaa + "/");//  获得根目录/data 内部存储路径 data路径读写失败 是不是权限问题?
            if (!updateDir.exists()) {
                updateDir.mkdirs();
            }
            updateFile = new File(updateDir + "/" + app_name + ".apk");
            Log.i("updateDir", "" + updateDir);
            if (!updateFile.exists()) {
                try {
                    updateFile.createNewFile();
                } catch (IOException e) {
                    isCreateFileSucess = false;
                    e.printStackTrace();
                }
            }
        }
    }

    public static boolean inputStreamToOutputStream(InputStream input,
                                                    OutputStream output) {
        BufferedOutputStream out = null;
        BufferedInputStream in = null;
        in = new BufferedInputStream(input, 8 * 1024);
        out = new BufferedOutputStream(output, 8 * 1024);
        int b;
        try {
            while ((b = in.read()) != -1) {
                out.write(b);
            }
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null)
                    out.close();
                if (in != null)
                    in.close();
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public static String inputStreamToString(InputStream in) {
        String result = "";
        if (null != in) {
            InputStreamReader ir = null;
            BufferedReader br = null;
            StringBuffer sb = new StringBuffer();
            try {
                ir = new InputStreamReader(in);
                br = new BufferedReader(ir);
                String line;
                while ((line = br.readLine()) != null)
                    sb.append("/n").append(line);
                if (result.length() > 0)
                    result = result.substring("/n".length());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (ir != null)
                        ir.close();
                    if (br != null)
                        br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static InputStream byteToInputStream(byte[] bytes) {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        return bais;
    }
   

    //检测sd卡是否可用
    public static boolean checkSDcardValid() {
        String sdStatus = Environment.getExternalStorageState();
        if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) {
            Log.e("fileutil", "sd卡不可用!");
            return false;
        }
        return true;
    }

    //判断文件夹是否创建成功
    public static boolean createDir() {
        File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/aaaa/");
        Log.d("fileutil", "文件夹路径:" + dir.getAbsolutePath());
        if (!dir.exists()) {
            if (!dir.mkdir()) {
                Log.e("fileutil", "创建文件夹失败!");
                return false;
            }
        }
        return true;
    }
     
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值