2015-05-14 8 views
14

Devo consentire a un utente di caricare più file (può essere immagine/video/audio) in una singola richiesta dalla mia applicazione Android al server PHP. Sto usando il servizio web REST.Android consente il caricamento di più file (Max 150 MB) al server PHP

Per questa funzionalità, Sto usando il seguente codice:

/* To upload the multiple documents */ 
public void uploadFile() { 
    String charset = "UTF-8"; 
    File[] uploadFileArray = new File[mediaList.size()]; 

    for (int i = 0; i < mediaList.size(); i++) { 
     uploadFileArray[i] = new File(mediaList.get(i).getMediaPath()); 
    } 

    try { 
     MultipartUtility multipart = new MultipartUtility(upLoadServerUri, charset); 

     for (int i = 0; i < mediaList.size(); i++) { 
      if (isImage)) { 
       multipart.addFilePart("image_doc[]", uploadFileArray[i]); 
      } 
      else if (isVideo) { 
       multipart.addFilePart("video_doc[]", uploadFileArray[i]); 
      } 
      else if (isAudio) { 
       multipart.addFilePart("audio_doc[]", uploadFileArray[i]); 
      } 
     } 

     List<String> responseUploadDocument = multipart.finish(); 
     System.out.println("SERVER REPLIED:"); 

     for (String line : responseUploadDocument) { 
      System.out.println(line); 
      responseUploadDocumentString = line; 
     } 

     if (responseUploadDocumentString != null) { 
      JSONObject jsonObj = new JSONObject(responseUploadDocumentString); 
      statusUploadDoc = jsonObj.getString("status"); 
     } 

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

E la mia classe MultipartUtility è la seguente:

public class MultipartUtility { 
    private final String boundary; 
    private static final String LINE_FEED = "\r\n"; 
    private HttpURLConnection httpConn; 
    private String charset; 
    private OutputStream outputStream; 
    private PrintWriter writer; 

    public MultipartUtility(String requestURL, String charset) 
      throws IOException { 
     this.charset = charset; 

     boundary = "===" + System.currentTimeMillis() + "==="; 

     URL url = new URL(requestURL); 
     httpConn = (HttpURLConnection) url.openConnection(); 

     ***httpConn.setChunkedStreamingMode(0);*** 
     httpConn.setUseCaches(false); 
     httpConn.setDoOutput(true); // indicates POST method 
     httpConn.setDoInput(true); 

     httpConn.setRequestProperty("Content-Type", 
       "multipart/form-data; boundary=" + boundary); 
     httpConn.setRequestProperty("User-Agent", "CodeJava Agent"); 
     httpConn.setRequestProperty("Test", "Bonjour"); 

     outputStream = httpConn.getOutputStream(); 
     writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), 
       true); 
    } 

    public void addFormField(String name, String value) { 
     writer.append("--" + boundary).append(LINE_FEED); 
     writer.append("Content-Disposition: form-data; name=\"" + name + "\"") 
       .append(LINE_FEED); 
     writer.append("Content-Type: text/plain; charset=" + charset).append(
       LINE_FEED); 
     writer.append(LINE_FEED); 
     writer.append(value).append(LINE_FEED); 
     writer.flush(); 
    } 

    public void addFilePart(String fieldName, File uploadFile) 
      throws IOException { 
     String fileName = uploadFile.getName(); 
     writer.append("--" + boundary).append(LINE_FEED); 
     writer.append(
       "Content-Disposition: form-data; name=\"" + fieldName 
         + "\"; filename=\"" + fileName + "\"") 
       .append(LINE_FEED); 
     writer.append(
       "Content-Type: " 
         + URLConnection.guessContentTypeFromName(fileName)) 
       .append(LINE_FEED); 
     writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED); 
     writer.append(LINE_FEED); 
     writer.flush(); 

     FileInputStream inputStream = new FileInputStream(uploadFile); 
     byte[] buffer = new byte[4096]; 
     int bytesRead = -1; 
     while ((bytesRead = inputStream.read(buffer)) != -1) { 
      outputStream.write(buffer, 0, bytesRead); 
     } 
     outputStream.flush(); 
     inputStream.close(); 

     writer.append(LINE_FEED); 
     writer.flush(); 
    } 

    public void addHeaderField(String name, String value) { 
     writer.append(name + ": " + value).append(LINE_FEED); 
     writer.flush(); 
    } 

    public List<String> finish() throws IOException { 
     List<String> response = new ArrayList<String>(); 

     writer.append(LINE_FEED).flush(); 
     writer.append("--" + boundary + "--").append(LINE_FEED); 
     writer.close(); 

     // checks server's status code first 
     int status = httpConn.getResponseCode(); 
     if (status == HttpURLConnection.HTTP_OK) { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
        httpConn.getInputStream())); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       response.add(line); 
      } 
      reader.close(); 
      httpConn.disconnect(); 
     } else { 
      throw new IOException("Server returned non-OK status: " + status); 
     } 

     return response; 
    } 
} 

Ma ora il problema è:

Sul server locale :

  • Consentire a caricare fino a 16 MB [se setChunkedStremmingMode (0) non è impostato]
  • permettono di caricare fino a 150 MB [se setChunkedStremmingMode (0) è impostato]

In diretta Server:

  • permettono di caricare fino a 16MB [se setChunkedStremmingMode (0) non è impostato]
  • Disallow per caricare un singolo file KB [se setChunkedStremmingMode (0) è impostato]

mio sia loc tutti i server live hanno le stesse configurazioni. Non capisco perché setChunkedStremmingMode (0) non funzioni per il server live.

+0

plz dare il tuo contributo se il problema è risolto, in caso contrario, dare un feedback che cosa è un problema. – DearDhruv

risposta

1

Ho un progetto che può caricare le dimensioni dell'immagine/file di fino a 48-50 MB. [Sto usando retrofit per la comunicazione di rete.] Ecco il link per il progetto di esempio: https://github.com/DearDhruv/Retrofit-with-EventBus

Ecco il codice:

private void startUploading(final File file) { 

    if (file == null || !isPictureValid(file.getAbsolutePath())) { 
     showMsg("File is not valid, try again."); 
    } else if (file.exists()) { 
     showProgressDialog(); 
     String mimeType = "image/jpeg" 
       // "application/octet-stream" 
       // "multipart/form-data" 
       // "image/*" 
       // "multipart/mixed" 
       ; 

     TypedFile typedFile = new TypedFile(mimeType, file); 
     mApiClient.uploadFile(UPLOAD_FILE_REQUEST_TAG, typedFile); 

    } else { 
     showMsg("File is corrupted."); 
    } 
} 

Ecco il codice lato server:

class ImageUploadStatus { 
    public $result_code = 0; 
    public $message = "Image upload failed.";} 
    class ImageResults { 
    public $name = ""; 
    public $url = ""; 
    public $size = ""; 
} 
$status = new ImageUploadStatus(); 
$results = new ImageResults(); 

if ($_FILES ["file"] ["error"] > 0) { 
    header ("HTTP/1.1 400 Bad Request"); 
    // echo "Error: " . $_FILES ["file"] ["error"] . "<br /> \n"; 
    $status->message = "Error: " . $_FILES ["file"] ["error"]; 
} else { 
    if ($_FILES ["file"] ["error"] > 0) { 
     // echo "Error: " . $_FILES ["file"] ["error"] . "<br /> \n"; 
     $status->message = "Error: " . $_FILES ["file"] ["error"]; 
    } else { 
     // echo "Upload: " . $_FILES ["file"] ["name"] . "<br /> \n"; 
     // echo "Type: " . $_FILES ["file"] ["type"] . "<br /> \n"; 
     // echo "Size: " . ($_FILES ["file"] ["size"]/1024) . " Kb<br /> \n"; 
     // echo "Stored in: " . $_FILES ["file"] ["tmp_name"] . "<br /> \n"; 
    } 

    $target_path = "../api/uploads/"; 
    $target_path = $target_path . basename ($_FILES ['file'] ['name']); 

    //if (is_uploaded_file ($_FILES ['uploadedfile'] ['tmp_name'])) { 
     // echo "There was an error uploading the file, please try again!"; 
     //$status->message = "There was an error uploading the file, please try again!"; 
    //} 

    if (move_uploaded_file ($_FILES ['file'] ['tmp_name'], $target_path)) { 
     // echo "The file " . basename ($_FILES ['file'] ['name']) . " has been uploaded"; 

     $status->message = "Image upload successful"; 
     $status->result_code = 1; 

     $results->name = $_FILES ["file"] ["name"] . ""; 
     $results->url = $target_path . ""; 
     $results->size = ($_FILES ["file"] ["size"]/1); // 1024 to convert in KB 
    } else { 
     // echo "There was an error Moving the file, please try again!"; 
     //$status->message = "There was an error Moving the file, please try again!"; 

     switch($_FILES['file']['error']){ 
      case 0: //no error; possible file attack! 
       $status->message = "There was a problem with your upload."; 
       break; 
      case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini 
       $status->message = "The file you are trying to upload is too big."; 
       break; 
      case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form 
       $status->message = "The file you are trying to upload is too big."; 
       break; 
      case 3: //uploaded file was only partially uploaded 
       $status->message = "The file you are trying upload was only partially uploaded."; 
       break; 
      case 4: //no file was uploaded 
       $status->message = "You must select an image for upload."; 
       break; 
      default: //a default error, just in case! :) 
       $status->message = "There was a problem with your upload."; 
       break; 
      } 

     } 

    $response = array (
      'status' => $status, 
      'results' => $results 
    ); 

    // echo (json_encode ($status)); 
    // echo (json_encode ($results)); 
    echo (json_encode ($response)); 
} 

Immagino che potrebbe essere utile.

Potrebbe anche essere necessario fornire la dimensione massima del file di caricamento nella configurazione di PHP.

+7

Tutto il lavoro che ci hai dedicato è fantastico. Per favore, ricorda che i collegamenti possono morire e la tua risposta è resa inutile. Inoltre stai forzando gli OP a passare un sacco di codice quando potrebbe non risolvere il loro problema.Aggiungi al tuo post utili punti salienti di ciò che hai fatto diverso dall'OP e perché il tuo codice funziona mentre il suo no. – Dzyann

+2

Si modifica il proprio nome utente github e i collegamenti github muoiono, sfortunatamente. La modifica è grandiosa. – Will

+0

Certo, terrò a mente a riguardo. – DearDhruv

1

Controllare queste due impostazioni nel file php.ini sul server che gestisce il caricamento del file.

; Maximum allowed size for uploaded files. 
upload_max_filesize = 150M 

; Must be greater than or equal to upload_max_filesize 
post_max_size = 150M 

È necessario configurare queste impostazioni prima sul server, quindi il caricamento di file di grandi dimensioni funzionerà correttamente. Controllare anche le impostazioni sul server locale. Queste impostazioni sono più importanti prima di scrivere il codice per gestire il caricamento perché il tuo codice è corretto secondo me, poiché il caricamento dei file funziona per te. Il problema sembra essere con le impostazioni di php.ini ....

+0

Si prega di condividere quale impostazione avete sul server e locale ?? – Vickrant

Problemi correlati