android - 在 Android 中的 Mysql 服务器上上传图像 我的代码出现错误 我正在使用 Volly?

标签 android mysql android-volley

这些我的 PHP 脚本很好地使用 postman 成功上传照片进行检查 但问题不是在站点代码上工作检查我的代码其工作效率 postman outman工作发现在这种情况下android为什么不正确发送数据serger如果你假装帮助他们我的工作做得很好请帮助它

require_once "connection.php";


$upload_path = 'upload/';
$server_ip = gethostbyname(gethostname());
$upload_url = 'http://'.$server_ip.'/shopping/'.$upload_path;

$responce = array();

if ($_SERVER['REQUEST_METHOD'] == 'POST') 
{
    if(isset($_POST['name']) and isset($_FILES['image']['name']))
    {
            global $connect;    

            $name = $_POST['name'];

            $fileinfo = pathinfo($_FILES['image']['name']);
            $extension = $fileinfo['extension'];

            $file_url = $upload_url . getFileName() . '.'. $extension;

            $file_path = $upload_path . getFileName() . '.'. $extension;    

            try{

                move_uploaded_file($_FILES['image']['tmp_name'],$file_path);

                $query = "INSERT INTO image(url,name) VALUES('$file_url','$name');";

                mysqli_query($connect,$query);
                {
                    $responce['error'] = false;
                    $responce['url'] = $file_url;
                    $responce['name'] = $name;
                }

            }
            catch(Exception $e)
            {
                $responce['error'] = false;
                $responce['message']=$e->getMessage();
            }
        //mysqli_close($connect);
    }
        else
        {
                $responce['error'] = true;
                $responce['message'] = 'please choose file';
        }
    echo json_encode($responce);
}

function getFileName()
 {

    global $connect;

    $sql = "SELECT MAX(id) as id FROM image";
    $result = mysqli_fetch_array(mysqli_query($connect,$sql));

    if($result['id'] == null)
    {
        return 1;
    }
    else
    {
        return ++$result['id'];
    }
    mysqli_close($connect);
 }

?> PHP代码

这些是我的 Android 代码,请帮我解决这些问题

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

ImageView imageAdd;
EditText name;
Button select,upload;
private Uri FilePath;
private Bitmap bitmap;
private String UPLOAD_URL = "http://192.168.0.103/shopping/file_upload.php";

private static final int STORAGE_PERMISSION_CODE = 2210;
private static final int PICK_IMAGE_REQUEST = 2310;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    imageAdd = findViewById(R.id.imageAdd);
    name = findViewById(R.id.name);
    select = findViewById(R.id.select);
    upload = findViewById(R.id.upload);
    select.setOnClickListener(this);
    upload.setOnClickListener(this);
}


@Override
public void onClick(View v) {

    if (v == upload){
        uploadImage();
    }

    if (v == select){
        ShowFileChooser();
    }
}




//Open Dialog For Choose Images

private void ShowFileChooser(){

    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent,"Select Picture"),PICK_IMAGE_REQUEST);

}

//Showing Result in  ImageView

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null){

        FilePath = data.getData();
        try {
            bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),FilePath);
            imageAdd.setImageBitmap(bitmap);


        } catch (IOException e) {
            e.printStackTrace();
        }

    }


} //over these method




private void uploadImage() {

    final String NAME = name.getText().toString().trim();

    StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            try {
                JSONObject jsonObject = new JSONObject(response);
                Toast.makeText(MainActivity.this, jsonObject.getString(response), Toast.LENGTH_LONG).show();
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

            Toast.makeText(MainActivity.this,error.getMessage(),Toast.LENGTH_LONG).show();
        }
    }) {


        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String,String> params = new HashMap<>();
            params.put("url",convertBitmapToString(bitmap));
            params.put("name",NAME);
            return params;
        }
    };

    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);

}

public String convertBitmapToString(Bitmap bmp) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream); //compress to which format you want.
    byte[] byte_arr = stream.toByteArray();
    String imageStr = Base64.encodeToString(byte_arr, 1);
    return imageStr;
} 

最佳答案

您正在使用 Base64 格式上传,这不是有效的方式 Case 编码的 Base64 字符串的长度比原始长度增加了更多。您可以通过 Base64 方式和多部分方式上传图像。我更喜欢多部分过程。

我认为下面的 snap-net 代码会对您有所帮助。

创造 VolleyMultipartRequest.class

public class VolleyMultipartRequest extends Request<NetworkResponse> {
private final String twoHyphens = "--";
private final String lineEnd = "\r\n";
private final String boundary = "apiclient-" + System.currentTimeMillis();

private Response.Listener<NetworkResponse> mListener;
private Response.ErrorListener mErrorListener;
private Map<String, String> mHeaders;

/**
 * Default constructor with predefined header and post method.
 *
 * @param url           request destination
 * @param headers       predefined custom header
 * @param listener      on success achieved 200 code from request
 * @param errorListener on error http or library timeout
 */
public VolleyMultipartRequest(String url, Map<String, String> headers,
                              Response.Listener<NetworkResponse> listener,
                              Response.ErrorListener errorListener) {
    super(Method.POST, url, errorListener);
    this.mListener = listener;
    this.mErrorListener = errorListener;
    this.mHeaders = headers;
}

/**
 * Constructor with option method and default header configuration.
 *
 * @param method        method for now accept POST and GET only
 * @param url           request destination
 * @param listener      on success event handler
 * @param errorListener on error event handler
 */
public VolleyMultipartRequest(int method, String url,
                              Response.Listener<NetworkResponse> listener,
                              Response.ErrorListener errorListener) {
    super(method, url, errorListener);
    this.mListener = listener;
    this.mErrorListener = errorListener;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    return (mHeaders != null) ? mHeaders : super.getHeaders();
}

@Override
public String getBodyContentType() {
    return "multipart/form-data;boundary=" + boundary;
}

@Override
public byte[] getBody() throws AuthFailureError {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);

    try {
        // populate text payload
        Map<String, String> params = getParams();
        if (params != null && params.size() > 0) {
            textParse(dos, params, getParamsEncoding());
        }

        // populate data byte payload
        Map<String, DataPart> data = getByteData();
        if (data != null && data.size() > 0) {
            dataParse(dos, data);
        }

        // close multipart form data after text and file data
        dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

        return bos.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Custom method handle data payload.
 *
 * @return Map data part label with data byte
 * @throws AuthFailureError
 */
protected Map<String, DataPart> getByteData() throws AuthFailureError {
    return null;
}

@Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
    try {
        return Response.success(
                response,
                HttpHeaderParser.parseCacheHeaders(response));
    } catch (Exception e) {
        return Response.error(new ParseError(e));
    }
}

@Override
protected void deliverResponse(NetworkResponse response) {
    mListener.onResponse(response);
}

@Override
public void deliverError(VolleyError error) {
    mErrorListener.onErrorResponse(error);
}

/**
 * Parse string map into data output stream by key and value.
 *
 * @param dataOutputStream data output stream handle string parsing
 * @param params           string inputs collection
 * @param encoding         encode the inputs, default UTF-8
 * @throws IOException
 */
private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException {
    try {
        for (Map.Entry<String, String> entry : params.entrySet()) {
            buildTextPart(dataOutputStream, entry.getKey(), entry.getValue());
        }
    } catch (UnsupportedEncodingException uee) {
        throw new RuntimeException("Encoding not supported: " + encoding, uee);
    }
}

/**
 * Parse data into data output stream.
 *
 * @param dataOutputStream data output stream handle file attachment
 * @param data             loop through data
 * @throws IOException
 */
private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException {
    for (Map.Entry<String, DataPart> entry : data.entrySet()) {
        buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
    }
}

/**
 * Write string data into header and data output stream.
 *
 * @param dataOutputStream data output stream handle string parsing
 * @param parameterName    name of input
 * @param parameterValue   value of input
 * @throws IOException
 */
private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException {
    dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
    dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd);
    //dataOutputStream.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
    dataOutputStream.writeBytes(lineEnd);
    dataOutputStream.writeBytes(parameterValue + lineEnd);
}

/**
 * Write data file into header and data output stream.
 *
 * @param dataOutputStream data output stream handle data parsing
 * @param dataFile         data byte as DataPart from collection
 * @param inputName        name of data input
 * @throws IOException
 */
private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException {
    dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
    dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
            inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd);
    if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) {
        dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd);
    }
    dataOutputStream.writeBytes(lineEnd);

    ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent());
    int bytesAvailable = fileInputStream.available();

    int maxBufferSize = 1024 * 1024;
    int bufferSize = Math.min(bytesAvailable, maxBufferSize);
    byte[] buffer = new byte[bufferSize];

    int bytesRead = fileInputStream.read(buffer, 0, bufferSize);

    while (bytesRead > 0) {
        dataOutputStream.write(buffer, 0, bufferSize);
        bytesAvailable = fileInputStream.available();
        bufferSize = Math.min(bytesAvailable, maxBufferSize);
        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
    }

    dataOutputStream.writeBytes(lineEnd);
}

/**
 * Simple data container use for passing byte file
 */
public class DataPart {
    private String fileName;
    private byte[] content;
    private String type;

    /**
     * Default data part
     */
    public DataPart() {
    }

    /**
     * Constructor with data.
     *
     * @param name label of data
     * @param data byte data
     */
    public DataPart(String name, byte[] data) {
        fileName = name;
        content = data;
    }

    /**
     * Constructor with mime data type.
     *
     * @param name     label of data
     * @param data     byte data
     * @param mimeType mime data like "image/jpeg"
     */
    public DataPart(String name, byte[] data, String mimeType) {
        fileName = name;
        content = data;
        type = mimeType;
    }

    /**
     * Getter file name.
     *
     * @return file name
     */
    public String getFileName() {
        return fileName;
    }

    /**
     * Setter file name.
     *
     * @param fileName string file name
     */
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    /**
     * Getter content.
     *
     * @return byte file data
     */
    public byte[] getContent() {
        return content;
    }

    /**
     * Setter content.
     *
     * @param content byte file data
     */
    public void setContent(byte[] content) {
        this.content = content;
    }

    /**
     * Getter mime type.
     *
     * @return mime type
     */
    public String getType() {
        return type;
    }

    /**
     * Setter mime type.
     *
     * @param type mime type
     */
    public void setType(String type) {
        this.type = type;
    }
}
}

您可以像这样在 Activity 或 Fragment 中实现

private void saveDoctorProfile(final String doctorId, final String firstName, final String lastName) {
      showDialog();

    VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST, AppConfig.LIVE_API_LINK + "getDoctorProfilePersonalinfo"
            , new Response.Listener<NetworkResponse>() {
        @Override
        public void onResponse(NetworkResponse response) {
            closeDialog();
            String resultResponse = new String(response.data);

            Log.d("doctor_profile_save", resultResponse);
            try {
                JSONObject result = new JSONObject(resultResponse);                  

                        AlertDialogManager.showSuccessDialog(getActivity(), "Your Personal Information saved successfully");
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            closeDialog();
            NetworkResponse networkResponse = error.networkResponse;
            String errorMessage = "Unknown error";
            if (networkResponse == null) {
                if (error.getClass().equals(TimeoutError.class)) {
                    errorMessage = "Request timeout";
                } else if (error.getClass().equals(NoConnectionError.class)) {
                    errorMessage = "Failed to connect server";
                }
            } else {
                String result = new String(networkResponse.data);
                try {
                    JSONObject response = new JSONObject(result);
                    String status = response.getString("status");
                    String message = response.getString("message");

                    Log.e("Error Status", status);
                    Log.e("Error Message", message);

                    if (networkResponse.statusCode == 404) {
                        errorMessage = "Resource not found";
                    } else if (networkResponse.statusCode == 401) {
                        errorMessage = message + " Please login again";
                    } else if (networkResponse.statusCode == 400) {
                        errorMessage = message + " Check your inputs";
                    } else if (networkResponse.statusCode == 500) {
                        errorMessage = message + " Something is getting wrong";
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            Log.i("Error", errorMessage);
            error.printStackTrace();
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();

            params.put("dri_drid", doctorId);
            params.put("first_name", firstName);
            params.put("last_name", lastName);

            return params;
        }

        @Override
        protected Map<String, DataPart> getByteData() {
            Map<String, DataPart> params = new HashMap<>();
            // file name could found file base or direct access from real path
            // for now just get bitmap data from ImageView

            params.put("image", new DataPart("file_avatar.jpg", AppHelper.getFileDataFromDrawable(getActivity(), ivPatientProfile.getDrawable()), "image/jpeg"));

            return params;
        }
    };

    AppController.getInstance().addToRequestQueue(multipartRequest);

}

关于android - 在 Android 中的 Mysql 服务器上上传图像 我的代码出现错误 我正在使用 Volly?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52472623/

相关文章:

php - Facebook API : Get a row from MySQL and Like an Object

mysql - AWS 2x.large 服务器 Apache 和 Mysql 配置没有很好地利用 CPU 和内存

java - Android 客户端-服务器应用程序和 Web 服务

android - 解析 JSON 数组值

android - 如何绘制内边框?

java - Android 中微调器中的 NullpointerException

java - 检查 Android 应用是否已安装,第二次检查时返回错误

android - 从 fragment 加载 timePickerDialog

mysql - 用于将人员存储在 MySQL(或任何数据库)中——多张表还是只有一张?

java - WeatherLib -- Volley.jar 错误导致应用程序崩溃