php - 如何使用 php 和 volley android 进行间接文件下载
问题描述
当涉及到与 android 的任何形式的 http 和 volley 连接以及文件下载时,我是一个初学者,目前正在从事一个需要 android 的项目。我将文件保存在无法通过 https 直接访问以使用 volley 下载的位置。我需要使用对 php 的 POST 调用来强制通过 volley 下载到我的应用程序。我已经看过有关如何使用 HTTPCilent 信息进行强制下载的教程,但是,我的应用程序不支持使用直接 HTTPClient 调用。我们正在处理更大尺寸的文件。具体来说,我的应用程序会下载为 android sceneform 生成的 sfb 文件。
我试图让它在 volley 向我的 php 页面发送一个字符串 POST 请求的地方回显文件的内容。但是,当我尝试然后显示 sfb 时,当我尝试将我的模型放在屏幕上时,我从 sceneform 中得到一个索引错误。已经验证直接存储在我的应用程序中的原始文件可以正确显示。
有谁知道如何使用 volley 进行这种类型的下载?如果不使用 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;
}
或者为了更多更好的方法,我个人向任何喜欢 Lightweight Volley for Api Integrations 的 Android 开发人员推荐一个库。
https://github.com/Lib-Jamun/Volley
dependencies {
compile 'tk.jamun:volley:0.0.4'
}
他的文档目前可用于 0.0.4 版本,但这个库的美是在 0.0.7 版本上,您不需要手动解析或创建 JSON,您只需传递您的模型类和其他自动完成的事情。它用于背景和正常使用的文件相关类,它对您的 Api 方法的响应非常强大,并且您可以获得更多的东西。
推荐阅读
- reactjs - 使用 ref 在反应中单击了获取元素
- slack - 您可以隐藏 Slack 预览的 URL 吗?
- android - 在函数中给它一个值后,值变为空
- reactjs - 使用 shouldComponentUpdate() 防止重新安装昂贵的(类)组件(图像列表,路由器内部)
- powershell - 尝试在 Jenkins 配置中使用 winrm 将特定文件夹从本地系统复制到远程 VM 时如何避免此错误?
- java - 通过 ResourceBundle 访问属性文件时出错
- flutter - Flutter Plugins pub 冲突,当其他依赖项依赖它并且它还在开发中时
- latex - 如何更改奇数页和偶数页的顶部和底部页边距?
- java - 前面的词=做什么?
- xslt - 无法使用“UTF-8”和“ISO-8859-1”显示字符“Œ œ Š š Ÿ † ‡ • ... ‰ € ™”