解析更新文件
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);
}