0

I wrote this AsyncTask class that sends an array of POST data to my php server with no problem. Now I want to extend it so that it also sends a file to same script (I have already the receive handling in the php file). What I mean is I want it to post DATA + FILE in one go. Something like multipart entity or something from HTML action to php script.

What would I need to add to this class so it can upload a file with other things?

public class UpdateSnakeGameStatusTask extends AsyncTask<String, Integer, HttpResponse> {
    private Context mContext;
    private ArrayList<NameValuePair> mPairs;

    /**
     * @param context The context that uses this AsyncTask thread
     * @param postPairs <b>NameValuePair</b> which contains name and post data
     */
    public UpdateSnakeGameStatusTask(Context context, ArrayList<NameValuePair> postPairs) {
        mContext = context;
        mPairs = new ArrayList<NameValuePair>(postPairs);
    }

    @Override
    protected HttpResponse doInBackground(String... params) {
        HttpResponse response = null;
        HttpPost httppost = new HttpPost(params[0]); //this is the URL

        try {
            httppost.setEntity(new UrlEncodedFormEntity(mPairs));
            HttpClient client = new DefaultHttpClient();
            response = client.execute(httppost);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}
Dumbo
  • 13,555
  • 54
  • 184
  • 288
  • possible duplicate of [How to send a file in Android from mobile to server using http?](http://stackoverflow.com/questions/4126625/how-to-send-a-file-in-android-from-mobile-to-server-using-http) – nKn Apr 29 '14 at 19:03
  • @nKn thats only for a single file, I want post DATA + FILE in same post action – Dumbo Apr 29 '14 at 19:11
  • You can put the file base64 encoded in a name value pair. – greenapps Apr 29 '14 at 23:42
  • @greenapps can you give an example please? – Dumbo Apr 29 '14 at 23:42
  • Well you have added some name value pairs to arraylist postPairs already. So add one more "filecontent", filecontentbase64string. By the way: in the constructor you can write mPairs = postPairs; – greenapps Apr 29 '14 at 23:54
  • @greenapps ok thanks I get the idea but my file is a text based CSV file, how will that work? and on the server side, does it go int $_FILES array or $_POST? – Dumbo Apr 29 '14 at 23:57
  • Csv or any file is ok. No it comes as the other parameters. So in my example in $_POST['filecontent'] – greenapps Apr 30 '14 at 00:02
  • @greenapps Thanks man problem solved...please look at my code I am not sure if it is optimized – Dumbo Apr 30 '14 at 00:56
  • mPairs = new ArrayList(postPairs); ?????? mPairs = postPairs; would do. That that even works... – greenapps Apr 30 '14 at 10:00

1 Answers1

0

Ok as @greenapps suggested (credit goes to him) I solved like this.

Well not entirly solved, because I have to decode the file content at server side and save it manually on server.

so I jsut added the file content to the BasicNameValuePair that I already had:

String fileAsBase64 = Base64.encodeToString( convertToByteArray(mFile)
                , Base64.DEFAULT);

    mPostPairs.add(new BasicNameValuePair("filecontent", fileAsBase64));

And this is the method that converts it to byte array:

/**
 *  Reads a file and returns its content as byte array
 * @param file file that should be returned as byte array
 * @return byte[] array of bytes of the file
 */
public static byte[] convertTextFileToByteArray(File file) {
    FileInputStream fileInputStream = null;
    byte[] bFile = new byte[(int) file.length()];
    try {
        fileInputStream = new FileInputStream(file);
        fileInputStream.read(bFile);
        fileInputStream.close();
    }catch(Exception e){
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            fileInputStream = null;
        }
    }
    return bFile;
}

At the server side I do this:

$content = imap_base64 ($_POST["filecontent"]);

that takes care of decoding the content back to normal.

Hope this helps someone else too

Dumbo
  • 13,555
  • 54
  • 184
  • 288
  • @greenapps yes, it arrives at server as a $_POST field, not $_FILE so I have to manually decode it from base64 and save it in a folder. If this is not the way, what you suggest? – Dumbo Apr 30 '14 at 07:41
  • Well it amazes me that writing some php code is categorised as "doing manually". – greenapps Apr 30 '14 at 09:56