为啥 网上下载的DownloadManager例程在android10,11上都不好用了

沈琛
2023-12-01

有个需求要下载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
  • 1

在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;
	}

}

 类似资料: