如何在Android / Java中使用AsyncTask将URI传递给API?

发布时间:2020-07-06 20:17

我正在尝试使用以下方法通过Web API发送PDF文件:

public static <function> JSONObject uploadFile(String url, Context context, JSONObject jsondata, String imagepath) {
        sJsonObj = null;
        sb = null;

        try {
            sUrl = new URL(url);

            sHttpUrlConnection = (HttpURLConnection) sUrl.openConnection();
            sHttpUrlConnection.setDoInput(true);
            sHttpUrlConnection.setDoOutput(true);
            sHttpUrlConnection.setUseCaches(false);
            sHttpUrlConnection.setReadTimeout(sTimeout);
            sHttpUrlConnection.setConnectTimeout(sTimeout);
            sHttpUrlConnection.setRequestMethod(HttpPost.METHOD_NAME);
            sHttpUrlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
            sHttpUrlConnection.setRequestProperty("fileName", imagepath);
            sHttpUrlConnection.setRequestProperty("Connection", "Keep-Alive");


            sPrintWriter = new PrintWriter(sHttpUrlConnection.getOutputStream());

            sPrintWriter.append(TWO_HYPHENS + BOUNDARY)
                    .append(LINE_END)
                    .append("Content-Disposition: form-data;name=\"body\"")
                    .append(LINE_END)
                    .append(LINE_END)
                    .append(jsondata.toString())
                    .append(LINE_END)

                    .append(TWO_HYPHENS + BOUNDARY)
                    .append(LINE_END)
                    .append("Content-Disposition: form-data; name=\"fileName\"; filename=\"" + new File(imagepath).getAbsoluteFile() + "\"")
                    .append(LINE_END)
                    .append("Content-Type: "
                            + URLConnection.guessContentTypeFromName(imagepath))
                    .append(LINE_END)
                    .append("Content-Transfer-Encoding: binary")
                    .append(LINE_END)
                    .append(LINE_END);

            sPrintWriter.flush();

            FileInputStream fileStream = new FileInputStream(imagepath);
            byte[] buffer = new byte[4096];
            int bytesRead = -1;
            while ((bytesRead = fileStream.read(buffer)) != -1) {
                sHttpUrlConnection.getOutputStream().write(buffer, 0, bytesRead);
            }

            fileStream.close();

            sPrintWriter.append(LINE_END);
            sPrintWriter.append(TWO_HYPHENS);
            sPrintWriter.append(BOUNDARY);
            sPrintWriter.append(TWO_HYPHENS);
            sPrintWriter.flush();
            sHttpUrlConnection.getOutputStream().close();

            if (true) {
                BufferedReader reader = null;
                reader = new BufferedReader(new InputStreamReader(sHttpUrlConnection.getInputStream()));
                sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                reader.close();

                sJsonObj = new JSONObject(sb.toString());
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sHttpUrlConnection.disconnect();
        }
        return sJsonObj;
    }

如果仔细看一下uploadFile方法的参数,那么您会发现最后一个参数是filePath

在过去2天不断搜索Stack溢出后,我发现在某些较新的Android版本中找不到filePath。

我的应用支持 Api级别21到30 ,因此每个人都建议仅通过传递URI进行尝试。

现在,在这个uploadFile方法中,如果我尝试将最后一个参数从String更改为Uri,那么编译器错误的出现就很多了。现在我不明白该方法应该改变什么?

任何人都可以用相同的方法发表一些修改后的答案,这一点将不胜感激。

FileNotFound异常即将到来,如果我通过uri.getPath

回答1

您可以尝试吗?我提供一些代码:

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            holder.setIsRecyclable(false);
            ItemsGetterSetter item = itemArrayList.get(holder.getAdapterPosition())
    
            itemAvailableArray.add(holder.getAdapterPosition(), item.isItemAvailable());
            itemAmountArray.add(holder.getAdapterPosition(), item.getAmount());
            holder.itemNameTxt.setText(item.getItemName());
            holder.isAvailableSwitch.setChecked(item.isItemAvailable());
            holder.itemAmountEditTxt.setText(String.valueOf(item.getAmount()));
    
        }