美文网首页
Android 11 公共目录Download文件操作

Android 11 公共目录Download文件操作

作者: 我家猫猫不睡觉 | 来源:发表于2022-01-12 16:17 被阅读0次

    因公司需求在不申请读写权限的情况下 下载和上传Download里面的文件。

    这里采取SAF方式

    一:选择文件上传
    • 创建指定文件夹
      创建文件夹我是直接用绝对路径创建的,文件夹可以创建成功。但是不可这么创建文件,开始直接下载文件到download文件夹 稍过一会文件就会被自动删除。
     public static final String DOWNLOAD_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/JoyStarManager";
    
    if (CommonUtils.isFirstStart()) {
                File downloadFile = new File(Configs.DOWNLOAD_PATH);
                if (!downloadFile.exists()) {
                    downloadFile.mkdir();
                }
            }
    
    • 打开指定文件夹目录 获取文件的uri
    public static final String DOWNLOAD_URI = "content://com.android.externalstorage.documents/tree/primary%3ADownload%2FJoyStarManager";
    Uri mDocumentDownloadUri = Uri.parse(Configs.DOWNLOAD_URI);
    
      getDownloadDirFiles(SCAN_IMG_IN_DOWNLOAD, mDocumentDownloadUri);
    
      private void getDownloadDirFiles(int scanType, Uri uri) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    
                try {
                    final int takeFlags = getIntent().getFlags()
                            & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    getContentResolver().takePersistableUriPermission(uri, takeFlags);
    
                    DocumentFile documentFile = DocumentFile.fromTreeUri(this, uri);
                    DocumentFile[] documentFiles = documentFile.listFiles();
                    mLocalFileInfos = new ArrayList<>();
                    LocalFileInfo fileInfo;
                    for (DocumentFile file : documentFiles) {
                        Uri fileUri = file.getUri();
                        String path = fileUri.getPath();
                        String fileType = FileUtil.getFileType(path);
                        switch (scanType) {
                            case SCAN_IMG_IN_DOWNLOAD:
                                if (fileType.equals(Configs.JPG) || fileType.equals(Configs.PNG)) {
                                    fileInfo = new LocalFileInfo();
                                    fileInfo.setUri(fileUri.toString());
                                    fileInfo.setName(file.getName());
                                    fileInfo.setType(fileType);
                                    mLocalFileInfos.add(fileInfo);
                                }
                                break;
                            case SCAN_ZIP_IN_DOWNLOAD:
                                if (fileType.equals(Configs.ZIP) && path.endsWith(Configs.ZIP)) {
                                    fileInfo = new LocalFileInfo();
                                    fileInfo.setUri(fileUri.toString());
                                    fileInfo.setName(file.getName());
                                    fileInfo.setType(fileType);
                                    mLocalFileInfos.add(fileInfo);
                                } else if (fileType.equals(Configs.RAR)) {
                                    fileInfo = new LocalFileInfo();
                                    fileInfo.setName(file.getName());
                                    fileInfo.setUri(fileUri.toString());
                                    fileInfo.setType(fileType);
                                    mLocalFileInfos.add(fileInfo);
                                }
                                break;
                            case SCAN_ZIP_APK_IN_DOWNLOAD:
                                if (fileType.equals(Configs.ZIP) || fileType.equals(Configs.RAR)) {
                                    fileInfo = new LocalFileInfo();
                                    fileInfo.setName(file.getName());
                                    fileInfo.setUri(fileUri.toString());
                                    fileInfo.setType(fileType);
                                    mLocalFileInfos.add(fileInfo);
                                }
                                break;
    
                        }
                        mAdapter.setData(mLocalFileInfos);
                    }
                } catch (SecurityException e) {
                    //转换成可以使用的路径uri
                    Uri useUri = DocumentFile.fromTreeUri(this, mDocumentDownloadUri).getUri();
                    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                    //打开指定路径文件夹
                    intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, useUri);
                    //申请这个文件夹的读写权限
                    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    startActivityForResult(intent, SCAN_DOWNLOAD_CALL_BACK);
    
    //            Uri useUri = DocumentFile.fromTreeUri(this, mDocumentDownloadUri).getUri();
    //            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    //            //文档需要是可以打开的
    //            intent.addCategory(Intent.CATEGORY_OPENABLE);
    //            intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, useUri);
    //            //指定文档的minitype为text类型
    //            intent.setType("*/*");
    //            //是否支持多选,默认不支持
    //            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
    //            startActivityForResult(intent, SCAN_DOWNLOAD_CALL_BACK);
                }
            }
        }
    
    
     // 获取文件的Uri
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (data == null || resultCode != RESULT_OK) {
                // 用户未选择任何文件,直接返回
                return;
            }
            if (requestCode == SCAN_DOWNLOAD_CALL_BACK) {
                Uri uri = data.getData();
                switch (mUploadType) {
                    case Configs.UPLOAD_NO_ZIP:
                        getDownloadDirFiles(SCAN_IMG_IN_DOWNLOAD, uri);
                        break;
                    case Configs.SET_INFO_TYPE_APK:
                        getDownloadDirFiles(SCAN_ZIP_APK_IN_DOWNLOAD, uri);
                        break;
                    default:
                        getDownloadDirFiles(SCAN_ZIP_IN_DOWNLOAD, uri);
                }
                final int takeFlags = data.getFlags()
                        & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                getContentResolver().takePersistableUriPermission(uri, takeFlags);
            }
        }
    
    • 上传
      retrofit2 可以直接用流上传
     private void addApkInfo() {
            mProgressbar.setVisibility(View.VISIBLE);
    
            Map<String, RequestBody> params = new HashMap<>();
            params.put("aaa", toRequestBody(aaa));
            params.put("bbb", toRequestBody(bbb));
            params.put("ccc", toRequestBody(ccc));
            params.put("ddd", toRequestBody(ddd));
            params.put("eee", toRequestBody(eee));
            try {
                //获得输入流
                InputStream is = getContentResolver().openInputStream(mUri);
                MultipartBody.Builder builder = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM);//表单类型
                RequestBody requestBody = new ProgressRequestBody(is, MediaType.parse("multipart/form-data"), new UploadListener() {
                    @Override
                    public void onProgressUpdate(int percentage) {
                        mProgressbar.setProgress(percentage);
                    }
    
                    @Override
                    public void onError() {
    
                    }
    
                    @Override
                    public void onFinish() {
    
                    }
                });
                //zzz是接口的参数名
                builder.addFormDataPart("zzz", Uri.encode(mLocalFileInfo.getName()), requestBody);
                List<MultipartBody.Part> parts = builder.build().parts();
                NetworkManager.getInstance().create(Api.class)
                        .addApp(params, parts)
                        .enqueue(new Callback<ResponseBody>() {
                            @Override
                            public void onResponse(retrofit2.Call<ResponseBody> call, Response<ResponseBody> response) {
                                mProgressbar.setVisibility(View.GONE);
    
                            @Override
                            public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
                                mProgressbar.setVisibility(View.GONE);
                            }
                        });
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    
     private RequestBody toRequestBody(String value) {
            return RequestBody.create(MediaType.parse("multipart/form-data"), value);
        }
    
    
    //附上ProgressRequestBody 代码
    public class ProgressRequestBody extends RequestBody {
        private File mFile;
        private InputStream mFis;
        private MediaType mMediaType;
        private UploadListener mListener;
        private int mEachBufferSize = 2048;
    
        public ProgressRequestBody(final File file, final MediaType mediaType, final UploadListener listener) {
            mFile = file;
            mMediaType = mediaType;
            mListener = listener;
        }
    
        public ProgressRequestBody(final InputStream fis, final MediaType mediaType, final UploadListener listener) {
            mFis = fis;
            mMediaType = mediaType;
            mListener = listener;
        }
    
        @Override
        public MediaType contentType() {
            return mMediaType;
        }
    
        @Override
        public void writeTo(BufferedSink sink) throws IOException {
            long fileLength = 0;
            InputStream in = null;
            if (mFile != null) {
                fileLength = mFile.length();
                in = new FileInputStream(mFile);
            } else {
                fileLength = mFis.available();
                in = mFis;
            }
            byte[] buffer = new byte[mEachBufferSize];
            long uploaded = 0;
            try {
                int read;
                Handler handler = new Handler(Looper.getMainLooper());
                while ((read = in.read(buffer)) != -1) {
                    // update progress on UI thread
                    handler.post(new ProgressUpdater(uploaded, fileLength));
                    uploaded += read;
                    sink.write(buffer, 0, read);
                }
            } finally {
                in.close();
            }
        }
    
        private class ProgressUpdater implements Runnable {
            private long mUploaded;
            private long mTotal;
    
            public ProgressUpdater(long uploaded, long total) {
                mUploaded = uploaded;
                mTotal = total;
            }
    
            @Override
            public void run() {
                mListener.onProgressUpdate((int) (100 * mUploaded / mTotal));
            }
        }
    
    public interface UploadListener {
        void onProgressUpdate(int percentage);
        void onError();
        void onFinish();
    }
    
    二:下载文件到公共目录

    原本是准备也采用retrofit2 直接下载到download文件夹里
    写了一半后 老板说直接下载到本地然后复制到download文件夹

    相关文章

      网友评论

          本文标题:Android 11 公共目录Download文件操作

          本文链接:https://www.haomeiwen.com/subject/ndmwcrtx.html