2016-09-30 203 views
0

我想從Android應用上傳文件到服務器。我嘗試這個,但仍然無法上傳文件到服務器。在我的java中有一個錯誤。將文件上傳到服務器,java.net.ProtocolException:讀取響應後無法寫入請求主體

public class UploadFileActivity extends AppCompatActivity implements View.OnClickListener{ 

    private static final int PICK_FILE_REQUEST = 1; 
    private static final String TAG = MainActivity.class.getSimpleName(); 
    private String selectedFilePath; 
    private String SERVER_URL = "http://url.com/mobile/json/upload_file.php"; 
    ImageView ivAttachment; 
    Button bUpload; 
    TextView tvFileName; 
    ProgressDialog dialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.activity_upload_file); 
     ivAttachment = (ImageView) findViewById(R.id.ivAttachment); 
     bUpload = (Button) findViewById(R.id.b_upload); 
     tvFileName = (TextView) findViewById(R.id.tv_file_name); 
     ivAttachment.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       showFileChooser(); 
      } 
     }); 
     bUpload.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(selectedFilePath != null){ 
        dialog = ProgressDialog.show(UploadFileActivity.this,"","Uploading File...",true); 

        new Thread(new Runnable() { 
         @Override 
         public void run() { 
          uploadFile(selectedFilePath); 
         } 
        }).start(); 
       }else{ 
        Toast.makeText(UploadFileActivity.this,"Please choose a File First",Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }); 
    } 


    @Override 
    public void onClick(View v) { 
    } 

    private void showFileChooser() { 
     Intent intent = new Intent(); 
     intent.setType("*/*"); 
     intent.setAction(Intent.ACTION_GET_CONTENT); 
     startActivityForResult(Intent.createChooser(intent,"Choose File to Upload.."),PICK_FILE_REQUEST); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     if(resultCode == Activity.RESULT_OK){ 
      if(requestCode == PICK_FILE_REQUEST){ 
       if(data == null){ 
        //no data present 
        return; 
       } 


       Uri selectedFileUri = data.getData(); 
       if(Build.VERSION.SDK_INT >= 19) { 
        selectedFilePath = FilePath.getPath(this, selectedFileUri); 
       } else { 
        selectedFilePath = FilePath.getSmartFilePath(this, selectedFileUri); 
       } 

       Log.i(TAG,"Selected File Path:" + selectedFilePath); 

       if(selectedFilePath != null && !selectedFilePath.equals("")){ 
        tvFileName.setText(selectedFilePath); 
       }else{ 
        Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show(); 
       } 
      } 
     } 
    } 

    public int uploadFile(final String selectedFilePath){ 

     int serverResponseCode = 0; 

     HttpURLConnection connection; 
     DataOutputStream dataOutputStream; 
     String lineEnd = "\r\n"; 
     String twoHyphens = "--"; 
     final String boundary = "*****"; 


     int bytesRead,bytesAvailable,bufferSize; 
     byte[] buffer; 
     int maxBufferSize = 1 * 1024 * 1024; 
     File selectedFile = new File(selectedFilePath); 

     String[] parts = selectedFilePath.split("/"); 
     String fileName = parts[parts.length-1]; 
     String[] separate = fileName.split(Pattern.quote(".")); 
     final String fileNameDoang = separate[0]; 
     final String fileType = separate[1]; 

     if (!selectedFile.isFile()){ 
      dialog.dismiss(); 

      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        tvFileName.setText("Source File Doesn't Exist: " + selectedFilePath); 
       } 
      }); 
      return 0; 
     }else{ 
      try{ 
       FileInputStream fileInputStream = new FileInputStream(selectedFile); 
       URL url = new URL(SERVER_URL); 
       connection = (HttpURLConnection) url.openConnection(); 
       connection.setDoInput(true);//Allow Inputs 
       connection.setDoOutput(true);//Allow Outputs 
       connection.setUseCaches(false);//Don't use a cached Copy 
       connection.setRequestMethod("POST"); 
       connection.setRequestProperty("Connection", "Keep-Alive"); 
       connection.setRequestProperty("ENCTYPE", "multipart/form-data"); 
       connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); 
       connection.setRequestProperty("uploaded_file",selectedFilePath); 
       int sizeFile = connection.getContentLength(); 
       dataOutputStream = new DataOutputStream(connection.getOutputStream()); 

       dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); 
       dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" 
         + selectedFilePath + "\"" + lineEnd); 

       dataOutputStream.writeBytes(lineEnd); 
       bytesAvailable = fileInputStream.available(); 
       bufferSize = Math.min(bytesAvailable,maxBufferSize); 
       buffer = new byte[bufferSize]; 

       bytesRead = fileInputStream.read(buffer,0,bufferSize); 

       while (bytesRead > 0){ 
        //write the bytes read from inputstream 
        dataOutputStream.write(buffer,0,bufferSize); 
        bytesAvailable = fileInputStream.available(); 
        bufferSize = Math.min(bytesAvailable,maxBufferSize); 
        bytesRead = fileInputStream.read(buffer,0,bufferSize); 
       } 

       dataOutputStream.writeBytes(lineEnd); 
       dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 

       serverResponseCode = connection.getResponseCode(); 
       String serverResponseMessage = connection.getResponseMessage(); 

       Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode); 

       if(serverResponseCode == 200){ 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          tvFileName.setText("File Upload completed.\n\n File Name : \n\n" + fileNameDoang + "File Type" + fileType); 
         } 
        }); 
       } 

       fileInputStream.close(); 
       dataOutputStream.flush(); 
       dataOutputStream.close(); 


      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         Toast.makeText(UploadFileActivity.this,"File Not Found",Toast.LENGTH_SHORT).show(); 
        } 
       }); 
      } catch (MalformedURLException e) { 
       e.printStackTrace(); 
       Toast.makeText(UploadFileActivity.this, "URL error!", Toast.LENGTH_SHORT).show(); 

      } catch (IOException e) { 
       e.printStackTrace(); 
       Toast.makeText(UploadFileActivity.this, "Cannot Read/Write File!", Toast.LENGTH_SHORT).show(); 
      } 
      dialog.dismiss(); 
      return serverResponseCode; 
     } 
    } 
} 

獲取filepath我把另一個java放進去。這是警告和錯誤:

09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err: java.net.ProtocolException: cannot write request body after response has been read 
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:  at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:223) 
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:  at com.sintask.android.ui.UploadFileActivity.uploadFile(UploadFileActivity.java:195) 
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:  at com.sintask.android.ui.UploadFileActivity$2$1.run(UploadFileActivity.java:66) 
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:  at java.lang.Thread.run(Thread.java:818) 
09-30 20:44:50.766 9855-10872/com.sintask.android E/AndroidRuntime: FATAL EXCEPTION: Thread-5234 
                    Process: com.sintask.android, PID: 9855 
                    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
                     at android.os.Handler.<init>(Handler.java:200) 
+0

@MWeisner編輯被拒絕。這裏的問題不是如何處理它,而是如何防止它。 – EJP

回答

1

這是因爲您在獲取輸出流之前調用了getContentLength()。沒有任何意義。您正在上傳,而不是下載。您不需要內容的長度,或者如果您確實需要,直到您上傳文件後才需要。

NB available()不是確定文件長度或任何輸入流長度的正確方法。使用File.length()

+0

非常感謝你是對的先生 –

相關問題