Android - Как добавить имя файла в функцию загрузки файла, которая вызывает файл PHP - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть следующий Java код в моем приложении Android - в классе Java, который расширяет 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); }});
         }
   }

Я называю его следующим образом:

   // 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);
            }
    }});

И это мой upload-file.php скрипт:

<?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'];
}
?>

Результат, который я получаю в Logcat, таков:

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

Что мне нужно сделать, это добавьте «image.jpg» в конец этого URL, чтобы конечный результат был таким:

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

Я предполагаю, что это можно сделать в моей функции XSUploadFile () в моем классе java, возможно, отредактировав эту строку:

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

Я пробовал несколько изменений, но безуспешно.

Обратите внимание, что я не могу редактировать сценарий PHP, у меня есть PHP и iOS SDK, который вызывает этот скрипт и работает нормально, поэтому я должен редактировать только код Android Java.

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Вам необходимо получить расширение из загруженного файла. см. приведенный ниже код.

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

EDIT

@ xscoder не может редактировать php, поэтому я даю функцию в java, которая возвращает расширение файла при передаче имени файла этому.

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

вы можете редактировать эту строку как

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

ПРИМЕЧАНИЕ: при использовании файла в java вам необходимо включить эту строку import java.io.File;

0 голосов
/ 22 февраля 2020

Я нашел решение, вдохновившись моим кодом Swift, мне пришлось добавить этот код в мою upload функцию:

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"

            );

Итак, финальная функция Java теперь выглядит так это:

 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); }});
         }
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...