从android设备上传php服务器中的文件

Posted

技术标签:

【中文标题】从android设备上传php服务器中的文件【英文标题】:Uploading file in php server from android device 【发布时间】:2014-10-13 10:13:48 【问题描述】:

我正在尝试将文件从我的 android 设备上传到 php 服务器,但服务器没有收到任何文件。这是我的示例代码,我在网上找到的。 php服务器,我正在通过块上传文件

我的 Android 代码

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener

private TextView messageText;
private Button uploadButton, btnselectpic;
private ImageView imageview;
private int serverResponseCode = 0;
private ProgressDialog dialog = null;

private String upLoadServerUri = null;
private String imagepath=null;
@Override
public void onCreate(Bundle savedInstanceState) 

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    uploadButton = (Button)findViewById(R.id.uploadButton);
    messageText  = (TextView)findViewById(R.id.messageText);
    btnselectpic = (Button)findViewById(R.id.button_selectpic);
    imageview = (ImageView)findViewById(R.id.imageView_pic);

    btnselectpic.setOnClickListener(this);
    uploadButton.setOnClickListener(this);
    upLoadServerUri = "http://192.168.2.4/fileupload/UploadToServer.php";



@Override
public void onClick(View arg0) 
    if(arg0==btnselectpic)
    
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Complete action using"), 1);
    
    else if (arg0==uploadButton) 

         dialog = ProgressDialog.show(MainActivity.this, "", "Uploading file...", true);
         messageText.setText("uploading started.....");
         new Thread(new Runnable() 
             public void run() 

                  uploadFile(imagepath);

             
           ).start();     
    

 

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 

    if (requestCode == 1 && resultCode == RESULT_OK) 
        //Bitmap photo = (Bitmap) data.getData().getPath(); 

        Uri selectedImageUri = data.getData();
        imagepath = getPath(selectedImageUri);
        Bitmap bitmap=BitmapFactory.decodeFile(imagepath);
        imageview.setImageBitmap(bitmap);
        messageText.setText("Uploading file path:" +imagepath);

    

     public String getPath(Uri uri) 
            String[] projection =  MediaStore.Images.Media.DATA ;
            Cursor cursor = managedQuery(uri, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        

public int uploadFile(String sourceFileUri) 


      String fileName = sourceFileUri;

      HttpURLConnection conn = null;
      DataOutputStream dos = null;  
      String lineEnd = "\r\n";
      String twoHyphens = "--";
      String boundary = "*****";
      int bytesRead, bytesAvailable, bufferSize;
      byte[] buffer;
      int maxBufferSize = 1 * 1024 * 1024; 
      File sourceFile = new File(sourceFileUri); 

      if (!sourceFile.isFile()) 

           dialog.dismiss(); 

           Log.e("uploadFile", "Source File not exist :"+imagepath);

           runOnUiThread(new Runnable() 
               public void run() 
                   messageText.setText("Source File not exist :"+ imagepath);
               
           ); 

           return 0;

      
      else
      
           try  

                 // open a URL connection to the Servlet
               FileInputStream fileInputStream = new FileInputStream(sourceFile);
               URL url = new URL(upLoadServerUri);

               // Open a HTTP  connection to  the URL
               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", fileName); 

               dos = new DataOutputStream(conn.getOutputStream());

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

               dos.writeBytes(lineEnd);

               // create a buffer of  maximum size
               bytesAvailable = fileInputStream.available(); 

               bufferSize = Math.min(bytesAvailable, maxBufferSize);
               buffer = new byte[bufferSize];

               // read file and write it into form...
               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);   

                

               // send multipart form data necesssary after file data...
               dos.writeBytes(lineEnd);
               dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

               // Responses from the server (code and message)
               serverResponseCode = conn.getResponseCode();
               String serverResponseMessage = conn.getResponseMessage();

               Log.i("uploadFile", "HTTP Response is : "
                       + serverResponseMessage + ": " + serverResponseCode);

               if(serverResponseCode == 200)

                   runOnUiThread(new Runnable() 
                        public void run() 
                            String msg = "File Upload Completed.\n\n See uploaded file here : \n\n"
                                  +" c:/xamp/htdocs/file upload/uploads";
                            messageText.setText(msg);
                            Toast.makeText(MainActivity.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
                        
                    );                
                   

               //close the streams //
               fileInputStream.close();
               dos.flush();
               dos.close();

           catch (MalformedURLException ex) 

              dialog.dismiss();  
              ex.printStackTrace();

              runOnUiThread(new Runnable() 
                  public void run() 
                      messageText.setText("MalformedURLException Exception : check script url.");
                      Toast.makeText(MainActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
                  
              );

              Log.e("Upload file to server", "error: " + ex.getMessage(), ex);  
           catch (Exception e) 

              dialog.dismiss();  
              e.printStackTrace();

              runOnUiThread(new Runnable() 
                  public void run() 
                      messageText.setText("Got Exception : see logcat ");
                      Toast.makeText(MainActivity.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show();
                  
              );
              Log.e("Upload file to server Exception", "Exception : "  + e.getMessage(), e);  
          
          dialog.dismiss();       
          return serverResponseCode; 

        // End else block 
     

PHP 服务器代码 在文件上传中,我通过块完成文件上传,请任何人帮我发​​送正确的代码文件上传通过块和相关的android文件上传代码

<?php

if (empty($_FILES) || $_FILES['file']['error']) 
die('"OK": 0, "info": "Failed to move uploaded file."');


$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;

$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : $_FILES["file"]["name"];
$filePath = "uploads/$fileName";


// Open temp file
$out = @fopen("$filePath.part", $chunk == 0 ? "wb" : "ab");
//$out2 = @fopen("$filePath.part2", $chunk == 0 ? "wb" : "ab");
if ($out) 
// Read binary input stream and append it to temp file
$in = @fopen($_FILES['file']['tmp_name'], "rb");

if ($in) 
while ($buff = fread($in, 4096))
      fwrite($out, $buff);
   //print($out);
 // echo sizeof($out);
 else
die('"OK": 0, "info": "Failed to open input stream."');

@fclose($in);

@fclose($out);

@unlink($_FILES['file']['tmp_name']);
 else
die('"OK": 0, "info": "Failed to open output stream."');


// Check if file has been uploaded

if (!$chunks || $chunk == $chunks - 1)

// Strip the temp .part suffix off
rename("$filePath.part", $filePath);



die('"OK": 1, "info": "Upload successful."');?>

【问题讨论】:

您可以使用 FTP 并借助 API (AsyncHttpResponseHandler) 上传文件 ***.com/questions/22138881/… 【参考方案1】:

我不知道您的代码,但为您提供了两个工作代码: 这适用于所有类型的文件。我将它用于图像、音频和视频文件。

安卓:

new UploadFileAsync().execute("");



  private class UploadFileAsync extends AsyncTask<String, Void, String> 

    @Override
    protected String doInBackground(String... params) 

        try 
  String sourceFileUri = "/mnt/sdcard/abc.png";

            HttpURLConnection conn = null;
            DataOutputStream dos = null;
            String lineEnd = "\r\n";
            String twoHyphens = "--";
            String boundary = "*****";
            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            int maxBufferSize = 1 * 1024 * 1024;
            File sourceFile = new File(sourceFileUri);

            if (sourceFile.isFile()) 

                try 
                    String upLoadServerUri = "http://website.com/abc.php?";

                    // open a URL connection to the Servlet
                    FileInputStream fileInputStream = new FileInputStream(
                            sourceFile);
                    URL url = new URL(upLoadServerUri);

                    // Open a HTTP connection to the URL
                    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("bill", sourceFileUri);

                    dos = new DataOutputStream(conn.getOutputStream());

                    dos.writeBytes(twoHyphens + boundary + lineEnd);
                    dos.writeBytes("Content-Disposition: form-data; name=\"bill\";filename=\""
                            + sourceFileUri + "\"" + lineEnd);

                    dos.writeBytes(lineEnd);

                    // create a buffer of maximum size
                    bytesAvailable = fileInputStream.available();

                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    buffer = new byte[bufferSize];

                    // read file and write it into form...
                    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);

                    

                    // send multipart form data necesssary after file
                    // data...
                    dos.writeBytes(lineEnd);
                    dos.writeBytes(twoHyphens + boundary + twoHyphens
                            + lineEnd);

                    // Responses from the server (code and message)
                    serverResponseCode = conn.getResponseCode();
                    String serverResponseMessage = conn
                            .getResponseMessage();

                    if (serverResponseCode == 200) 

                        // messageText.setText(msg);
                        //Toast.makeText(ctx, "File Upload Complete.",
                        //      Toast.LENGTH_SHORT).show();

                        // recursiveDelete(mDirectory1);

                    

                    // close the streams //
                    fileInputStream.close();
                    dos.flush();
                    dos.close();

                 catch (Exception e) 

                    // dialog.dismiss();
                    e.printStackTrace();

                
                // dialog.dismiss();

             // End else block


         catch (Exception ex) 
            // dialog.dismiss();

            ex.printStackTrace();
        
        return "Executed";
    

    @Override
    protected void onPostExecute(String result) 

    

    @Override
    protected void onPreExecute() 
    

    @Override
    protected void onProgressUpdate(Void... values) 
    

PHP::

 <?php


     if (is_uploaded_file($_FILES['bill']['tmp_name'])) 
    $uploads_dir = './';
                            $tmp_name = $_FILES['bill']['tmp_name'];
                            $pic_name = $_FILES['bill']['name'];
                            move_uploaded_file($tmp_name, $uploads_dir.$pic_name);
                            
               else
                   echo "File not uploaded successfully.";
           

   ?>

【讨论】:

@Purushotamrawat 上传没有文件大小限制取决于您的托管服务提供商。 我有一个疑问。如果可以像上面那样直接使用 HTTP 上传,那么为什么有些博客使用了 volley 或改造库。这些方法有什么区别?【参考方案2】:

试试这个:它是 100% 的工作副本。

上传函数:(函数的参数是imagePath)

public void uploadFile(String sourceFileUri) 


          String fileName = imagePath;
          HttpURLConnection conn = null;
          DataOutputStream dos = null;  
          String lineEnd = "\r\n";
          String twoHyphens = "--";
          String boundary = "*****";
          int bytesRead, bytesAvailable, bufferSize;
          byte[] buffer;
          int maxBufferSize = 1 * 1024 * 1024; 
          File sourceFile = new File(imagePath); 

          if (!sourceFile.isFile()) 

                if (dialog != null && dialog.isShowing()) 
                    dialog.dismiss();
                

            Log.e("uploadFile", "Source File not exist :"+imagePath);


          
          else
          
            try  

               // open a URL connection to the Servlet
                FileInputStream fileInputStream = new FileInputStream(sourceFile);
                URL url = new URL(Upload_Image_URL);

                // Open a HTTP  connection to  the URL
                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("uploaded_file", fileName); 

                dos = new DataOutputStream(conn.getOutputStream());

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

                dos.writeBytes(lineEnd);

                // create a buffer of  maximum size
                bytesAvailable = fileInputStream.available(); 

                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                buffer = new byte[bufferSize];

                // read file and write it into form...
                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);   

                 

                // send multipart form data necesssary after file data...
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                // Responses from the server (code and message)
                serverResponseCode = conn.getResponseCode();
                String serverResponseMessage = conn.getResponseMessage();

                Log.i("uploadFile", "HTTP Response is : " 
                  + serverResponseMessage + ": " + serverResponseCode);


                //close the streams //
                fileInputStream.close();
                dos.flush();
                dos.close();

            catch (MalformedURLException ex) 

                    if (dialog != null && dialog.isShowing()) 
                        dialog.dismiss();
                    
               ex.printStackTrace();

               Log.e("Upload file to server", "error: " + ex.getMessage(), ex);  
            catch (Exception e) 

               if (dialog != null && dialog.isShowing()) 
                        dialog.dismiss();
               
               e.printStackTrace();


           

            if (dialog != null && dialog.isShowing()) 
                        dialog.dismiss();

              


                // End else block 
              

PHP 服务:

  $file_path = "images/";
  $file_path = $file_path . basename( $_FILES['uploaded_file']['name']);

  if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) 
  echo "success";
   else echo "fail";

必须在服务器中创建一个名为“images”的文件夹,这样 $file_path 才有效

【讨论】:

String serverResponseMessage = conn.getResponseMessage();【参考方案3】:

如果您使用免费托管,则页面将被重定向以跟踪编号。点击数。您可能会收到 Http Response :200 OK 但您不会看到文件上传,因为文件丢失了。

我自己浪费了 3 天时间寻找解决方案,但一无所获。这是我自己想出来的。

【讨论】:

【参考方案4】:

完整的工作代码 .... 带有 PHP 代码

 public class MainActivity 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://Ip Address/a.php";
ImageView ivAttachment;
Button bUpload;
TextView tvFileName;
ProgressDialog dialog;


@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ivAttachment = (ImageView) findViewById(R.id.ivAttachment);
    bUpload = (Button) findViewById(R.id.b_upload);
    tvFileName = (TextView) findViewById(R.id.tv_file_name);
    ivAttachment.setOnClickListener(this);
    bUpload.setOnClickListener(this);


@Override
public void onClick(View v) 
    if(v== ivAttachment)

        //on attachment icon click
        showFileChooser();
    
    if(v== bUpload)

        //on upload button Click
        if(selectedFilePath != null)
            dialog = ProgressDialog.show(MainActivity.this,"","Uploading File...",true);

            new Thread(new Runnable() 
                @Override
                public void run() 
                    //creating new thread to handle Http Operations
                    uploadFile(selectedFilePath);
                
            ).start();
        else
            Toast.makeText(MainActivity.this,"Please choose a File First",Toast.LENGTH_SHORT).show();
        

    


private void showFileChooser() 
    Intent intent = new Intent();
    //sets the select file to all types of files
    intent.setType("*/*");
    //allows to select data and return it
    intent.setAction(Intent.ACTION_GET_CONTENT);
    //starts new activity to select file and return data
    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();
            selectedFilePath = FilePath.getPath(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();
            
        
    


//android upload file to server
public int uploadFile(final String selectedFilePath)

    int serverResponseCode = 0;

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


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


    String[] parts = selectedFilePath.split("/");
    final String fileName = parts[parts.length-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);

            //creating new dataoutputstream
            dataOutputStream = new DataOutputStream(connection.getOutputStream());

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

            dataOutputStream.writeBytes(lineEnd);

            //returns no. of bytes present in fileInputStream
            bytesAvailable = fileInputStream.available();
            //selecting the buffer size as minimum of available bytes or 1 MB
            bufferSize = Math.min(bytesAvailable,maxBufferSize);
            //setting the buffer as byte array of size of bufferSize
            buffer = new byte[bufferSize];

            //reads bytes from FileInputStream(from 0th index of buffer to buffersize)
            bytesRead = fileInputStream.read(buffer,0,bufferSize);

            //loop repeats till bytesRead = -1, i.e., no bytes are left to read
            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);

            //response code of 200 indicates the server status OK
            if(serverResponseCode == 200)
                runOnUiThread(new Runnable() 
                    @Override
                    public void run() 
                        tvFileName.setText("File Upload completed.\n\n You can see the uploaded file here: \n\n" + "http://coderefer.com/extras/uploads/"+ fileName);
                    
                );
            

            //closing the input and output streams
            fileInputStream.close();
            dataOutputStream.flush();
            dataOutputStream.close();



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

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

   
   

添加 FilePath.cs

public class FilePath 

public static String getPath(final Context context, final Uri uri) 

    // check here to KITKAT or new version
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) 

        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) 
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) 
                return Environment.getExternalStorageDirectory() + "/"
                        + split[1];
            
        
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) 

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"),
                    Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        
        // MediaProvider
        else if (isMediaDocument(uri)) 
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) 
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
             else if ("video".equals(type)) 
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
             else if ("audio".equals(type)) 
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            

            final String selection = "_id=?";
            final String[] selectionArgs = new String[]  split[1] ;

            return getDataColumn(context, contentUri, selection,
                    selectionArgs);
        
    
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) 

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(context, uri, null, null);
    
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) 
        return uri.getPath();
    

    return null;


/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context
 *            The context.
 * @param uri
 *            The Uri to query.
 * @param selection
 *            (Optional) Filter used in the query.
 * @param selectionArgs
 *            (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public static String getDataColumn(Context context, Uri uri,
                                   String selection, String[] selectionArgs) 

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection =  column ;

    try 
        cursor = context.getContentResolver().query(uri, projection,
                selection, selectionArgs, null);
        if (cursor != null && cursor.moveToFirst()) 
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        
     finally 
        if (cursor != null)
            cursor.close();
    
    return null;


/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) 
    return "com.android.externalstorage.documents".equals(uri
            .getAuthority());


/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) 
    return "com.android.providers.downloads.documents".equals(uri
            .getAuthority());


/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) 
    return "com.android.providers.media.documents".equals(uri
            .getAuthority());


/**
 * @param uri
 *            The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
public static boolean isGooglePhotosUri(Uri uri) 
    return "com.google.android.apps.photos.content".equals(uri
            .getAuthority());


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:background="@color/colorAccent">

<TextView
    android:layout_
    android:layout_
    android:gravity="center"
    android:textSize="18sp"
    android:id="@+id/tvHeading"
    android:text="Touch the icon below to upload file to server"
    android:textColor="#fff"
    android:textStyle="bold"/>
<ImageView
    android:id="@+id/ivAttachment"
    android:layout_
    android:layout_
    android:src="@android:drawable/ic_menu_camera"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"/>

<TextView
    android:id="@+id/tv_file_name"
    android:layout_
    android:layout_
    android:textColor="#fff"
    android:layout_marginTop="10dp"
    android:gravity="center"
    android:layout_below="@+id/ivAttachment"
    android:layout_centerHorizontal="true"/>

<Button
    android:layout_
    android:layout_
    android:id="@+id/b_upload"
    android:text="Upload"
    android:textStyle="bold"
    android:textSize="20sp"
    android:layout_alignParentBottom="true"
    android:gravity="center"
    android:textColor="#fff"
    android:background="#039be5"/>

  </RelativeLayout>

php 文件 a.php

<?php
 if (isset($_FILES["uploaded_file"]["name"])) 

$name = $_FILES["uploaded_file"]["name"];
$tmp_name = $_FILES['uploaded_file']['tmp_name'];
$error = $_FILES['uploaded_file']['error'];

if (!empty($name)) 
    $location = './fileload/';

 if ( ! is_dir($location)) 
 mkdir($location);
 

    if  (move_uploaded_file($tmp_name, $location.$name))
        echo 'Uploaded';
    

 else 
    echo 'please choose a file';


 ?>

为文件加载文件夹添加读/写权限

用 fiddler 用下面的代码测试过

  User-Agent: Fiddler
  Content-Type: multipart/form-data;boundary=*****
  uploaded_file: C:\Desktop\oldScreen.png
  Content-Disposition: form-data; 
  name="uploaded_file";filename="C:\\Desktop\oldScreen.png"
  Content-Length: 0

【讨论】:

【参考方案5】:

php 文件

 <?php


 if (is_uploaded_file($_FILES['bill']['tmp_name'])) 
$uploads_dir = 'Uploads/staff_documents/';
                        $tmp_name = $_FILES['bill']['tmp_name'];
                        $pic_name = $_FILES['bill']['name'];
                        echo $pic_name;
                        move_uploaded_file($tmp_name, $uploads_dir.$pic_name);
                        
           else
               echo "File not uploaded successfully.";
       

?>

它支持所有文件 要从安卓设备上传文档,您可以使用https://github.com/gotev/android-upload-service 因为它也提供通知支持

Android Java 部分

 new MultipartUploadRequest(getApplicationContext(), uploadId, "Your server 
 url")
                        .addFileToUpload(filePathURI + "","bill") 
                         //Adding file
                        .setNotificationConfig(new UploadNotificationConfig())
                        .setMaxRetries(2)
                        .startUpload();

【讨论】:

【参考方案6】:

这些示例在 nginx+HyperfastCGI+Mono 上给出错误。要消除错误,您需要在分号后放置一个空格。

conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

也许有人会需要这些信息。

【讨论】:

【参考方案7】:

那些正在寻找 Kotlin 解决方案的人可以使用这个实用程序类。这是我写的关于这个主题的详细文章。它使用 OKHTTP3。 Upload File to Server in Android Kotlin

package com.mvp.handyopinion

import android.app.Activity
import android.app.ProgressDialog
import android.net.Uri
import android.util.Log
import android.webkit.MimeTypeMap
import android.widget.Toast
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File

class UploadUtility(activity: Activity) 

    var activity = activity;
    var dialog: ProgressDialog? = null
    var serverURL: String = "https://handyopinion.com/tutorials/UploadToServer.php"
    var serverUploadDirectoryPath: String = "https://handyopinion.com/tutorials/uploads/"
    val client = OkHttpClient()

    fun uploadFile(sourceFilePath: String, uploadedFileName: String? = null) 
        uploadFile(File(sourceFilePath), uploadedFileName)
    

    fun uploadFile(sourceFileUri: Uri, uploadedFileName: String? = null) 
        val pathFromUri = URIPathHelper().getPath(activity,sourceFileUri)
        uploadFile(File(pathFromUri), uploadedFileName)
    

    fun uploadFile(sourceFile: File, uploadedFileName: String? = null) 
        Thread 
            val mimeType = getMimeType(sourceFile);
            if (mimeType == null) 
                Log.e("file error", "Not able to get mime type")
                return@Thread
            
            val fileName: String = if (uploadedFileName == null)  sourceFile.name else uploadedFileName
            toggleProgressDialog(true)
            try 
                val requestBody: RequestBody =
                    MultipartBody.Builder().setType(MultipartBody.FORM)
                        .addFormDataPart("uploaded_file", fileName,sourceFile.asRequestBody(mimeType.toMediaTypeOrNull()))
                        .build()

                val request: Request = Request.Builder().url(serverURL).post(requestBody).build()

                val response: Response = client.newCall(request).execute()

                if (response.isSuccessful) 
                    Log.d("File upload","success, path: $serverUploadDirectoryPath$fileName")
                    showToast("File uploaded successfully at $serverUploadDirectoryPath$fileName")
                 else 
                    Log.e("File upload", "failed")
                    showToast("File uploading failed")
                
             catch (ex: Exception) 
                ex.printStackTrace()
                Log.e("File upload", "failed")
                showToast("File uploading failed")
            
            toggleProgressDialog(false)
        .start()
    

    // url = file path or whatever suitable URL you want.
    fun getMimeType(file: File): String? 
        var type: String? = null
        val extension = MimeTypeMap.getFileExtensionFromUrl(file.path)
        if (extension != null) 
            type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
        
        return type
    

    fun showToast(message: String) 
        activity.runOnUiThread 
            Toast.makeText( activity, message, Toast.LENGTH_LONG ).show()
        
    

    fun toggleProgressDialog(show: Boolean) 
        activity.runOnUiThread 
            if (show) 
                dialog = ProgressDialog.show(activity, "", "Uploading file...", true);
             else 
                dialog?.dismiss();
            
        
    


【讨论】:

以上是关于从android设备上传php服务器中的文件的主要内容,如果未能解决你的问题,请参考以下文章

从android应用程序上传多个图像文件到php服务器

带有服务器端 php 的 Android 文件上传器

将图像从android上传到服务器php时出错?

Android:如何将 .mp3 文件上传到 http 服务器?

将图像从 android 上传到 PHP 服务器

Android - 在 GridView 中使用 PHP 显示服务器文件夹中的所有图像