Как сделать косвенную загрузку файлов с помощью php и volley android - PullRequest
0 голосов
/ 24 февраля 2019

Я новичок, когда дело доходит до любой формы http и volley соединений с android, а также с загрузкой файлов и в настоящее время работаю над проектом, который требует как для android.У меня есть файлы, сохраненные в месте, к которому я не могу получить прямой доступ через https для загрузки с использованием залпа.Мне нужно использовать вызов POST для php, чтобы вызвать загрузку через залп для моего приложения.Я видел руководства по принудительной загрузке с использованием информации HTTPCilent, однако мое приложение не поддерживает использование прямых вызовов HTTPClient.Мы обрабатываем файлы большего размера.В частности, мое приложение загружает файл sfb, созданный для сцены Android.

Я пытался получить его там, где volley отправляет на мою страницу 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 голосов
/ 03 марта 2019

Я нашел способ сделать это, используя залп.Мне удалось использовать 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);
?>
0 голосов
/ 24 февраля 2019

Я рекомендую вам использовать 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;
}

Или, для более лучшего пути, есть библиотека, которую я лично рекомендую любому разработчику Android, который любит LightWeight Volley for Api Integrations.

https://github.com/Lib-Jamun/Volley

dependencies {
    compile 'tk.jamun:volley:0.0.4'
}

Его документация уже доступна для версии 0.0.4, но прелесть этой библиотеки в версии 0.0.7, где вам не нужно анализировать или создавать JSON вручнуювам просто нужно передать свой класс модели и другие вещи, выполненные автоматически.Его классы, относящиеся к файлам, для BackGround и обычного использования. Его реакция на ваши методы Api очень сильна, и вы получите гораздо больше вещей.

...