apk时存放到data下时引导安装解析失败解决办法

做下载时,当sd卡满了或是不可用时,可将内容下载到data下面,但是下载到data下的apk,在安装时,会出现“解析失败”,查看了文件大小,是正确的。

解决办法:在下载前,打开data下文件流时,要设置属性为可读可写:

如:

 String filePath=getApplicationContext().getFilesDir().toString() + File.separator+"test.apk";
 FileOutputStream fos = new FileOutputStream(new File(filePath));
 FileOutputStream fos= getApplicationContext().openFileOutput(fileName,Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);

断点下载示例:

  

	/* * 
	 * 下载升级包线程
	 * 
	 */
     class DownApkRunnable implements Runnable {
		private DownLoadFile dlFile;


		public DownApkRunnable(DownLoadFile dlFile) {
			this.dlFile = dlFile;
		}


		@Override
		public synchronized void run() {
			// 开始下载前先提示
			mHandler.sendMessage(mHandler.obtainMessage(MSG_SHOW_TOAST, MainApplication.getInstance().getString(
					R.string.tip_update_begin)));


			isStartUpdate = true;


			// 初始化下载路径,确保下载路径存在并可用
			savePath = UriConfig.getSavePath() + "update/";
			setState(UPDATE_STATE_UPDATING);
			ELog.d(Constant.TAG, "start to download update info...");
			FileManager.deleteDirectoryContent(savePath);
			ELog.d(Constant.TAG, "updateDataSavePath=" + savePath);
			File file = new File(savePath);
			if (!file.exists()) {
				boolean isSuccess=file.mkdirs();
				ELog.e("创建savePath:"+savePath+" isSuccess="+isSuccess);
			}
			dlFile.setSavePath(savePath);


			// 初始化文件路径及临时存储路径
			final String filePath = dlFile.getSavePath() + dlFile.getFileName();
			String tempFilePath = savePath + dlFile.getTempFileName();
			ELog.i(Constant.TAG, "filePath=" + filePath);
			ELog.i(Constant.TAG, "tempFilePath=" + tempFilePath);
			if (tempFilePath == null
					|| (tempFilePath = tempFilePath.trim()).length() <= 0) {
				updateFailed(
						mContext.getString(R.string.notification_update_error_title),
						null);
				return;
			}
			long currLen = 0;
			long maxLen = 0;
			InputStream is = null;
			// 下载失败重试次数
			int retryCount = 2;
			boolean isCreateFileSuccess = false;
			for (int i = 0; i <= retryCount; i++) {
				try {
					ELog.e("第" + i + "次连接网络...");
					final File tempfile = new File(tempFilePath);
					if (tempfile.exists()) {
						// 第1次连接时,确保临时存放的文件是空的,存在的
						if (i == 0) {
							tempfile.delete();
							isCreateFileSuccess = tempfile.createNewFile();
						} else {// 重试时,读取临时文件的大小,如支持断点就继续下载,否则从头下载
							currLen = tempfile.length();
							ELog.v("file has download portion :currLen="
									+ currLen);
							isCreateFileSuccess = true;
						}
					} else {
						isCreateFileSuccess = tempfile.createNewFile();
					}
					ELog.e("...isCreateFileSuccess="+isCreateFileSuccess);
					NetWorkManager netManager = new NetWorkManager();
					Header[] mHeaders = null;


					if (currLen > 0) {
						mHeaders = new Header[1];
						final long tempLen = currLen;
						Header header = new Header() {
							@Override
							public String getValue() {
								return "bytes=" + tempLen + "-";
							}


							@Override
							public String getName() {
								return "RANGE";
							}


							@Override
							public HeaderElement[] getElements()
									throws ParseException {
								return null;
							}
						};
						mHeaders[0] = header;
					}


					HttpResponse response = netManager
							.sendGetRequestAndWaitHttpEntityResponse(mContext,
									dlFile.getUrl(), mHeaders);
					if (response == null) {
//						throw new Exception();
						downLoadStateChanged(dlFile,
								UPDATE_STATE_UPDATE_ERROR, null);
						updateFailed(
								mContext.getString(R.string.notification_update_error_title),
								mContext.getString(R.string.notification_update_error4));
						return;
					}
					int respCode = response.getStatusLine().getStatusCode();
					ELog.i("升级下载,respCode:" + respCode);
					HttpEntity httpEntiy;
					if (respCode == HttpStatus.SC_OK
							|| respCode == HttpStatus.SC_PARTIAL_CONTENT) {// 206表示支持断点续传){
						httpEntiy = response.getEntity();
					} else {
						throw new Exception();
					}


					if (httpEntiy == null) {
						throw new Exception();
					}


					FileOutputStream fos = null;


					// 判断是否支持断点续传
					Header[] allHeaders = response.getAllHeaders();
					if (allHeaders != null) {
						for (Header header : allHeaders) {
							ELog.w("升级包head: key=" + header.getName()
									+ "  value=" + header.getValue());
							if (header.getName().equals("Accept-Ranges")) {
								if ((header.getValue() != null && header
										.getValue().equalsIgnoreCase("bytes"))
										|| respCode == HttpStatus.SC_PARTIAL_CONTENT) {
									ELog.i("升级包,支持断点续传的...");
									fos = new FileOutputStream(tempfile, true);
								} else {
									ELog.i("升级包,不..支持断点续传的...");
									fos = new FileOutputStream(tempfile);
									currLen = 0;
								}
							}
						}
					}


					// 长度取第一次联网获取的长度
					if (i == 0 && maxLen <= 0) {
						maxLen = httpEntiy.getContentLength();
					}


					ELog.i("下载,文件大小:" + maxLen + "  sd卡剩余空间:"
							+ DownloadTask.getTotalExternalMemorySize());


					if (maxLen > DownloadTask.getTotalExternalMemorySize()) {
						ELog.i("文件下载前比较,空间不足,取消下载...");
						downLoadStateChanged(dlFile, UPDATE_STATE_UPDATE_ERROR,
								null);
						updateFailed(
								mContext.getString(R.string.notification_update_error_title),
								mContext.getString(R.string.notification_update_error2));
						return;
					}
					setMaxLen(maxLen);
					setCurrLen(currLen);


					downLoadProgressChanged(dlFile, maxLen, currLen);
					is = httpEntiy.getContent();
					byte[] data = new byte[1024];
					int len;
					downLoadStateChanged(dlFile, UPDATE_STATE_UPDATING, null);
					// 流读取完或是文件被暂停后停止读取数据
					while ((len = is.read(data)) != -1) {
						fos.write(data, 0, len);
						currLen += len;
						ELog.v(Constant.TAG, "down....currLen=" + currLen);
						downLoadProgressChanged(dlFile, maxLen, currLen);
						dlFile.setCurrSize(currLen);
					}
					fos.flush();
					fos.close();
					is.close();
					// 当下载完后才重命名
					ELog.v(Constant.TAG, dlFile.getTempFileName()
							+ "  rename to :" + dlFile.getFileName());
					file.renameTo(new File(savePath + dlFile.getFileName()));
					downLoadFileCompleted(dlFile);
					downLoadStateChanged(dlFile, UPDATE_STATE_UPDATE_SUCCESS,
							null);
					dlFile.setState(DownLoadFileListener.STATE_DOWNCOMPLETE);
					break;
				} catch (Exception e) {
					ELog.e("Error:"+e.getMessage());
					e.printStackTrace();
					if (!isCreateFileSuccess) {
						downLoadStateChanged(dlFile, UPDATE_STATE_UPDATE_ERROR,
								null);
						updateFailed(
								mContext.getString(R.string.notification_update_error_title),
								mContext.getString(R.string.notification_update_error5));
						break;
					} else if (DownloadTask.getTotalExternalMemorySize() <= 0) {
						downLoadStateChanged(dlFile, UPDATE_STATE_UPDATE_ERROR,
								null);
						updateFailed(
								mContext.getString(R.string.notification_update_error_title),
								mContext.getString(R.string.notification_update_error2));
						break;
					} else if (i >= retryCount) {
						if (!Utils.isNetworkAvailable(mContext)) {
							downLoadStateChanged(dlFile,
									UPDATE_STATE_UPDATE_ERROR, null);
							updateFailed(
									mContext.getString(R.string.notification_update_error_title),
									mContext.getString(R.string.notification_update_error3));
						} else if (e instanceof SocketTimeoutException) {
							downLoadStateChanged(dlFile,
									UPDATE_STATE_UPDATE_ERROR, null);
							updateFailed(
									mContext.getString(R.string.notification_update_error_title),
									mContext.getString(R.string.notification_update_error4));
						} else {
							downLoadStateChanged(dlFile,
									UPDATE_STATE_UPDATE_ERROR, null);
							updateFailed(
									mContext.getString(R.string.notification_update_error_title),
									mContext.getString(R.string.notification_update_error6));
						}
					}
				} finally {
					try {
						if (is != null) {
							is.close();
							is = null;
						}
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
		}
	}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值