Android APK下载与更新

解析更新文件

public UpdateInfo getUpdateInfo(InputStream inStream) throws Exception {
        UpdateInfo mUpdateInfo=new UpdateInfo();
        HashMap<String, String> hashMap = new HashMap<String, String>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(inStream);
        Element root = document.getDocumentElement();
        NodeList childNodes = root.getChildNodes();
        for (int j = 0; j < childNodes.getLength(); j++) {
            Node childNode = (Node) childNodes.item(j);
            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                Element childElement = (Element) childNode;
                if (("Rversion".equals(childElement.getNodeName()))) {
                    mUpdateInfo.setVersion(childElement.getFirstChild().getNodeValue());
                } else if (("Rname".equals(childElement.getNodeName()))) {
                    mUpdateInfo.setAppName(childElement.getFirstChild().getNodeValue());
                } else if (("Rurl".equals(childElement.getNodeName()))) {
                    mUpdateInfo.setUrl(childElement.getFirstChild().getNodeValue());
                }
            }
        }
        return mUpdateInfo;
    }

判别是否有更新

public void showUpdate(InputStream s) {
        int version=Integer.parseInt(getVersionCode(mContext));
        ParseXmlService service = new ParseXmlService();
        UpdateInfo mUpdateInfo=new UpdateInfo();
        try {
            mUpdateInfo=service.getUpdateInfo(s);
            if(Integer.parseInt(mUpdateInfo.getVersion())>version)
            {
                showNoticeDialog(mUpdateInfo.getVersion());
                FileUtil.downloadUrl=mUpdateInfo.getUrl();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

显示更新框

private void showNoticeDialog(String version_info) {
        // 构造对话框
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("更新提示");
        builder.setMessage("木兰湾开发区土地利用变化监测更新");
        // 更新
        builder.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                // 启动后台服务下载apk
                //mContext.startService(new Intent(MainActivity.this, DownLoadService.class));
                new DownLoadService(MainActivity.this,mContext).loadFile();
            }
        });
        // 稍后更新
        builder.setNegativeButton("以后更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        Dialog noticeDialog = builder.create();
        noticeDialog.show();
    }

更新操作

public class DownLoadService {

    private Context mContext;
    int downloadCount = 0;
    private File outputFile;
    private MainActivity mMainActivity;


    public DownLoadService(MainActivity mainActivity,  Context mContext) {
        this.mMainActivity = mainActivity;
        this.mContext = mContext;
    }

    /**
     * 下载文件
     */
    public void loadFile() {
        initNotification();
        DownloadProgressListener listener = new DownloadProgressListener() {
            @Override
            public void update(long bytesRead, long contentLength, boolean done) {
                //不频繁发送通知,防止通知栏下拉卡顿
                int progress = (int) ((bytesRead * 100) / contentLength);
                if ((downloadCount == 0) || progress > downloadCount) {
                    Download download = new Download();
                    download.setTotalFileSize(contentLength);
                    download.setCurrentFileSize(bytesRead);
                    download.setProgress(progress);

                    sendNotification(download);
                }
            }
        };
        outputFile = new File(Environment.getExternalStoragePublicDirectory
                (Environment.DIRECTORY_DOWNLOADS), "mlw.apk");

        if (outputFile.exists()) {
            outputFile.delete();
        }

        String baseUrl = StringUtils.getHostName(downloadUrl);

        new DownloadAPI(baseUrl, listener).downloadAPK(downloadUrl, outputFile, new Subscriber() {
            @Override
            public void onCompleted() {
                downloadCompleted();
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                downloadCompleted();
            }

            @Override
            public void onNext(Object o) {

            }
        });
    }

    private static ProgressBar pb;
    private static AlertDialog alertDialog = null;
    private static LinearLayout layoutSend;
    private AlertDialog.Builder mSendDialog;

    /**
     * 初始化Notification通知
     */
    public void initNotification() {
        layoutSend = (LinearLayout) mMainActivity.getLayoutInflater().inflate(
                R.layout.send_file_progress_layout, null);
        pb = (ProgressBar) layoutSend.findViewById(R.id.send_progress);
        pb.setProgress(0);

        mSendDialog = new AlertDialog.Builder(mMainActivity);
        mSendDialog.setTitle("下载进度");
        mSendDialog.setView(layoutSend);
        alertDialog = mSendDialog.create();
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.show();

    }

    private void downloadCompleted() {
        pb.setProgress(100);
        alertDialog.dismiss();

        //安装apk
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-archive");
        mMainActivity.startActivity(intent);
    }

    private void sendNotification(Download download) {
        pb.setProgress(download.getProgress());
    }

}

下载监听

public interface DownloadProgressListener {
    void update(long bytesRead, long contentLength, boolean done);
}
public class DownloadProgressInterceptor implements Interceptor {

    private DownloadProgressListener listener;

    public DownloadProgressInterceptor(DownloadProgressListener listener) {
        this.listener = listener;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Response originalResponse = chain.proceed(chain.request());

        return originalResponse.newBuilder()
                .body(new DownloadProgressResponseBody(originalResponse.body(), listener))
                .build();
    }
}
public class DownloadProgressResponseBody extends ResponseBody {

    private ResponseBody responseBody;
    private DownloadProgressListener progressListener;
    private BufferedSource bufferedSource;

    public DownloadProgressResponseBody(ResponseBody responseBody,
                                        DownloadProgressListener progressListener) {
        this.responseBody = responseBody;
        this.progressListener = progressListener;
    }

    @Override
    public MediaType contentType() {
        return responseBody.contentType();
    }

    @Override
    public long contentLength() {
        return responseBody.contentLength();
    }

    @Override
    public BufferedSource source() {
        if (bufferedSource == null) {
            bufferedSource = Okio.buffer(source(responseBody.source()));
        }
        return bufferedSource;
    }

    private Source source(Source source) {
        return new ForwardingSource(source) {
            long totalBytesRead = 0L;

            @Override
            public long read(Buffer sink, long byteCount) throws IOException {
                long bytesRead = super.read(sink, byteCount);
                // read() returns the number of bytes read, or -1 if this source is exhausted.
                totalBytesRead += bytesRead != -1 ? bytesRead : 0;

                if (null != progressListener) {
                    progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
                }
                return bytesRead;
            }
        };

    }
}

网络下载

public class DownloadAPI {
    private static final String TAG = "DownloadAPI";
    private static final int DEFAULT_TIMEOUT = 15;
    public Retrofit retrofit;


    public DownloadAPI(String url, DownloadProgressListener listener) {

        DownloadProgressInterceptor interceptor = new DownloadProgressInterceptor(listener);

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .retryOnConnectionFailure(true)
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .build();


        retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .client(client)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }

    public void downloadAPK(@NonNull String url, final File file, Subscriber subscriber) {
        Log.d(TAG, "downloadAPK: " + url);

        retrofit.create(MapSayApis.class)
                .downloadFile(url)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .map(new Func1<ResponseBody, InputStream>() {
                    @Override
                    public InputStream call(ResponseBody responseBody) {
                        return responseBody.byteStream();
                    }
                })
                .observeOn(Schedulers.computation())
                .doOnNext(new Action1<InputStream>() {
                    @Override
                    public void call(InputStream inputStream) {
                        try {
                            FileUtil.writeFile(inputStream, file);
                        } catch (IOException e) {
                            e.printStackTrace();
                            throw new CustomizeException(e.getMessage(), e);
                        }
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }
}
public class CustomizeException extends RuntimeException {
    public CustomizeException(String message, Throwable cause) {
        super(message, cause);
    }
}
public interface MapSayApis {
     @Streaming
    @GET
    Observable<ResponseBody> downloadFile(@Url String url);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值