ভলির সাথে অ্যান্ড্রয়েডে কীভাবে একটি "মাল্টিপার্ট / ফর্ম-ডেটা" পোষ্ট পাঠাতে হয়


89

multipart/form-dataভলির সাথে এখনও কি কেউ অ্যান্ড্রয়েডে কোনও পোষ্ট প্রেরণ সম্পাদন করতে সক্ষম হয়েছে ? image/pngআমাদের সার্ভারে একটি পোষ্ট অনুরোধ ব্যবহার করে একটি আপলোড করার চেষ্টা করতে আমার কোনও সাফল্য হয়নি এবং কারও কাছে থাকলে আগ্রহী।

আমি বিশ্বাস করি এটি করার ডিফল্ট উপায়টি ক্লাসে ওভাররাইড করা public byte[] getPostBody()এবং সীমানার জন্য একটি ফাঁকা শিরোনাম কী দিয়ে সেখানে Request.javaসংযুক্ত করা File। তবে আমার ফাইল রূপান্তর Stringজন্য Map<String, String> postParamsএবং তারপর এনকোড থাকার আবার ভোঁতা এবং সত্যিই মার্জিত না বলে মনে হয়। এছাড়াও আমি আমার প্রয়াসে ব্যর্থ হয়েছি। এই লাইব্রেরিতে স্যুইচ করা থেকে আমাদের পিছনে রাখা কেবল সত্যই এটি।

যাইহোক, সমস্ত চিন্তাভাবনা এবং উত্তর অত্যন্ত প্রশংসা করা হয়। আপনার সাহায্যের জন্য ধন্যবাদ।

উত্তর:


75

আমি এতে ভুল হতে পারি তবে আমি মনে করি এটির জন্য আপনাকে নিজের প্রয়োগ করতে হবে com.android.volley.toolbox.HttpStackকারণ HurlStackডিফল্টগুলি ( যদি সংস্করণ> জিঞ্জারব্রেড বা HttpClientStack) এর সাথে চুক্তি করে না multipart/form-data

সম্পাদনা করুন:

এবং সত্যিই আমি ভুল ছিল। MultipartEntityঅনুরোধে এটি ব্যবহার করে আমি এটি করতে সক্ষম হয়েছি :

public class MultipartRequest extends Request<String> {

    private MultipartEntity entity = new MultipartEntity();

    private static final String FILE_PART_NAME = "file";
    private static final String STRING_PART_NAME = "text";

    private final Response.Listener<String> mListener;
    private final File mFilePart;
    private final String mStringPart;

    public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, File file, String stringPart)
    {
        super(Method.POST, url, errorListener);

        mListener = listener;
        mFilePart = file;
        mStringPart = stringPart;
        buildMultipartEntity();
    }

    private void buildMultipartEntity()
    {
        entity.addPart(FILE_PART_NAME, new FileBody(mFilePart));
        try
        {
            entity.addPart(STRING_PART_NAME, new StringBody(mStringPart));
        }
        catch (UnsupportedEncodingException e)
        {
            VolleyLog.e("UnsupportedEncodingException");
        }
    }

    @Override
    public String getBodyContentType()
    {
        return entity.getContentType().getValue();
    }

    @Override
    public byte[] getBody() throws AuthFailureError
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try
        {
            entity.writeTo(bos);
        }
        catch (IOException e)
        {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response)
    {
        return Response.success("Uploaded", getCacheEntry());
    }

    @Override
    protected void deliverResponse(String response)
    {
        mListener.onResponse(response);
    }
}

এটি বেশ কাঁচা তবে আমি এটি একটি চিত্র এবং একটি সাধারণ স্ট্রিং দিয়ে চেষ্টা করেছি এবং এটি কার্যকর। প্রতিক্রিয়া একটি স্থানধারক, এক্ষেত্রে কোনও প্রতিক্রিয়া স্ট্রিং ফেরত দেওয়ার পক্ষে খুব বেশি অর্থবোধ করে না। মাল্টিপার্টএনটিটি ব্যবহার করতে আমার অ্যাপাচি httpsime ব্যবহার করতে সমস্যা হয়েছিল তাই আমি এই https://code.google.com/p/httpclientandroidlib/ ব্যবহার করেছি এর চেয়ে ভাল উপায় আছে কিনা তা জানি না। আশা করি এটা সাহায্য করবে.

সম্পাদনা করুন

আপনি httpclientandroidlib ব্যবহার না করে httpsime ব্যবহার করতে পারেন, একমাত্র নির্ভরতা হ'ল পোস্টকোর।


4
@ লগ_এটিএজি: এটি বড় ফাইলগুলিকে সমর্থন করবে না। বা এটি কোনও অগ্রগতি বারকে সমর্থন করবে না। কারণ হ'ল এটি সমস্ত ডেটা একক বাইটে রাখবে []। বড় ফাইলগুলির জন্য, আপনি একটি ইনপুট স্ট্রিম ব্যবহার করতে চান, যা ভলির মাধ্যমে সম্ভব বলে মনে হচ্ছে না। তবে তারা (ভল্লি ডেভস) পাশাপাশি বলেছে যে ভলি বড় ফাইলগুলির জন্য তৈরি হয় না।
প্যাট্রিক বুস

9
@ আলেক্স আপনি কীভাবে মাল্টিপার্টআরকেস্ট ব্যবহার করবেন কিছু কোড রাখতে পারেন?
কৃষ্ণ শ্রেষ্ঠ

4
আমি এই ত্রুটিটি পেয়েছি: java.lang.NoClassDefFoundError: org.apache.http.entity.ContentType
মিলাদ

4
অ্যাপাচি http ব্যবহার করে মাল্টিপার্টেনটিটি। আমি এপাচি মাল্টিপার্ট লাইব্রেরি ছাড়াই এটি করতে চাই। কিভাবে আমি এটি করতে পারব.
জোসেফএম

4
রিটার্ন সত্তা.জেটকন্টেন্টটাইপ ()। getValue (); ত্রুটি
ভোলাডাইমার কুলিক 10'50

14

আই / ও (প্রায় 4:05) তে উপস্থাপনায় যেমন উল্লেখ করা হয়েছে, ভোলি বড় পেওডের জন্য "ভয়ঙ্কর"। যেহেতু আমি এটি বুঝতে পেরেছি তার অর্থ (বড়) ফাইলগুলি গ্রহণ / প্রেরণের জন্য ভোলি ব্যবহার না করা। কোডটি দেখে মনে হচ্ছে এটি এমনকি মাল্টিপার্ট ফর্ম ডেটা হ্যান্ডেল করার জন্য ডিজাইন করা হয়নি (যেমন, অনুরোধ.জাবায় হার্ডকোডযুক্ত "অ্যাপ্লিকেশন / x-www-form-urlencoded" সহ getBodyContentType () রয়েছে; HTTPClientStack :: createHttpRequest () কেবলমাত্র বাইট পরিচালনা করতে পারে [], ইত্যাদি ...)। সম্ভবত আপনি এমন বাস্তবায়ন তৈরি করতে সক্ষম হবেন যা মাল্টিপার্ট হ্যান্ডেল করতে পারে তবে আমি যদি আপনি থাকতাম তবে আমি কেবল এইচটিপিপ্লিয়েন্টটি সরাসরি মাল্টিপার্টএন্টিটির সাথে ব্যবহার করব:

    HttpPost req = new HttpPost(composeTargetUrl());
    MultipartEntity entity = new MultipartEntity();
    entity.addPart(POST_IMAGE_VAR_NAME, new FileBody(toUpload));
    try {
        entity.addPart(POST_SESSION_VAR_NAME, new StringBody(uploadSessionId));
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    }
    req.setEntity(entity);

আপনার আরও নতুন এইচটিপিপিপ্লায়েন্টের প্রয়োজন হতে পারে (যেমন বিল্ট-ইন নয়) বা আরও ভাল, নতুন এইচটিটিপি ক্লিনেন্টের সাথে ভলি ব্যবহার করুন


4
সহায়তার জন্য অনেক ধন্যবাদ, আপনার ব্লগটি এমন কিছু আমাকে দেখায় যা আমার কাছে না হওয়া উচিত। অ্যালেক্সের কাজের সমাধান না পেয়ে আমি উপরের লিঙ্কটির মাধ্যমে আপনার পরামর্শটি চেষ্টা করব। চিয়ার্স!
অলডায়আমাজিং

হ্যালো @ ওগ্রে_বিজিআর, আপনি কীভাবে আপনার স্ন্যাপ কোড ব্যবহার করে কোনও চিত্র আপলোড করবেন তা সম্পর্কে একটি সম্পূর্ণ নমুনা সরবরাহ করতে পারেন। আমি কেবলমাত্র অনেকগুলি নমুনার চেষ্টা করেছি, তবে সেগুলি খুব পুরানো এবং আমি এটি কাজ করতে পারি না। আপনাকে ধন্যবাদ
থিয়াগো

মাল্টিপার্ট এখন সমর্থিত। এই পৃষ্ঠায় অন্যান্য উত্তর তাকান।
মার্টিন কনেকেনি

4
@ মার্টিনকোননি দয়া করে আপনার মন্তব্যে সঠিক উত্তরটি লিঙ্ক করুন যাতে অন্যান্য ব্যবহারকারীরা এটিতে সরাসরি যেতে পারেন
অগনিয়ান ২

আমি কীভাবে একটি একক অনুরোধে মাল্টিপার্ট ফর্ম্যাট সহ অন্যান্য পরামিতিগুলি যুক্ত করতে সক্ষম হতে পারি?
ক্যাসিলা 16

10

আপডেট 2015/08/26:

আপনি যদি অবহেলিত HTTPEntity ব্যবহার করতে না চান, তবে এখানে আমার কাজের নমুনা কোড (এএসপি. নেট ওয়েবএপিআই দিয়ে পরীক্ষিত)

MultipartActivity.java

package com.example.volleyapp;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.view.Menu;
import android.view.MenuItem;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.example.volleyapp.BaseVolleyRequest;
import com.example.volleyapp.VolleySingleton;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class MultipartActivity extends Activity {

    final Context mContext = this;
    String mimeType;
    DataOutputStream dos = null;
    String lineEnd = "\r\n";
    String boundary = "apiclient-" + System.currentTimeMillis();
    String twoHyphens = "--";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1024 * 1024;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multipart);             

        Drawable drawable = ContextCompat.getDrawable(mContext, R.drawable.ic_action_file_attachment_light);
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
        final byte[] bitmapData = byteArrayOutputStream.toByteArray();
        String url = "http://192.168.1.100/api/postfile";

        mimeType = "multipart/form-data;boundary=" + boundary;

        BaseVolleyRequest baseVolleyRequest = new BaseVolleyRequest(1, url, new Response.Listener<NetworkResponse>() {
            @Override
            public void onResponse(NetworkResponse response) {

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        }) {
            @Override
            public String getBodyContentType() {
                return mimeType;
            }

            @Override
            public byte[] getBody() throws AuthFailureError {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                dos = new DataOutputStream(bos);
                try {
                    dos.writeBytes(twoHyphens + boundary + lineEnd);
                    dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                            + "ic_action_file_attachment_light.png" + "\"" + lineEnd);
                    dos.writeBytes(lineEnd);
                    ByteArrayInputStream fileInputStream = new ByteArrayInputStream(bitmapData);
                    bytesAvailable = fileInputStream.available();

                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    buffer = new byte[bufferSize];

                    // read file and write it into form...
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                    while (bytesRead > 0) {
                        dos.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    }

                    // send multipart form data necesssary after file data...
                    dos.writeBytes(lineEnd);
                    dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                    return bos.toByteArray();

                } catch (IOException e) {
                    e.printStackTrace();
                }
                return bitmapData;
            }
        };

        VolleySingleton.getInstance(mContext).addToRequestQueue(baseVolleyRequest);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_multipart, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

বেসভোলিআরকয়েস্ট.জভা:

package com.example.volleyapp;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.JsonSyntaxException;


public class BaseVolleyRequest extends Request<NetworkResponse> {

    private final Response.Listener<NetworkResponse> mListener;
    private final Response.ErrorListener mErrorListener;

    public BaseVolleyRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
        super(0, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
    }

    public BaseVolleyRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
    }

    @Override
    protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
        try {
            return Response.success(
                    response,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (JsonSyntaxException e) {
            return Response.error(new ParseError(e));
        } catch (Exception e) {
            return Response.error(new ParseError(e));
        }
    }

    @Override
    protected void deliverResponse(NetworkResponse response) {
        mListener.onResponse(response);
    }

    @Override
    protected VolleyError parseNetworkError(VolleyError volleyError) {
        return super.parseNetworkError(volleyError);
    }

    @Override
    public void deliverError(VolleyError error) {
        mErrorListener.onErrorResponse(error);
    }
}

আপডেট শেষ

এটি আমার কাজের নমুনা কোড (কেবলমাত্র ছোট আকারের ফাইল দিয়ে পরীক্ষা করা):

public class FileUploadActivity extends Activity {

    private final Context mContext = this;
    HttpEntity httpEntity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file_upload);   

        Drawable drawable = getResources().getDrawable(R.drawable.ic_action_home);
        if (drawable != null) {
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            final byte[] bitmapdata = stream.toByteArray();
            String url = "http://10.0.2.2/api/fileupload";
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

            // Add binary body
            if (bitmapdata != null) {
                ContentType contentType = ContentType.create("image/png");
                String fileName = "ic_action_home.png";
                builder.addBinaryBody("file", bitmapdata, contentType, fileName);
                httpEntity = builder.build();

                MyRequest myRequest = new MyRequest(Request.Method.POST, url, new Response.Listener<NetworkResponse>() {
                    @Override
                    public void onResponse(NetworkResponse response) {
                        try {                            
                            String jsonString = new String(response.data,
                                    HttpHeaderParser.parseCharset(response.headers));
                            Toast.makeText(mContext, jsonString, Toast.LENGTH_SHORT).show();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(mContext, error.toString(), Toast.LENGTH_SHORT).show();                        
                    }
                }) {
                    @Override
                    public String getBodyContentType() {
                        return httpEntity.getContentType().getValue();
                    }

                    @Override
                    public byte[] getBody() throws AuthFailureError {
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        try {
                            httpEntity.writeTo(bos);
                        } catch (IOException e) {
                            VolleyLog.e("IOException writing to ByteArrayOutputStream");
                        }
                        return bos.toByteArray();
                    }
                };

                MySingleton.getInstance(this).addToRequestQueue(myRequest);
            }
        }
    }

    ...
}

public class MyRequest extends Request<NetworkResponse>

4
কিছু সার্ভারগুলি খুব পিক হয়। আপনার যদি সমস্যা থাকে তবে ";" এর মধ্যে একটি স্পেস যোগ করুন; এবং "ফাইলের নাম =" কন্টেন্ট-বিভাজন এবং "মাল্টিপার্ট / ফর্ম-ডেটা তৈরি করার সময়; সীমানা =" + সীমানা;
কেভিন

আপনার মন্তব্য @ কেভিনের জন্য ধন্যবাদ। আসলে, এটি পরীক্ষা করার জন্য আমার কাছে অনেকগুলি সার্ভার অ্যাপ্লিকেশন নেই :-)
বিএনকে

@HemsLodha: Pls আমার নিচের প্রশ্নগুলোর এ RacZo এর উত্তর কটাক্ষপাত করা stackoverflow.com/questions/32240177/... এটি আপনার বা না সাহায্য করতে পারেন :) দেখতে
BNK

4
আমি ভলির সাথে পোস্ট মাল্টিপার্ট অনুরোধ প্রেরণ করছি এবং অবশেষে url এ পরামিতি সেট করেছি এবং এটি কাজ করে works সাহায্যের জন্য ধন্যবাদ @ বিএনকে
জোসেফএম

@ ব্যবহারকারী 3561494 এটি ভিডিওর মতো বড় আকারের ফাইলগুলির জন্য প্রস্তাবিত নয়
বিএনকে

9

আপলোড অগ্রগতি সহ সম্পূর্ণ মাল্টিপার্ট অনুরোধ

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.util.CharsetUtils;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import com.beusoft.app.AppContext;

public class MultipartRequest extends Request<String> {

    MultipartEntityBuilder entity = MultipartEntityBuilder.create();
    HttpEntity httpentity;
    private String FILE_PART_NAME = "files";

    private final Response.Listener<String> mListener;
    private final File mFilePart;
    private final Map<String, String> mStringPart;
    private Map<String, String> headerParams;
    private final MultipartProgressListener multipartProgressListener;
    private long fileLength = 0L;

    public MultipartRequest(String url, Response.ErrorListener errorListener,
            Response.Listener<String> listener, File file, long fileLength,
            Map<String, String> mStringPart,
            final Map<String, String> headerParams, String partName,
            MultipartProgressListener progLitener) {
        super(Method.POST, url, errorListener);

        this.mListener = listener;
        this.mFilePart = file;
        this.fileLength = fileLength;
        this.mStringPart = mStringPart;
        this.headerParams = headerParams;
        this.FILE_PART_NAME = partName;
        this.multipartProgressListener = progLitener;

        entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        try {
            entity.setCharset(CharsetUtils.get("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        buildMultipartEntity();
        httpentity = entity.build();
    }

    // public void addStringBody(String param, String value) {
    // if (mStringPart != null) {
    // mStringPart.put(param, value);
    // }
    // }

    private void buildMultipartEntity() {
        entity.addPart(FILE_PART_NAME, new FileBody(mFilePart, ContentType.create("image/gif"), mFilePart.getName()));
        if (mStringPart != null) {
            for (Map.Entry<String, String> entry : mStringPart.entrySet()) {
                entity.addTextBody(entry.getKey(), entry.getValue());
            }
        }
    }

    @Override
    public String getBodyContentType() {
        return httpentity.getContentType().getValue();
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            httpentity.writeTo(new CountingOutputStream(bos, fileLength,
                    multipartProgressListener));
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {

        try {
//          System.out.println("Network Response "+ new String(response.data, "UTF-8"));
            return Response.success(new String(response.data, "UTF-8"),
                    getCacheEntry());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            // fuck it, it should never happen though
            return Response.success(new String(response.data), getCacheEntry());
        }
    }

    @Override
    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }

//Override getHeaders() if you want to put anything in header

    public static interface MultipartProgressListener {
        void transferred(long transfered, int progress);
    }

    public static class CountingOutputStream extends FilterOutputStream {
        private final MultipartProgressListener progListener;
        private long transferred;
        private long fileLength;

        public CountingOutputStream(final OutputStream out, long fileLength,
                final MultipartProgressListener listener) {
            super(out);
            this.fileLength = fileLength;
            this.progListener = listener;
            this.transferred = 0;
        }

        public void write(byte[] b, int off, int len) throws IOException {
            out.write(b, off, len);
            if (progListener != null) {
                this.transferred += len;
                int prog = (int) (transferred * 100 / fileLength);
                this.progListener.transferred(this.transferred, prog);
            }
        }

        public void write(int b) throws IOException {
            out.write(b);
            if (progListener != null) {
                this.transferred++;
                int prog = (int) (transferred * 100 / fileLength);
                this.progListener.transferred(this.transferred, prog);
            }
        }

    }
}

নমুনা ব্যবহার

protected <T> void uploadFile(final String tag, final String url,
            final File file, final String partName,         
            final Map<String, String> headerParams,
            final Response.Listener<String> resultDelivery,
            final Response.ErrorListener errorListener,
            MultipartProgressListener progListener) {
        AZNetworkRetryPolicy retryPolicy = new AZNetworkRetryPolicy();

        MultipartRequest mr = new MultipartRequest(url, errorListener,
                resultDelivery, file, file.length(), null, headerParams,
                partName, progListener);

        mr.setRetryPolicy(retryPolicy);
        mr.setTag(tag);

        Volley.newRequestQueue(this).add(mr);

    }

হাই @AZ_ - আমি আপনার কোডটি চেষ্টা করেছি: তবে আমি এই ত্রুটিটি পেয়েছি: মাল্টিপার্টআরকোয়েস্ট.জেটবডি: বাইটআরআউটপুট স্ট্রিমে আইওএক্সেপশন লেখা। দয়া করে সাহায্য করতে পারেন
থিয়াগো

আমার কাছে আপনার কোড নেই, অন্য প্রশ্ন খোলার জন্য আমি আরও ভাল কিছু প্রস্তাব করতে পারি না, সবচেয়ে সম্ভাব্য কারণ হ'ল আপনি ভার্চুয়াল মেমরির বাইরে চলে এসেছেন।
এজেড_

4
আমার ওপেন আই নতুন প্রশ্ন: স্ট্যাকওভারফ্লো.com / প্রশ্নস / ৩১৪745৫৫৫ / আপনি কি দয়া করে সাহায্য করতে পারেন? আপনাকে ধন্যবাদ
থিয়াগো

আমি কীভাবে একটি একক অনুরোধে মাল্টিপার্ট ফর্ম্যাট সহ অন্যান্য পরামিতিগুলি যুক্ত করতে সক্ষম হতে পারি?
ক্যাসিলা 16

@ ক্যাসিলারা অনুরোধের শিরোনামে কী মান যুক্ত করে।
এজেড_

8

দেবের জন্য একটি খুব সহজ পদ্ধতির যারা কেবলমাত্র মাল্টিপার্ট অনুরোধে POST পরামিতি প্রেরণ করতে চান approach

অনুরোধ.জভা প্রসারিত ক্লাসে নিম্নলিখিত পরিবর্তনগুলি করুন

প্রথমে এই ধ্রুবকগুলি সংজ্ঞায়িত করুন:

String BOUNDARY = "s2retfgsGSRFsERFGHfgdfgw734yhFHW567TYHSrf4yarg"; //This the boundary which is used by the server to split the post parameters.
String MULTIPART_FORMDATA = "multipart/form-data;boundary=" + BOUNDARY;

আপনার জন্য একটি পোস্ট বডি তৈরি করতে একটি সহায়ক ফাংশন যুক্ত করুন:

private String createPostBody(Map<String, String> params) {
        StringBuilder sbPost = new StringBuilder();
        if (params != null) {
            for (String key : params.keySet()) {
                if (params.get(key) != null) {
                    sbPost.append("\r\n" + "--" + BOUNDARY + "\r\n");
                    sbPost.append("Content-Disposition: form-data; name=\"" + key + "\"" + "\r\n\r\n");
                    sbPost.append(params.get(key).toString());
                }
            }
        }
        return sbPost.toString();
    } 

GetBody () এবং getBodyContentType ওভাররাইড করুন

public String getBodyContentType() {
    return MULTIPART_FORMDATA;
}

public byte[] getBody() throws AuthFailureError {
        return createPostBody(getParams()).getBytes();
}

4
খুব সহজ এবং পুরোপুরি কাজ করে! আমি যে sbPost.append("--" + BOUNDARY + "--");এপিআই ব্যবহার করছি তার জন্য ফিরে আসার আগে আমাকে ডানদিকে যেতে হবে
সাইরেনস

ধন্যবাদ! এটি আমার পক্ষে ফ্রন্ট-এন্ডে কাজ করেছে তবে ব্যাক-এন্ডের বিশেষত নোডেজগুলি এটি পার্স করতে সমস্যা হচ্ছে? আপনি কি এর কোন অভিজ্ঞতা পেয়েছেন?
Woppi

4
দুঃখিত, আমার ব্যাকএন্ডের অভিজ্ঞতা নেই :(
অর্পিত রতন

@ অরপিট ধন্যবাদ, আমি এর পরিবর্তে এই সহায়ক সহায়ক শ্রেণিটি ব্যবহার করে আমার সমস্যা সমাধান করতে সক্ষম হয়েছি gist.github.com/anggadarkprince/…
ওয়াপিপি

সহজ এবং দরকারী। এই পদ্ধতির ভাগ করে নেওয়ার জন্য ধন্যবাদ!
lgallard

4

এসও প্রথম উত্তর।

আমি একই সমস্যার মুখোমুখি হয়েছি এবং @ অ্যালেক্সের কোডটি খুব সহায়ক বলে খুঁজে পেয়েছি। আমি হ্যাশম্যাপের মাধ্যমে প্রয়োজনীয় parseNetworkResponse()যতগুলি প্যারামিটারগুলিতে পাস করার জন্য কিছু সাধারণ পরিবর্তন করেছি এবং মূলত স্ট্রিংরয়েস্ট থেকে অনুলিপি করেছি। আমি অনলাইনে অনুসন্ধান করেছি এবং এত অবাক হয়েছি যে এইরকম একটি সাধারণ কাজের খুব কমই উত্তর দেওয়া হয়। যাইহোক, আমি আশা করি কোডটি সহায়তা করতে পারে:

public class MultipartRequest extends Request<String> {

private MultipartEntity entity = new MultipartEntity();

private static final String FILE_PART_NAME = "image";

private final Response.Listener<String> mListener;
private final File file;
private final HashMap<String, String> params;

public MultipartRequest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener, File file, HashMap<String, String> params)
{
    super(Method.POST, url, errorListener);

    mListener = listener;
    this.file = file;
    this.params = params;
    buildMultipartEntity();
}

private void buildMultipartEntity()
{
    entity.addPart(FILE_PART_NAME, new FileBody(file));
    try
    {
        for ( String key : params.keySet() ) {
            entity.addPart(key, new StringBody(params.get(key)));
        }
    }
    catch (UnsupportedEncodingException e)
    {
        VolleyLog.e("UnsupportedEncodingException");
    }
}

@Override
public String getBodyContentType()
{
    return entity.getContentType().getValue();
}

@Override
public byte[] getBody() throws AuthFailureError
{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try
    {
        entity.writeTo(bos);
    }
    catch (IOException e)
    {
        VolleyLog.e("IOException writing to ByteArrayOutputStream");
    }
    return bos.toByteArray();
}

/**
 * copied from Android StringRequest class
 */
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
    String parsed;
    try {
        parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
    } catch (UnsupportedEncodingException e) {
        parsed = new String(response.data);
    }
    return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}

@Override
protected void deliverResponse(String response)
{
    mListener.onResponse(response);
}

এবং আপনি ক্লাসটি নিম্নলিখিত হিসাবে ব্যবহার করতে পারেন:

    HashMap<String, String> params = new HashMap<String, String>();

    params.put("type", "Some Param");
    params.put("location", "Some Param");
    params.put("contact",  "Some Param");


    MultipartRequest mr = new MultipartRequest(url, new Response.Listener<String>(){

        @Override
        public void onResponse(String response) {
            Log.d("response", response);
        }

    }, new Response.ErrorListener(){

        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("Volley Request Error", error.getLocalizedMessage());
        }

    }, f, params);

    Volley.newRequestQueue(this).add(mr);

0

আরও একটি সমাধান, পেওলড সহ উচ্চ কার্যকারিতা সহ খুব হালকা:

অ্যান্ড্রয়েড অ্যাসিঙ্ক্রোনাস এইচটিপি ক্লায়েন্ট লাইব্রেরি: http://loopj.com/android-async-http/

private static AsyncHttpClient client = new AsyncHttpClient();

private void uploadFileExecute(File file) {

    RequestParams params = new RequestParams();

    try { params.put("photo", file); } catch (FileNotFoundException e) {}

    client.post(getUrl(), params,

        new AsyncHttpResponseHandler() {

            public void onSuccess(String result) {

                Log.d(TAG,"uploadFile response: "+result);

            };

            public void onFailure(Throwable arg0, String errorMsg) {

                Log.d(TAG,"uploadFile ERROR!");

            };

        }

    );

}

4
বড় ফাইল আকার মেমরি ব্যতিক্রম বাদ দেয়
রবি

4
@ রাভি +1 এই লাইব্রেরি বড় ফাইলগুলি আপলোড করার জন্য ব্যর্থ হয়েছে
অ্যান্টন

আপনি যদি বড় ফাইলগুলি পাঠাতে চান তবে মাল্টিপার্টের জন্য অ্যাপাচি মাইম লাইব্রেরি ব্যবহার করুন এবং এই লাইব্রেরিটি ব্যবহার করে এটি পোস্ট করুন।
রবি

আপনার চিত্রের আকার সংকুচিত করতে হবে এবং তারপরে চিত্রটি আপলোড করতে এই লাইব্রেরিটি ব্যবহার করতে হবে আমি নীচের URL থেকে সমাধান পেয়েছি: প্রোগ্রামারগুরু / অ্যান্ড্রয়েড- টিউটোরিয়াল/… আমি আশা করি এটি কারও সময় সাশ্রয় করতে পারে।
মিলন শেঠ

@ রাভি অ্যাপাচি মাইম আপনাকে দ্বন্দ্ব এবং নকল শ্রেণীর ত্রুটি দেবে।
মুহাম্মদ সাকিব

0

ভলি অ্যান্ড্রয়েড ব্যবহার করে ফাইল আপলোড করার জন্য এখানে সরল সমাধান এবং সম্পূর্ণ উদাহরণ

1) গ্রেডল আমদানি

compile 'dev.dworks.libs:volleyplus:+'

2) এখন একটি ক্লাস রিকোয়েস্টম্যানেজার তৈরি করুন

public class RequestManager {
    private static RequestManager mRequestManager;
    /**
     * Queue which Manages the Network Requests :-)
     */
    private static RequestQueue mRequestQueue;
    // ImageLoader Instance

    private RequestManager() {

    }

    public static RequestManager get(Context context) {

        if (mRequestManager == null)
            mRequestManager = new RequestManager();

        return mRequestManager;
    }

    /**
     * @param context application context
     */
    public static RequestQueue getnstance(Context context) {

        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(context);
        }

        return mRequestQueue;

    }


}

3) এখন ফাইল ওয়েব সার্ভিস আপলোড করার জন্য অনুরোধ পরিচালনা করতে একটি ক্লাস তৈরি করুন

public class WebService {
    private RequestQueue mRequestQueue;
    private static WebService apiRequests = null;

    public static WebService getInstance() {
        if (apiRequests == null) {
            apiRequests = new WebService();
            return apiRequests;
        }
        return apiRequests;
    }
    public void updateProfile(Context context, String doc_name, String doc_type, String appliance_id, File file, Response.Listener<String> listener, Response.ErrorListener errorListener) {
        SimpleMultiPartRequest request = new SimpleMultiPartRequest(Request.Method.POST, "YOUR URL HERE", listener, errorListener);
//        request.setParams(data);
        mRequestQueue = RequestManager.getnstance(context);
        request.addMultipartParam("token", "text", "tdfysghfhsdfh");
        request.addMultipartParam("parameter_1", "text", doc_name);
        request.addMultipartParam("dparameter_2", "text", doc_type);
        request.addMultipartParam("parameter_3", "text", appliance_id);
            request.addFile("document_file", file.getPath());

        request.setFixedStreamingMode(true);
        mRequestQueue.add(request);
    }
}

4) এবং এখন পরিষেবাটি হিট করতে পদ্ধতিটিকে এভাবে লাইক করুন

public class Main2Activity extends AppCompatActivity implements Response.ErrorListener, Response.Listener<String>{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Button button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                uploadData();
            }
        });
    }

    private void uploadData() {
        WebService.getInstance().updateProfile(getActivity(), "appl_doc", "appliance", "1", mChoosenFile, this, this);
    }

    @Override
    public void onErrorResponse(VolleyError error) {

    }

    @Override
    public void onResponse(String response) {
     //Your response here 
    }
}

আমি আপনার সমাধান সহ এই ত্রুটিটি পাচ্ছি: java.lang.NoSuchMethodError: সরাসরি কোনও পদ্ধতি নেই <আইএনটি> (আইলজভা / ল্যাং / স্ট্রিং; এলকম / অ্যান্ড্রয়েড / ভলি / অনুরোধ $ অগ্রাধিকার; এলকম / অ্যান্ড্রয়েড / ভলি / প্রতিক্রিয়া $ ত্রুটিলিস্টনার; এলকম / অ্যান্ড্রয়েড / ভল্লি / রিট্রিপলিসি;) ক্লাস এলকম / অ্যান্ড্রয়েড / ভল্লি / অনুরোধে ভি; বা এর সুপার ক্লাস ('com.android.volley.Request এর ঘোষণা' /data/data/com.footballscout.app/files/instant-run/dex/slice-slice_4-classes.dex এ প্রকাশিত হয়েছে
স্পাইজেপ

আপনি ক্লাসে সঠিক গ্রেডেল এবং আমদানি পরীক্ষা করেছেন?
তাত্ক্ষণিক শিক্ষার্থী

আমি এখানে বর্ণিত একবার এবং আপনার উত্তরটি ব্যবহার করেছি github.com/DWorkS/VolleyPlus
স্পাইজেপ

4
এবং আপনি যে ক্লাসটি ব্যবহার করছেন সে ক্ষেত্রে আপনার আমদানিগুলি পরীক্ষা করুন কারণ আপনি অবশ্যই ভলির জন্য সঠিক আমদানি ব্যবহার করবেন না যেমন ত্রুটি শ্রোতার দিকে নির্দেশ করছে, পুনরায় আমদানি পরীক্ষা করুন এবং গ্রেড করুন তবে প্রকল্পটি সাফ করুন, ধন্যবাদ, যদি আপনি এখনও কিছু খুঁজে পান সমস্যা আমাকে জানতে দিন
দ্রুত শিখর

-1

এটি আমার কাজ করার পদ্ধতি। এটি অন্যদের জন্য দরকারী হতে পারে:

private void updateType(){
    // Log.i(TAG,"updateType");
     StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {

         @Override
         public void onResponse(String response) {
             // running on main thread-------
             try {
                 JSONObject res = new JSONObject(response);
                 res.getString("result");
                 System.out.println("Response:" + res.getString("result"));

                 }else{
                     CustomTast ct=new CustomTast(context);
                     ct.showCustomAlert("Network/Server Disconnected",R.drawable.disconnect);
                 }

             } catch (Exception e) {
                 e.printStackTrace();

                 //Log.e("Response", "==> " + e.getMessage());
             }
         }
     }, new Response.ErrorListener() {
         @Override
         public void onErrorResponse(VolleyError volleyError) {
             // running on main thread-------
             VolleyLog.d(TAG, "Error: " + volleyError.getMessage());

         }
     }) {
         protected Map<String, String> getParams() {
             HashMap<String, String> hashMapParams = new HashMap<String, String>();
             hashMapParams.put("key", "value");
             hashMapParams.put("key", "value");
             hashMapParams.put("key", "value"));
             hashMapParams.put("key", "value");
             System.out.println("Hashmap:" + hashMapParams);
             return hashMapParams;
         }
     };
     AppController.getInstance().addToRequestQueue(request);

 }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.