【问题标题】:How to send image File type to php server using volley library如何使用 volley 库将图像文件类型发送到 php 服务器
【发布时间】:2016-12-12 06:52:28
【问题描述】:

我正在开发将图像发送到服务器的应用程序。 我正在使用 volley 库将应用程序与服务器通信。 问题是,我想将图像作为 FILE 类型发送,以便 php 服务器端可以毫无问题地接收它,并且可以将_the_uploaded 文件移动到图像文件夹。但是凌空StringRequest的getParams没有发送FILE类型,怎么办?请帮忙。

代码如下:

这是从图库中选择照片或从相机中捕获照片的 Activity

public class PhotoPicker extends AppCompatActivity {

private static final String ARG_PARAM1 = "uriOfTheImage";

private static final int REQUEST_STORAGE = 0;
private static final int REQUEST_IMAGE_CAPTURE = REQUEST_STORAGE + 1;
private static final int REQUEST_LOAD_IMAGE = REQUEST_IMAGE_CAPTURE + 1;
private Uri cameraImageUri = null;
private String path;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_photo);

    // Get the Intent sent data to handle camera
    Intent i = getIntent();
    String flag = i.getStringExtra("Camera");
    if (flag.equals("photo_by_camera")) {
        // Take photo by camera
        requestStoragePermission();
    } else if (flag.equals("photo_by_library")) {
        // Pick photo from library
        loadPhotoOnLibrary();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
        Uri selectedImage = null;
        if (requestCode == REQUEST_LOAD_IMAGE && data != null) {
            selectedImage = data.getData();
        } else if (requestCode == REQUEST_IMAGE_CAPTURE) {
            // Do something with imagePath
            selectedImage = cameraImageUri;
        }

        // Getting the image path
        path = getPath(selectedImage);

        if (selectedImage != null) {
            // Launch the popUp preview Image and add the photo caption
            showPhoto(path);
        }
    }
}

/**
 * This method will add the show photo fragment
 *
 * @param fileImage image
 */
private void showPhoto(String fileImage) {
    // Open the activity that will handle the Image stuff
    Intent i = new Intent(PhotoPicker.this, Main.class);
    i.putExtra(ARG_PARAM1, fileImage);
    startActivity(i);
}

/**
 * This method will just popup a dialog fragment and get the image from user
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void requestStoragePermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
    } else {
        // Eh, prompt anyway
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_STORAGE) {
        if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            takePhotoByCamera(); // Launch the camera
        }
    } else {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

/**
 * For images captured from the photo_picker, we need to create a File first to tell the photo_picker
 * where to store the image.
 *
 * @return the File created for the image to be store under.
 */
private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File photoFile = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    cameraImageUri = Uri.fromFile(photoFile);
    return photoFile;
}


/**
 * This checks to see if there is a suitable activity to handle the `ACTION_PICK` intent
 * and returns it if found. {@link Intent#ACTION_PICK} is for picking an image from an external app.
 *
 * @return A prepared intent if found.
 */
@Nullable
private Intent createPickIntent() {
    Intent picImageIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    if (picImageIntent.resolveActivity(getPackageManager()) != null) {
        return picImageIntent;
    } else {
        return null;
    }
}

/**
 * This checks to see if there is a suitable activity to handle the {@link MediaStore#ACTION_IMAGE_CAPTURE}
 * intent and returns it if found. {@link MediaStore#ACTION_IMAGE_CAPTURE} is for letting another app take
 * a picture from the photo_picker and store it in a file that we specify.
 *
 * @return A prepared intent if found.
 */
@Nullable
private Intent createCameraIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        return takePictureIntent;
    } else {
        return null;
    }
}

/**
 * This utility function combines the photo_picker intent creation and image file creation, and
 * ultimately fires the intent.
 *
 * @see {@link #createCameraIntent()}
 * @see {@link #createImageFile()}
 */
private void takePhotoByCamera() {
    Intent takePictureIntent = createCameraIntent();
    // Ensure that there's a photo_picker activity to handle the intent
    if (takePictureIntent != null) {
        // Create the File where the photo should go
        try {
            File imageFile = createImageFile();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        } catch (IOException e) {
            // Error occurred while creating the File
        }
    }
}

public String getPath(Uri uri) {
    String res = null;
    String[] proj = {MediaStore.Images.Media.DATA};
    Cursor cursor = getContentResolver().query(uri, proj, null, null, null);
    if (cursor != null) {
        if (cursor.moveToFirst()) {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            res = cursor.getString(column_index);
        }
        cursor.close();
    }
    return res;
}

/**
 * This will open the library and get a photo
 */
private void loadPhotoOnLibrary() {
    Intent loadPhoto = createPickIntent();
    // Ensure that there's a photo_picker activity to handle the intent
    if (loadPhoto != null) {
        startActivityForResult(loadPhoto, REQUEST_LOAD_IMAGE);
    }
   }
 }

这是发送图像的主要活动

public class Main extends AppCompatActivity {

private ProgressDialog pd;
private int sucesso = 0;
private static final String ARG_PARAM1 = "uriOfTheImage";
private String path;
private CoordinatorLayout coordinatorLayout;
private String message_restult = "";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    if (getSupportActionBar() != null) {
        getSupportActionBar().setTitle("Sending image");
    }


    Intent i = getIntent();
    if (i.getStringExtra(ARG_PARAM1) != null) {
        path = i.getStringExtra(ARG_PARAM1);
    }

    coordinatorLayout = (CoordinatorLayout) findViewById(R.id.container);
    AppCompatButton button = (AppCompatButton) findViewById(R.id.start);
    AppCompatImageView image = (AppCompatImageView) findViewById(R.id.image);
    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);

    if (image != null) {
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        image.setImageBitmap(bitmap);
    }
    if (button != null)
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager manager = getFragmentManager();
                PopUpCamera fr = new PopUpCamera();
                FragmentTransaction transaction = manager.beginTransaction();
                transaction.add(R.id.container, fr, "PopupCamera")
                        .commit();
            }
        });

    if (fab != null)
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendImage(path);
            }
        });
}

private void sendImage(final String uri) {
    final String url = "http://inserts.php";
    String req_tag = "send_image";
    pd = new ProgressDialog(Main.this);
    pd.setMessage("Hold...sending");
    pd.setCancelable(false);
    pd.setIndeterminate(false);
    pd.show();

    StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            // Log cat
            Log.d("Response:", response);
            try {
                JSONObject object = new JSONObject(response);
                sucesso = object.getInt("Success");
                message_restult = object.getString("Message");

                pd.dismiss();
                if (sucesso == 1) {
                    Snackbar.make(coordinatorLayout, R.string.success, Snackbar.LENGTH_LONG)
                            .show();
                } else {
                    Snackbar.make(coordinatorLayout, message_restult, Snackbar.LENGTH_LONG)
                            .show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            pd.dismiss();
            Snackbar.make(coordinatorLayout, R.string.volley_error, Snackbar.LENGTH_LONG)
                    .show();
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("uri", uri);
            return params;
        }
    };
    VolleyAPI.getmInstance().addToRequestQueue(request, req_tag);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
   }
}

最后这是服务器端

<?php
/**
* @Wrote by @Anselmo Alexandre Munguambe
*/

#include the file that contains the functions to the database
include_once('db_connect.php');
$DB = new Connection();
$c = $DB->makeConnection();

#prepare the JSon array response
$response = array();

# get all the things sent here

if (!empty(isset($_FILES['uri']))) {

    # all good to send the Pedido ...
    $Foto = $_FILES['uri'];

    # Path to move uploaded files
    $target_path = "images/";
    $Nome = "anselmo" . basename($Foto['name']);
    $target_path = $target_path . $Nome;

    # Throws exception incase file is not being moved
    try {
        if (!move_uploaded_file($Foto['tmp_name'], $target_path)) {
            # in case the photo did not been moved
            return "";
        }

        # Returning the exactly location of the photo
        return $Nome;
    } catch (Exception $e) {
        # Exception occurred. Make error flag true
        return "";
    }

    # Move the photo to the server
    if($Nome != ""){

        $query = "CALL `insert_image`('{$Nome}')";
        $result = mysqli_query($c,$query);

        # Success photo already on the server dude... 
        if($result){
            # Success
            $response["Success"] = 1;
            $response["Message"] = "All things set...";             
        } else{
            $response["Success"] = 0;
            $response["Message"] = "Erro ao salvar caminho da foto do pedido...";               
        }
    } else{
        $response["Success"] = 0;
        $response["Message"] = "Erro ao mover a foto...";   
    }
} else {
    $response["Success"] = 0;
    $response["Message"] = "Nada Enviado...";
}

# showing the JSon
 echo json_encode($response);
?>

请帮忙

【问题讨论】:

  • 文件类型到底是什么意思?它是特定于 PHP 的吗?我会将文件转换为二进制文件(也许研究一些关于文件大小的图像优化。
  • @Hannes... 我的意思是将所选图像作为文件发送,以便我可以在服务器中接收它,例如“ $_FILE['sent_image_file'];
  • 您不能通过 HTTP 发送类型文件。您必须发送二进制/编码信息并使用某种 PHP 将其解析回 FILE-Type。
  • @Hannes...我现在知道了。但是我没有用 Php 解析它的想法。你能给我举个例子吗
  • 我会直接回答 - 遗憾的是我从未使用过 PHP :(。我使用 python 作为后端!祝你好运!

标签: android


【解决方案1】:

文件发送使用multipartgithub implementaion

private void sendImage(final Uri uri) {
    final String url = "http://inserts.php";
    String req_tag = "send_image";
    pd = new ProgressDialog(Main.this);
    pd.setMessage("Hold...sending");
    pd.setCancelable(false);
    pd.setIndeterminate(false);
    pd.show();
 //get real path of image 

 String image_path = getPath(uri);
   MultipartRequest multipartRequest =

            new MultipartRequest(url, params, image_path, new Response.Listener<String>() { 
                @Override 
                public void onResponse(String response) { 
                    Log.e(TAG, "Success Response: " + response.toString()); 

                } 
            }, new Response.ErrorListener() { 

                @Override 
                public void onErrorResponse(VolleyError error) { 

                    if (error.networkResponse != null) { 
                        Log.e(TAG, "Error Response code: " + 
                                error.networkResponse.statusCode); 


                        try { 



                    } 


                    if (error instanceof NetworkError) { 
                    } else if (error instanceof ServerError) { 
                    } else if (error instanceof AuthFailureError) { 
                    } else if (error instanceof ParseError) { 
                    } else if (error instanceof NoConnectionError) { 
                    } else if (error instanceof TimeoutError) { 
                    } 
                } 
            }); 
} 

【讨论】:

  • 嘿伙计...我无法解析 HttpEntity...我必须添加什么依赖项?...帮助
  • @AnselmoAlexandreMunguambe 你试过这个吗??
【解决方案2】:

只需将您的图像编码为 Base64 字符串。诀窍是:

public String getStringImage(Bitmap bmp){
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] imageBytes = baos.toByteArray();
    String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return encodedImage;
}

你可以在link找到示例代码

【讨论】:

    猜你喜欢
    • 2015-10-20
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多