Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
231 views
in Technique[技术] by (71.8m points)

Why does PDF is not able to upload in PHP API for Android Pie, Q and R using Retrofit 2 in Android/Java? [Not solved]

I tried to upload a PDF file [Not Image] in PHP API from Android, and I'm getting 400 with this exception:

{"head":{"StatusValue":400,"StatusText":"Failed"},"body":{"Error":"Missing required property fileId"}}

I'm getting 200 request code, when I'm doing in Postman:

enter image description here

Now, Android code:

    @Multipart
    @POST("eligibity/auth/attachment/upload/add")
    Call<ResponseBody> uploadFile(@Part MultipartBody.Part file, @Part("fileName") RequestBody name, @Part("body") JSONObject body);

 
 private void uploadPDF(String path) {

        String pdfname = String.valueOf(Calendar.getInstance().getTimeInMillis());

        File file = new File(path);
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("fileName", file.getName(), requestBody);
        RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), pdfname);

        try {
            JSONObject sJsonAttachment = new JSONObject();
            JSONObject body = new JSONObject();
            sJsonAttachment.put("appointmentId", AdapterCollections.clsClaimDiscussionList.get(position).appointment_id);
            sJsonAttachment.put("createdBy", Integer.parseInt(preferenceManager.getUserId()));
            sJsonAttachment.put("customerId", Integer.parseInt(preferenceManager.getCustomerId()));
            sJsonAttachment.put("encounterId", AdapterCollections.clsClaimDiscussionList.get(position).encounter_id);
            sJsonAttachment.put("expiryDate", Utility.getCurrentDate("MM-DD-YY"));
            sJsonAttachment.put("fbType", 4);
            sJsonAttachment.put("fileId", 0);
            sJsonAttachment.put("fileName", "name");
            sJsonAttachment.put("insTpaPatId", 0);
            sJsonAttachment.put("isActive", 1);
            sJsonAttachment.put("messageId", AdapterCollections.clsClaimDiscussionList.get(position).log_messages.get(position).log_id);
            sJsonAttachment.put("patientId", AdapterCollections.clsClaimDiscussionList.get(position).patient_id);
            sJsonAttachment.put("recType", "");
            sJsonAttachment.put("reportDate", Utility.getCurrentDate("DD-MM-YYYY"));
            sJsonAttachment.put("siteId", Integer.parseInt(preferenceManager.getSiteId()));
            sJsonAttachment.put("type", 4);
            sJsonAttachment.put("uploadDate", Utility.getCurrentDate("MMDDYY"));

           // body.put("body", sJsonAttachment);

            ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
            assert apiCall != null;
            apiCall.uploadFile(fileToUpload, filename, sJsonAttachment).enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(@NotNull Call<ResponseBody> call, @NotNull Response<ResponseBody> response) {
                    try {
                        showLog("STATUS: " + response.code());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFailure(@NotNull Call<ResponseBody> call, @NotNull Throwable t) {
                    showLog("FAILED: "+ t.getMessage());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

I know that I'm doing somewhere small mistakes, but not able to spot that.

If I used part then this error: Missing required property fileId, and if I use query then this error: must be object.

Update

Regarding Path:

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="/storage/emulated/0" path="."/>
</paths>

Intent to open PDF chooser:

 private void fileDialog() {
    Intent intent = new Intent().setType("application/pdf").setAction(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    
    startActivityForResult(Intent.createChooser(intent, "Select PDF file"), 123);
}

I followed this https://stackoverflow.com/a/62830720/12630878 answer to getPath, but, I'm NOT getting path properly.

Higher version means: 28 to 30

Higher Version URI: URI: content://com.android.providers.media.documents/document/document%3A31

FROM RECENT, If I'll choose PDF, then cursor is returning null:

 if (cursor.moveToFirst()) {
        return cursor.getString(column_index);
        }

FROM DOWNLOADS, if I'll choose PDF, then NumberFormatException coming on this line: URI: content://com.android.providers.downloads.documents/document/msf%3A27

Exception: java.lang.NumberFormatException: For input string: "msf:27"

LINE NO: Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));

FileUtils class: https://drive.google.com/file/d/1S5-Sdp_CCSXXsOsZxwuhv0F5_CtH2EQO/view?usp=sharing

Search this method where I'm getting Path:

public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPathForAllVersion(context, uri);
            //   String path = getFilePathFromURI(context, uri);
            showLog("isPATH: " + path);
            if (checkNull(path) && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
    }
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You api accept only two parameters but you passed three parameters that's why you getting error.

so API method should be

@Multipart
@POST("eligibity/auth/attachment/upload/add")
Call<ResponseBody> uploadFile(
    @Part("body") RequestBody description,
    @Part MultipartBody.Part file
);

And update your uploadPDF() like below

    private void uploadPDF(String path) {

   //json data
    JSONObject sJsonAttachment = new JSONObject();
            JSONObject body = new JSONObject();
            sJsonAttachment.put("appointmentId", AdapterCollections.clsClaimDiscussionList.get(position).appointment_id);
            sJsonAttachment.put("createdBy", Integer.parseInt(preferenceManager.getUserId()));
            sJsonAttachment.put("customerId", Integer.parseInt(preferenceManager.getCustomerId()));
            sJsonAttachment.put("encounterId", AdapterCollections.clsClaimDiscussionList.get(position).encounter_id);
            sJsonAttachment.put("expiryDate", Utility.getCurrentDate("MM-DD-YY"));
            sJsonAttachment.put("fbType", 4);
            sJsonAttachment.put("fileId", 0);
            sJsonAttachment.put("fileName", "name");
            sJsonAttachment.put("insTpaPatId", 0);
            sJsonAttachment.put("isActive", 1);
            sJsonAttachment.put("messageId", AdapterCollections.clsClaimDiscussionList.get(position).log_messages.get(position).log_id);
            sJsonAttachment.put("patientId", AdapterCollections.clsClaimDiscussionList.get(position).patient_id);
            sJsonAttachment.put("recType", "");
            sJsonAttachment.put("reportDate", Utility.getCurrentDate("DD-MM-YYYY"));
            sJsonAttachment.put("siteId", Integer.parseInt(preferenceManager.getSiteId()));
            sJsonAttachment.put("type", 4);
            sJsonAttachment.put("uploadDate", Utility.getCurrentDate("MMDDYY"));




   // create RequestBody instance from file
    File file=new File(path);
    RequestBody requestFile =
            RequestBody.create(
                         MediaType.parse(Files.probeContentType(file.toPath()))),
                         file
             );

    // MultipartBody.Part is used to send also the actual file name
    MultipartBody.Part fileBody =
            MultipartBody.Part.createFormData("fileName", file.getName(), requestFile);

    // add another part within the multipart request
     RequestBody bodyJsonAttachment =
            RequestBody.create(
                    okhttp3.MultipartBody.FORM, sJsonAttachment.toString());


    ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
            assert apiCall != null;
            apiCall.uploadFile(fileBody, bodyJsonAttachment).enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(@NotNull Call<ResponseBody> call, @NotNull Response<ResponseBody> response) {
                    try {
                        showLog("STATUS: " + response.code());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFailure(@NotNull Call<ResponseBody> call, @NotNull Throwable t) {
                    showLog("FAILED: "+ t.getMessage());
                }
            });

 }

Note : if you getting warning error on mime type, update it


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...