0

I have the following Java code in my Android app - in a Java class that extends Application:

public static void XSUploadFile(final String filePath, final String fileName, final Activity act, final XSFileHandler handler) {
      new Thread(new Runnable() {
         public void run() {
            upload(filePath, fileName, act, handler);
         }
      }).start();
   }
   public interface XSFileHandler { void done(String fileURL, String error); }
   public static void upload(String sourceFileUri, String fileName, Activity act, final XSFileHandler handler) {
         HttpURLConnection conn;
         DataOutputStream dos;
         String lineEnd = "\r\n";
         String twoHyphens = "--";
         String boundary = "*****";
         final int code;
         int bytesRead, bytesAvailable, bufferSize;
         byte[] buffer;
         int maxBufferSize = 1024*1024;
         File sourceFile = new File(sourceFileUri);
         try {
               FileInputStream fileInputStream = new FileInputStream(sourceFile);
               URL url = new URL(DATABASE_PATH + "upload-file.php");

               conn = (HttpURLConnection) url.openConnection();
               conn.setDoInput(true); // Allow Inputs
               conn.setDoOutput(true); // Allow Outputs

               conn.setUseCaches(false); // Don't use a Cached Copy
               conn.setRequestMethod("POST");
               conn.setRequestProperty("Connection", "Keep-Alive");
               conn.setRequestProperty("ENCTYPE", "multipart/form-data");
               conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
               conn.setRequestProperty("file", sourceFileUri);
               dos = new DataOutputStream(conn.getOutputStream());
               dos.writeBytes(twoHyphens + boundary + lineEnd);

               dos.writeBytes("Content-Disposition: form-data; name='file';fileName='" + sourceFileUri + "'" + fileName + "\"" + lineEnd);

               dos.writeBytes(lineEnd);
               bytesAvailable = fileInputStream.available();
               bufferSize = Math.min(bytesAvailable, maxBufferSize);
               buffer = new byte[bufferSize];
               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);
               }
               dos.writeBytes(lineEnd);
               dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
               code = conn.getResponseCode();

               if (code == HttpURLConnection.HTTP_OK) {
                  final HttpURLConnection finalConn = conn;
                  act.runOnUiThread(new Runnable() {
                     public void run() {
                        InputStream responseStream = null;
                        try {
                           responseStream = new BufferedInputStream(finalConn.getInputStream());
                           BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
                           String line;
                           StringBuilder stringBuilder = new StringBuilder();
                           int i = 0;
                           while ((line = responseStreamReader.readLine()) != null) {
                              if (i != 0) { stringBuilder.append("\n"); }
                              stringBuilder.append(line);
                              i++;
                           }
                           responseStreamReader.close();
                           String response = stringBuilder.toString();
                           responseStream.close();
                           finalConn.disconnect();
                           // Log.i(TAG, "XSUploadFile -> " + response);

                           if (response != null) { handler.done(DATABASE_PATH + response, null);
                           } else { handler.done(null, E_401); }

                        // error
                        } catch (IOException e) { e.printStackTrace(); handler.done(null, XS_ERROR); }
                     }});

               // Bad response from sever
               } else {
                  act.runOnUiThread(new Runnable() {
                     public void run() { handler.done(null, XS_ERROR); }});
               }
               fileInputStream.close();
               dos.flush();
               dos.close();

         // No response from server
         } catch (final Exception ex) {
            act.runOnUiThread(new Runnable() {
               public void run() { handler.done(null, XS_ERROR); }});
         }
   }

I call it as it follows:

   // Get demo image path
   Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.demo_img);
   final String filePath = getRealPathFromURI(getImageUri(bmp, ctx), ctx);

    XSUploadFile(filePath, "image.jpg", (Activity)ctx, new XServerSDK.XSFileHandler() {
        @Override
        public void done(String fileURL, String e) {
            if (fileURL != null) {
                hideHUD();
                Log.i("log-", "Uploaded FileURL: " + fileURL);
            }
    }});

And this is my upload-file.php script:

<?php include '_config.php';

if ($_FILES["file"]["error"] > 0) {
    echo "Error: " .$_FILES["file"]["error"]. "<br>";

} else {
    // Check file size
    if ($_FILES["file"]["size"] > 20485760) { // 20 MB
        echo "ERROR: Your file is larger than 20 MB. Please upload a smaller one.";    
    } else { uploadImage(); }

}// ./ If


// UPLOAD IMAGE ------------------------------------------
function uploadImage() {
    // generate a unique random string
    $randomStr = generateRandomString();
    $filePath = "uploads/".$randomStr;

    // upload image into the 'uploads' folder
    move_uploaded_file($_FILES['file']['tmp_name'], $filePath);

    // echo the link of the uploaded image
    echo $filePath;
}

// GENERATE A RANDOM STRING ---------------------------------------
function generateRandomString() {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i<20; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString."_".$_POST['fileName'];
}
?>

The result I get in the Logcat is this one:

Uploaded FileURL: https://xscoder.com/xserver/uploads/mocpWfxIvtRAacnk1lTV_

What I need to do is to append the "image.jpg" to the end of that URL, so the final result should be like:

Uploaded FileURL: https://xscoder.com/xserver/uploads/mocpWfxIvtRAacnk1lTV_image.jpg

I assume it can be done in my XSUploadFile() function in my java class, maybe by editing this line:

dos.writeBytes("Content-Disposition: form-data; name='file';fileName='" + sourceFileUri + "'" + fileName + "\"" + lineEnd);

I've tried a few editing but no success at all.

Note that I cannot edit the PHP script, I have a PHP and iOS SDK that both call that script and work fine, so I must edit only the Android Java code.

3
  • please find the below answer. Commented Feb 21, 2020 at 15:45
  • Thanks, I've edited my question Commented Feb 21, 2020 at 15:49
  • without the extension how ios displays the image? Commented Feb 21, 2020 at 15:52

2 Answers 2

1

You need to get the extension from the uploaded file. see the below code.

$filename = $_FILES["file"]["name"];
$file_extension = end((explode(".", $filename)));
$filePath = 'uploads/' . $randomStr.$file_extension;
move_uploaded_file($_FILES["file"]["tmp_name"], $filePath);

EDIT

@xscoder could not edit the php, so I am giving the function in java which return the file extension when you pass filename to that.

private static String getFileExtension(String fileName) {
        if(fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0)
        return fileName.substring(fileName.lastIndexOf(".")+1);
        else return "";
}

you can edit this line as

dos.writeBytes("Content-Disposition: form-data; name='file';fileName='" + sourceFileUri + "'" + fileName +"."+ getFileExtension(fileName) +"\"" + lineEnd);

NOTE: while using file in java you need to include this line import java.io.File;

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks, but I can't edit my php script, I've forgot to mention it in my question, because I also have a PHP and iOS SDK that calls that file the way it is and it works fine, so I must edit my Java code only
@xscoder without the extension how ios displays the image?
Because in a similar Swift function, this is what I use: body.append("\(fileName)\r\n".data(using: String.Encoding.utf8)!) AND if fileName.hasSuffix(".jpg") { body.append("Content-Type:image/png\r\n\r\n".data(using: String.Encoding.utf8)!). So my http request sends the file data + the file name String, and the complete file name becomes randomChars_image.jpg. I must do a similar job to my Android code as well
@xscoder what all are the extensions you are uploading in php file?
mainly jpg, png and mp4, but i can upload any file since i append its name and extension from my code.
|
0

I've found a solution by getting inspired from my Swift code, I had to add this code in my upload function:

dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\"fileName\"\r\n\r\n" +
                    fileName + "\r\n" +
                    "--" + boundary + "\r\n" +
                    "Content-Disposition: form-data; name=\"file\"; filename=\"file\"\r\n"

            );

So, the final Java function now looks like this:

 public static void upload(String sourceFileUri, String fileName, Activity act, final XSFileHandler handler) {
         HttpURLConnection conn;
         DataOutputStream dos;
         String lineEnd = "\r\n";
         String twoHyphens = "--";
         String boundary = "*****";
         final int code;
         int bytesRead, bytesAvailable, bufferSize;
         byte[] buffer;
         int maxBufferSize = 1024*1024;
         File sourceFile = new File(sourceFileUri);

         StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
         StrictMode.setThreadPolicy(policy);

         try {
               FileInputStream fileInputStream = new FileInputStream(sourceFile);
               URL url = new URL(DATABASE_PATH + "upload-file.php");

               conn = (HttpURLConnection) url.openConnection();
               conn.setDoInput(true);
               conn.setDoOutput(true);
               conn.setUseCaches(false);
               conn.setRequestMethod("POST");
               conn.setRequestProperty("Connection", "Keep-Alive");
               conn.setRequestProperty("ENCTYPE", "multipart/form-data");
               conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
               conn.setRequestProperty("file", sourceFileUri);
               dos = new DataOutputStream(conn.getOutputStream());
               dos.writeBytes(twoHyphens + boundary + lineEnd);

            /* HERE'S THE MAGIC CODE :) */
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\"fileName\"\r\n\r\n" +
                    fileName + "\r\n" +
                    "--" + boundary + "\r\n" +
                    "Content-Disposition: form-data; name=\"file\"; filename=\"file\"\r\n"

            );


               dos.writeBytes(lineEnd);
               bytesAvailable = fileInputStream.available();
               bufferSize = Math.min(bytesAvailable, maxBufferSize);
               buffer = new byte[bufferSize];
               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);
               }
               dos.writeBytes(lineEnd);
               dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
               code = conn.getResponseCode();

               if (code == HttpURLConnection.HTTP_OK) {
                  final HttpURLConnection finalConn = conn;
                  act.runOnUiThread(new Runnable() {
                     public void run() {
                        InputStream responseStream = null;
                        try {
                           responseStream = new BufferedInputStream(finalConn.getInputStream());
                           BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
                           String line;
                           StringBuilder stringBuilder = new StringBuilder();
                           int i = 0;
                           while ((line = responseStreamReader.readLine()) != null) {
                              if (i != 0) { stringBuilder.append("\n"); }
                              stringBuilder.append(line);
                              i++;
                           }
                           responseStreamReader.close();
                           String response = stringBuilder.toString();
                           responseStream.close();
                           finalConn.disconnect();
                           // Log.i(TAG, "XSUploadFile -> " + response);

                           if (response != null) { handler.done(DATABASE_PATH + response, null);
                           } else { handler.done(null, E_401); }

                        // error
                        } catch (IOException e) { e.printStackTrace(); handler.done(null, XS_ERROR); }
                     }});

               // Bad response from sever
               } else { act.runOnUiThread(new Runnable() {
                     public void run() { handler.done(null, XS_ERROR); }}); }
               fileInputStream.close();
               dos.flush();
               dos.close();

         // No response from server
         } catch (final Exception ex) {
            act.runOnUiThread(new Runnable() {
               public void run() { handler.done(null, XS_ERROR); }});
         }
   }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.