我想将.mp3文件(仅限)从设备上传到我的服务器。
我想浏览媒体数据的路径并选择任何mp3文件并上传。
我该怎么做?
答案 0 :(得分:36)
我最终使用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文件相同的目录中创建一个“uploads”文件夹。
4)您显然必须将我撰写的网址http://mywebsite.com/directory/upload.php更改为您自己的网站。
答案 1 :(得分:6)
感谢Keaton的好建议。
我已经安排了一些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();
}
}
}
答案 2 :(得分:1)
请注意,如果您复制&amp;粘贴上面的PHP代码,任何人都可以将恶意PHP脚本上传到你的服务器并运行它,总是要注意这一点,用PHP检查扩展SERVER SIDE这里有成千上万的例子,在网上有关如何做到这一点。 另外为了额外的安全性,为你的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;
}
答案 3 :(得分:0)
我知道这被问了一会儿。我试图实现相同的功能,在尝试了许多解决方案后,我发现了这一点 @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();
}
};
然后是AsyncTask
public class doFileUpload extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
<Keaton's code>
return null;
}
}
我希望这对任何遇到同样问题的人都有帮助。