首页 > 解决方案 > 如何使用 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;
    }

标签: phpandroiddownloadandroid-volley

解决方案


我建议您使用 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 方法的响应非常强大,并且您可以获得更多的东西。


推荐阅读