有个需求要下载rom更新,下载了N多的DownloadManager下载更新,没有一个好用的。因为都是针
对Android 7,8 来写的,另外还有个是基于kotlin写的居然好用,但是我要编译到rom中,就放弃用了。原因见下面的
为保证用户数据和设备的安全,Google针对下一代 Android 系统(Android P) 的应用程序,将要求默认使用加密连接,这意味着 Android P 将禁止 App 使用所有未加密的连接,因此运行 Android P 系统的安卓设备无论是接收或者发送流量,未来都不能明码传输,需要使用下一代(Transport Layer Security)传输层安全协议,而 Android Nougat 和 Oreo 则不受影响。
因此在Android P 使用HttpUrlConnection进行http请求会出现以下异常
java.io.IOException: Cleartext HTTP traffic to 192.168.0.5 not permitted
在Android P系统的设备上,如果应用使用的是非加密的明文流量的http网络请求,则会导致该应用无法进行网络请求,https则不会受影响,同样地,如果应用嵌套了webview,webview也只能使用https请求。
针对这个问题,有种解决方法:
:在AndroidManifest.xml配置文件的标签中直接插入
android:usesCleartextTraffic="true"
附自己的实现代码,这个是调用别人的浏览器去下载
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse(rom_url);
intent.setData(content_url);
this.startActivity(intent);
另外一个
package org.lineageos.updater;
import android.os.Environment;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 下载工具类
*/
public class HttpDownloader {
private String SDPATH;
public HttpDownloader() {
//得到当前外部存储设备的目录( /SDCARD )
SDPATH = Environment.getExternalStorageDirectory() + "/";
}
private URL url = null;
/**
* 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文本当中的内容
* 1.创建一个URL对象
* 2.通过URL对象,创建一个HttpURLConnection对象
* 3.得到InputStream
* 4.从InputStream当中读取数据
*
* @param urlStr
* @return
*/
public String download(String urlStr) {
StringBuffer sb = new StringBuffer();
String line = null;
BufferedReader buffer = null;
try {
url = new URL(urlStr);
//根据URL取得与资源提供的服务器的连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
//将连接流管道成BufferedReader
buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
//利用BufferedReader逐行读取文本信息,并添加到StringBuffer中
while ((line = buffer.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (buffer != null) {
buffer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//将读取的文本信息以String的形式输出
return sb.toString();
}
/**
* @param urlStr 文件地址
* @param path 文件保存路径
* @param fileName 文件名
* @return 文件的绝对路径
*/
public String downFile(String urlStr, String path, String fileName) {
InputStream inputStream = null;
String filePath = null;
try {
FileUtils fileUtils = new FileUtils();
//判断文件是否存在
if (fileUtils.isFileExist(path + fileName)) {
System.out.println("exits");
filePath = SDPATH + path + fileName;
} else {
//得到io流
inputStream = getInputStreamFromURL(urlStr);
//从input流中将文件写入SD卡中
File resultFile = fileUtils.write2SDFromInput(path, fileName, inputStream);
if (resultFile != null) {
filePath = resultFile.getPath();
}
}
} catch (Exception e) {
FileUtils.state=FileUtils.STATE_DOWNLOAD_ERROR;
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return filePath;
}
/**
* 根据URL得到输入流
*
* @param urlStr
* @return
*/
public InputStream getInputStreamFromURL(String urlStr) {
HttpURLConnection urlConn;
InputStream inputStream = null;
try {
url = new URL(urlStr);
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setConnectTimeout(5000);
FileUtils.file_totalsize=urlConn.getContentLength();
inputStream = urlConn.getInputStream();
} catch (Exception e) {
FileUtils.state=FileUtils.STATE_DOWNLOAD_ERROR;
e.printStackTrace();
}
return inputStream;
}
}
package org.lineageos.updater;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
/**
* SD卡的路径
*/
private String SDPATH;
/**
* 设置最大的文件大小
*/
private int FILESIZE = 10 * 1024;
public static long file_totalsize =0;
public static long current_totalCount =0;
public static long currentMB =0;
public static int state =0;
public static int STATE_INIT = 0;
public static int STATE_DOWNLOAD_OK = 1;
public static int STATE_DOWNLOAD_ERROR = 2;
public static int STATE_FILE_MISSING = 3;
public String getSDPATH(){
return SDPATH;
}
public FileUtils(){
//得到当前外部存储设备的目录( /SDCARD )
SDPATH = Environment.getExternalStorageDirectory() + "/";
}
public static void reset()
{
file_totalsize =STATE_INIT;
current_totalCount =0;
currentMB =0;
state =0;
}
/**
* 在SD卡上创建文件
* @param fileName
* @return
* @throws IOException
*/
public File createSDFile(String fileName) throws IOException {
File file = new File(SDPATH + fileName);
file.createNewFile();
return file;
}
/**
* 在SD卡上创建目录
* @param dirName
* @return
*/
public File createSDDir(String dirName){
File dir = new File(SDPATH + dirName);
dir.mkdir();
return dir;
}
/**
* 判断SD卡上的文件夹是否存在
* @param fileName
* @return
*/
public boolean isFileExist(String fileName){
File file = new File(SDPATH + fileName);
return file.exists();
}
/**
* 将一个InputStream里面的数据写入到SD卡中
* @param path
* @param fileName
* @param input
* @return
*/
public File write2SDFromInput(String path, String fileName,
InputStream input) {
File file = null;
OutputStream output = null;
state=0;
try {
// 创建文件夹
createSDDir(path);
// 创建文件
file = createSDFile(path + fileName);
// 开启输出流,准备写入文件
output = new FileOutputStream(file);
// 缓冲区
byte[] buffer = new byte[FILESIZE];
int count;
while ((count = input.read(buffer)) != -1) {
output.write(buffer, 0, count);
current_totalCount +=count;
currentMB=(current_totalCount /1024/1024);
}
output.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
output.close();
input.close();
state=STATE_DOWNLOAD_OK;
Log.d("out put ","Download finished "+currentMB+"MB downloaded");
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
}