如何使用PHP和Volley Android进行间接文件下载

时间:2019-02-23 23:41:36

标签: php android download android-volley

在与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;
    }

2 个答案:

答案 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);
?>