我是初学者,当谈到任何形式的http和凌空连接与android以及文件下载,目前正在开发一个需要Android的项目。我将文件保存在一个我无法通过https直接访问的位置使用凌空下载。我需要使用POST调用php来强制通过凌空下载到我的应用程序。我已经看过如何使用HTTPCilent信息进行强制下载的教程,但我的应用程序不支持使用直接的HTTPClient调用。我们正在处理更大的文件。具体来说,我的应用程序下载为android sceneform生成的sfb文件。
我试图让它在volley发送一个字符串POST请求到我的php页面,回复文件的内容。但是,当我尝试然后显示sfb时,我在尝试将模型放在屏幕上时会从sceneform获得索引错误。已经验证直接存储在我的应用程序中的原始文件正确显示。
有谁知道如何使用截击这种类型的下载?如果不可能有另一种方法没有使用HTTPClient库来做到这一点?
下面是我的代码部分,目前处理我的PHP和应用程序之间的通信:
PHP:
<?php
ini_set('display_errors',1);
$fileID = $_POST["model_id"];
$filePath = $_POST["model_path"];
$downloadPath = "<dir only this page can get to> /$fileID/$filePath";
readfile($downloadPath);
//$fileStr = file_get_contents ($downloadPath);
// echo $fileStr;
?>
安卓:
private StringRequest generatePhpDownloadRequest(String FileName, String FileID)
{
StringRequest request = new StringRequest(Request.Method.POST, WebsiteInterface.DOWNLOAD_URL_STRING,
new Response.Listener<String>()
{
@Override
public void onResponse(String response) {
// response
Log.d("Response", response);
//@todo save the return information
/*if(response.length() > 60) {
createAlertDialog("LNG:" + response.substring(0, 56));
}else {
createAlertDialog(response);
}*/
if(response.length() > 10)
{
try {
if (response!=null) {
FileOutputStream outputStream;
String name=ModelInformation[0];
outputStream = openFileOutput(name, Context.MODE_PRIVATE);
outputStream.write(response.getBytes(Charset.forName("UTF-8")));
outputStream.close();
ReturnWithResult(RESULT_OK, getFilesDir().getAbsolutePath());
//Toast.makeText(this, "Download complete.", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("KEY_ERROR", "UNABLE TO DOWNLOAD FILE");
e.printStackTrace();
ReturnWithResult(RESULT_CANCELED, "KEY_ERROR: UNABLE TO DOWNLOAD FILE");
}
ReturnWithResult(RESULT_OK, getFilesDir().getAbsolutePath());
}
else
{
ReturnWithResult(RESULT_CANCELED, "invalid file");
}
//ReturnWithResult(RESULT_CANCELED, "Sucess but no file save");
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error) {
String msg = "unknown error";
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
//This indicates that the reuest has either time out or there is no connection
//Log.d(TAG, "Connection Error!");
msg = "Connection Error!";
} else if (error instanceof AuthFailureError) {
//Error indicating that there was an Authentication Failure while performing the request
//Log.d(TAG, "Authentication Error!");
msg = "Authentication Error!";
} else if (error instanceof ServerError) {
//Indicates that the server responded with a error response
//Log.d(TAG, "Server Error!");
msg = "Server Error!";
} else if (error instanceof NetworkError) {
//Indicates that there was network error while performing the request
//Log.d(TAG, "Network Error!");
msg = "Network Error!";
} else if (error instanceof ParseError) {
// Indicates that the server response could not be parsed
//Log.d(TAG, "Parsing Error!");
msg = "Parsing Error!";
}
VolleyLog.d(TAG, "Error: " + error.getMessage());
ReturnWithResult(Activity.RESULT_CANCELED, "VOLLEY: " + msg);
}
}
) {
@Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("model_id", FileID);
params.put("model_path", FileName);
return params;
}
};
return request;
}
我建议你使用HttpConnection调用来下载File Payload,这是代码,
private static final String twoHyphens = "--";
private static final String lineEnd = "\r\n";
private static final String boundary = "*****";
private String uploadFile(File sourceFile) {
HttpURLConnection.setFollowRedirects(false);
DataInputStream inStream = null;
try {
connection = (HttpURLConnection) new URL(URL_POST_MESSAGE_FILE).openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
String boundary = "---------------------------boundary";
String tail = lineEnd + "--" + boundary + "--" + lineEnd;
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
connection.setRequestProperty(modelHeader.getValue(), modelHeader.getValue());
String metadataPart = "--" + boundary + lineEnd
+ "Content-Disposition: form-data; name=\"metadata\"\r\n\r\n"
+ "" + lineEnd;
long fileLength = sourceFile.length() + tail.length();
String stringData = metadataPart + "--" + boundary + lineEnd
+ "Content-Disposition: form-data; name=\"fileToUpload\"; filename=\""
+ sourceFile.getName() + "\"\r\n"
+ "Content-Type: application/octet-stream" + lineEnd
+ "Content-Transfer-Encoding: binary" + lineEnd + "Content-length: " + fileLength + lineEnd + lineEnd;
long requestLength = stringData.length() + fileLength;
connection.setRequestProperty("Content-length", "" + requestLength);
connection.setFixedLengthStreamingMode((int) requestLength);
connection.connect();
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes(stringData);
out.flush();
int bytesRead;
FileInputStream fileInputStream = new FileInputStream(sourceFile);
BufferedInputStream bufInput = new BufferedInputStream(fileInputStream);
byte buf[] = new byte[(int) sourceFile.length() / 200];
while ((bytesRead = bufInput.read(buf)) != -1) {
out.write(buf, 0, bytesRead);
out.flush();
}
out.writeBytes(tail);
out.flush();
out.close();
} catch (IOException e) {
Log.e(VolleyDownUpFiles.class.getSimpleName(), e.getMessage() + " ");
return null;
}
try {
inStream = new DataInputStream(connection.getInputStream());
String str;
if ((str = inStream.readLine()) != null) {
inStream.close();
return str;
}
} catch (IOException e) {
Log.e("Tag", e.getMessage());
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}
或者更好的方式,有一个图书馆,我个人推荐给任何喜欢轻量级Volley for Api Integrations的Android开发者。
https://github.com/Lib-Jamun/Volley
dependencies {
compile 'tk.jamun:volley:0.0.4'
}
他的文档目前可用于0.0.4版本,但是这个库的Beauty是0.0.7版本,你不需要手动解析或创建JSON,你只需要传递你的模型类和其他自动完成的事情。它的BackGround和Normal Use的文件相关类,它对你的Api方法的响应非常强大,你可以获得更多的东西。
我发现了一种使用Volley的方法。我能够使用从here获得的InputStreamVollyRequest。通过将我的变量添加到参数并调用我的php文件,我能够从我的数据库间接成功下载文件。下面是我现在成功执行的代码片段。 (关于我的文件路径和参数的细节已被抽象出来)。请注意,参数似乎没有做任何事情,但我抽象出如何使用它们来确定相对文件路径。我也在这篇文章中没有错误处理它只是将错误信息保存到应用程序上生成的文件中,文件名是param1的值。
Android:java
private InputStreamVolleyRequest generatePHPDownloadRequest(String param1Value, String param2Value)
{
Map<String,String> inParams = new HashMap<String,String>();
inParams.put("param1", param1Value);
inParams.put("param2", param2Value);
String requestURL = WebsiteInterface.DOWNLOAD_URL_STRING;
InputStreamVolleyRequest request = new InputStreamVolleyRequest(Request.Method.POST, requestURL,
new Response.Listener<byte[]>() {
@Override
public void onResponse(byte[] response) {
// TODO handle the response
try {
if (response!=null) {
FileOutputStream outputStream;
String name=param1Value;
outputStream = openFileOutput(name, Context.MODE_PRIVATE);
outputStream.write(response);
outputStream.close();
ReturnWithResult(RESULT_OK, getFilesDir().getAbsolutePath());
//Toast.makeText(this, "Download complete.", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("KEY_ERROR", "UNABLE TO DOWNLOAD FILE");
e.printStackTrace();
ReturnWithResult(RESULT_CANCELED, "KEY_ERROR: UNABLE TO DOWNLOAD FILE");
}
}
} ,new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO handle the error
error.printStackTrace();
String msg = "unknown error";
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
//This indicates that the reuest has either time out or there is no connection
//Log.d(TAG, "Connection Error!");
msg = "Connection Error!";
} else if (error instanceof AuthFailureError) {
//Error indicating that there was an Authentication Failure while performing the request
//Log.d(TAG, "Authentication Error!");
msg = "Authentication Error!";
} else if (error instanceof ServerError) {
//Indicates that the server responded with a error response
//Log.d(TAG, "Server Error!");
msg = "Server Error!";
} else if (error instanceof NetworkError) {
//Indicates that there was network error while performing the request
//Log.d(TAG, "Network Error!");
msg = "Network Error!";
} else if (error instanceof ParseError) {
// Indicates that the server response could not be parsed
//Log.d(TAG, "Parsing Error!");
msg = "Parsing Error!";
}
VolleyLog.d(TAG, "Error: " + error.getMessage());
ReturnWithResult(Activity.RESULT_CANCELED, "VOLLEY: " + msg);
}
}, (HashMap<String, String>) inParams);
return request;
}
PHP
<?php
ini_set('display_errors',1);
if(!isset($_POST["param1"]))
{
exit("PARAM 1 EMPTY");
}
if(!isset($_POST["param2"]))
{
exit("PARAM 2 EMPTY");
}
$param1Value = $_POST["param1"];
$param2Value = $_POST["param2"];
$downloadPath = "<relative path from php file location to the desired file>";
readfile($downloadPath);
?>