在与android进行任何形式的http和凌空连接以及文件下载方面,我是一个初学者,目前正在开发一个需要同时具备android和android的项目。我将文件保存在无法直接通过https访问以使用凌空下载的位置。我需要对php使用POST调用,以强制通过凌空下载到我的应用程序。我看过有关如何使用HTTPCilent信息进行强制下载的教程,但是,我的应用程序不支持直接使用HTTPClient调用。我们正在处理较大的文件。具体来说,我的应用下载了为Android Sceneform生成的sfb文件。
我已经尝试过在凌空向我的php页面发送字符串POST请求的地方,它回显文件的内容。但是,当我尝试显示sfb时,在尝试将模型放在屏幕上时,我从场景窗体中得到了索引错误。已经证实原始文件直接存储在我的应用程序中时可以正确显示。
有人知道如何用凌空抽空进行这种下载吗?如果不可能,是否有另一种方法可以不使用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;
?>
Android:
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;
}
答案 0 :(得分:0)
我建议您使用HttpConnection调用下载文件有效负载, 这是代码,
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版本, 但是该库的Beauty是0.0.7版,您不需要手动解析或创建JSON,您只需要传递模型类和其他自动完成的事情即可。 它的文件相关类可用于BackGround和常规使用,它对Api方法的响应非常强大,并且您可以得到更多的东西。
答案 1 :(得分:0)
我找到了一种使用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);
?>