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

Posted

技术标签:

【中文标题】Android:如何将 .mp3 文件上传到 http 服务器?【英文标题】:Android:How to upload .mp3 file to http server? 【发布时间】:2011-06-25 09:54:09 【问题描述】:

我想将 .mp3 文件(仅)从设备上传到我的服务器。

我想浏览媒体数据的路径并选择任何 mp3 文件并上传。

我该怎么做?

【问题讨论】:

什么是 php 服务器?你是说 HTTP 服务器吗? 【参考方案1】:

我最后的工作 JAVA 和 PHP 代码将文件从 android 的 SD 卡上传到我自己的 Web 服务器。

Java/Android 代码:

private void doFileUpload() 

    HttpURLConnection conn = null;
    DataOutputStream dos = null;
    DataInputStream inStream = null;
    String existingFileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/mypic.png";
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024;
    String responseFromServer = "";
    String urlString = "http://mywebsite.com/directory/upload.php";

    try 

        //------------------ CLIENT REQUEST
        FileInputStream fileInputStream = new FileInputStream(new File(existingFileName));
        // open a URL connection to the Servlet
        URL url = new URL(urlString);
        // Open a HTTP connection to the URL
        conn = (HttpURLConnection) url.openConnection();
        // Allow Inputs
        conn.setDoInput(true);
        // Allow Outputs
        conn.setDoOutput(true);
        // Don't use a cached copy.
        conn.setUseCaches(false);
        // Use a post method.
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
        dos = new DataOutputStream(conn.getOutputStream());
        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + existingFileName + "\"" + 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);
        // close streams
        Log.e("Debug", "File is written");
        fileInputStream.close();
        dos.flush();
        dos.close();

     catch (MalformedURLException ex) 
        Log.e("Debug", "error: " + ex.getMessage(), ex);
     catch (IOException ioe) 
        Log.e("Debug", "error: " + ioe.getMessage(), ioe);
    

    //------------------ read the SERVER RESPONSE
    try 

        inStream = new DataInputStream(conn.getInputStream());
        String str;

        while ((str = inStream.readLine()) != null) 

            Log.e("Debug", "Server Response " + str);

        

        inStream.close();

     catch (IOException ioex) 
        Log.e("Debug", "error: " + ioex.getMessage(), ioex);
    

要在您的服务器上运行的相关 PHP 代码 (upload.php):

<?php
// Where the file is going to be placed 
$target_path = "uploads/";

/* Add the original filename to our target path.  
Result is "uploads/filename.extension" */
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']); 

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) 
    echo "The file ".  basename( $_FILES['uploadedfile']['name']). 
    " has been uploaded";
    chmod ("uploads/".basename( $_FILES['uploadedfile']['name']), 0644);
 else
    echo "There was an error uploading the file, please try again!";
    echo "filename: " .  basename( $_FILES['uploadedfile']['name']);
    echo "target_path: " .$target_path;

?>

注意事项。 1)我在 SD 卡的根目录中有“mypic.png”。例如,如果您通过 Mass Storage USB 视图查看 Android 设备,您会将文件放在您遇到的第一个目录中。

2) 必须在手机上关闭 USB 大容量存储!或者只是将其从您正在编写代码的计算机上完全拔下以确保是这种情况。

3) 我必须在与我的 php 文件相同的目录中创建一个“上传”文件夹。

4) 你显然必须把我写成http://mywebsite.com/directory/upload.php 的网址改成你自己的网站。

【讨论】:

你能告诉我如何在多部分发布的同时发布一个简单的字符串数据...我想发送一个名为 postingname 的参数... 很棒的示例代码 :-) 在我的情况下,我必须首先进行基本身份验证,这很容易通过以下方式处理:'Authenticator.setDefault (new Authenticator() protected PasswordAuthentication getPasswordAuthentication() return new PasswordAuthentication ( "用户名", "密码".toCharArray()); );'我想其他人可能有兴趣了解我的解决方案。 @Keaton 我的文件正在上传,但上传的文件大小始终为 0。可能是什么原因。我使用了来自 link 的相同来源,提前致谢 @Keaton 很抱歉打扰您。我发现了错误。我只是把大于号放在其他地方:-) @Keaton 是否有必要在 //----------------- 读取 SERVER RESPONSE 行之后编写代码【参考方案2】:

感谢基顿的好建议。

我已经对 Java 代码进行了一些整理,以便可以使用并添加对其他 URL 参数的支持:

public class HttpMultipartUpload 
    static String lineEnd = "\r\n";
    static String twoHyphens = "--";
    static String boundary = "AaB03x87yxdkjnxvi7";

    public static String upload(URL url, File file, String fileParameterName, HashMap<String, String> parameters)
            throws IOException 
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream dis = null;
        FileInputStream fileInputStream = null;

        byte[] buffer;
        int maxBufferSize = 20 * 1024;
        try 
            //------------------ CLIENT REQUEST
            fileInputStream = new FileInputStream(file);

            // open a URL connection to the Servlet
            // Open a HTTP connection to the URL
            conn = (HttpURLConnection) url.openConnection();
            // Allow Inputs
            conn.setDoInput(true);
            // Allow Outputs
            conn.setDoOutput(true);
            // Don't use a cached copy.
            conn.setUseCaches(false);
            // Use a post method.
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

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

            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\"" + fileParameterName
                    + "\"; filename=\"" + file.toString() + "\"" + lineEnd);
            dos.writeBytes("Content-Type: text/xml" + lineEnd);
            dos.writeBytes(lineEnd);

            // create a buffer of maximum size
            buffer = new byte[Math.min((int) file.length(), maxBufferSize)];
            int length;
            // read file and write it into form...
            while ((length = fileInputStream.read(buffer)) != -1) 
                dos.write(buffer, 0, length);
            

            for (String name : parameters.keySet()) 
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"" + lineEnd);
                dos.writeBytes(lineEnd);
                dos.writeBytes(parameters.get(name));
            

            // send multipart form data necessary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
            dos.flush();
         finally 
            if (fileInputStream != null) fileInputStream.close();
            if (dos != null) dos.close();
        

        //------------------ read the SERVER RESPONSE
        try 
            dis = new DataInputStream(conn.getInputStream());
            StringBuilder response = new StringBuilder();

            String line;
            while ((line = dis.readLine()) != null) 
                response.append(line).append('\n');
            

            return response.toString();
         finally 
            if (dis != null) dis.close();
        
    

【讨论】:

这是什么fileParameterName?是文件格式吗? 您好,我正在使用此代码,但不适用于我。我正在尝试上传音频文件,但它不应该在浏览器中播放。 五年过去了,有一些简单的解决方案可以执行 http 上传,并且 http 本身已经发展(http 2)。我建议你使用 OkHttp。【参考方案3】:

请注意,如果您复制并粘贴上述 PHP 代码,任何人都可以将恶意 PHP 脚本上传到您的服务器并运行它,请始终注意这一点,检查扩展 SERVER SIDE with PHP 此处和网络中有数千个示例关于如何去做。 此外,为了额外的安全性,向您的 apache、nginx 服务器添加规则以添加标头 Content-Disposition (jpg,png,gif,???) 并且不解析上传文件夹中的 PHP 代码。

例如在 nxgin 中它会是这样的......

#add header Content-Disposition
location ^~ /upload/pictures 

        default_type application/octet-stream;

    types 
            image/gif     gif;
            image/jpeg    jpg;
            image/png    png;
    

    add_header X-Content-Type-Options 'nosniff';

    if ($request_filename ~ /(((?!\.(jpg)|(png)|(gif)$)[^/])+$)) 
        add_header Content-Disposition 'attachment; filename="$1"';
            # Add X-Content-Type-Options again, as using add_header in a new context
            # dismisses all previous add_header calls:
            add_header X-Content-Type-Options 'nosniff';
        


#do NOT parse PHP script on the upload folder
location ~ \.php$ 
    try_files $uri =404;
    include /etc/nginx/fastcgi_params;
    #if is the upload folder DO NOT parse PHP scripts on it
    if ($uri !~ "^/upload/pictures") 
        fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
    
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

【讨论】:

【参考方案4】:

我知道这是不久前被问到的。我试图实现相同的方法,在尝试了许多解决方案后,我发现 @Keaton 的代码对我有用,但它阻塞了我的 UI(我使用的是 Android Studio 2.1.2),所以我不得不将它包装在 AsyncTask 中。

所以使用@Keaton 的代码我有这个。

来自我的 onClickListener()

private View.OnClickListener btnUpload = new View.OnClickListener() 
    @Override
    public void onClick(View v) 
        new doFileUpload().execute();
    
;

然后是异步任务

public class doFileUpload extends AsyncTask<Void, Void, Void> 

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

        <Keaton's code>

     return null;
   

我希望这对遇到我遇到同样问题的人有所帮助。

【讨论】:

以上是关于Android:如何将 .mp3 文件上传到 http 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 express、mongoose 将 mp3 上传到 mongodb

如何在 Qt (QMediaPlayer) 上上传 Mp3 文件?

Android - 将音频细节添加到 mp3 文件

如何在 android studio 项目中添加 mp3 文件?

C#UWP:帮助创建应用程序:用户上传要从列表中存储和播放的MP3文件

上传到 Firebase 存储时如何使用 Cloud Functions for FIrebase 获取 mp3 文件的持续时间