1

I am working in application that send images to server. I am using volley library to communicate the app with the server. The problem is, I want to send the image as FILE type so that the php server side can receive it with no problem and can move_the_uploaded file to the images folder. But the getParams of the volley StringRequest do not send FILE type, what can I DO? Help Please.

Here is the code:

This is the Activity that picks Photo from galery or capture it from Camera

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);
    }
   }
 }

And this is the main activity that send the 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);
   }
}

Finally this is the server side

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

Help Please

  • What exactly do you mean by File-Type? is it PHP specific?. I would convert the file to binary (Maybe look into some Image optimization regarding file-size. – Hannes Aug 05 '16 at 19:24
  • @Hannes... I mean to send the selected image as File so that I can receive it in server like " $_FILE['sent_image_file']; – Anselmo Alexandre Aug 05 '16 at 19:35
  • You cant send type File via HTTP. You would have to send binary/encoded information and use some sort of PHP to parse it back to FILE-Type. – Hannes Aug 05 '16 at 19:38
  • @Hannes... I got you now. But I don't have an Idea to parse it in Php.. can you show me an example – Anselmo Alexandre Aug 05 '16 at 19:40
  • I would have answered it directly - sadly i never used PHP :(. I use python as Backend! Good Luck mate! – Hannes Aug 05 '16 at 19:52

2 Answers2

0

Simply encode your image to Base64 String. The trick is:

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

You can find the sample code in this link

Ricardo Carmo
  • 266
  • 4
  • 9
0

File send use multipart see on github 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) { 
                    } 
                } 
            }); 
} 
Muhammad Waleed
  • 2,517
  • 4
  • 27
  • 75