Sending an image file message using Retrofit?
I am testing a way to send an image using the Retrofit library. The Retrofit docs here: http://square.github.io/retrofit/ have a way to use the @MultiPart annotation. I am trying to use as documentation but still doesn't work for me.
How can i do this?
This is how I am trying.
Php file of web service
if($_REQUEST["uploadfile"] == "add"){
$uploaddir = 'C:\Users\fernando\Pictures';
$uploadfile = $uploaddir . $_FILES['userfile']['name'];
$response = array();
//param
$response["nome"] = $_REQUEST["nome"];
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name'])) {
$response["msg"] = "O arquivo é valido e foi carregado com sucesso. Aqui esta alguma informação:\n";
print_r($_FILES);
} else {
$response["msg"] = "Possivel ataque de upload! Aqui esta alguma informação:\n";
print_r($_FILES);
}
$json = json_encode($response);
echo $json;
}
Usuario listener
public interface UsuarioListener {
//send an image with params with Post
@Multipart
@POST("/android/login.php")
void setUserImage(
@QueryMap Map<String, String> params,
@Part("pathImage") TypedFile file,
Callback<JsonElement> response);
}
activity
btnEnviar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setUserImage();
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE &&
resultCode == RESULT_OK &&
null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
pathImage = cursor.getString(columnIndex);
cursor.close();
}
}
public void setUserImage() {
HashMap<String, String> params = new HashMap<String, String>();
params.put("nome", "Fernando Paiva Campos");
RestAdapter adapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(END_POINT).build();
UsuarioListener listener = adapter.create(UsuarioListener.class);
TypedFile image = new TypedFile("image/jpg", new File(pathImage));
listener.setUserImage(
params,
image,
new Callback<JsonElement>() {
@Override
public void success(JsonElement arg0, Response arg1) {
Log.i("JSON_ELEMENT:", arg0.toString() + "");
}
@Override
public void failure(RetrofitError arg0) {
Log.e("ERROR:", arg0.getLocalizedMessage());
}
});
}
Exception
E / ERROR: (5200): com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient (true) to accept invalid JSON on line 1 column 6
source to share
It looks like the above error is related to your php output. It is not clear if the download was successful or not, but your response is not valid JSON because before you echo the JSON response, you will also print out the value $_FILES
. Try commenting out the lines with the following code in your php file.
print_r($_FILES);
source to share
There are two amendments to your problems:
In this code:
public interface UsuarioListener {
//send an image with params with Post
@Multipart
@POST("/android/login.php")
void setUserImage(
@QueryMap Map<String, String> params,
// the @Part has the parameter "pathImage".
// You should pass this in your php code.
@Part("pathImage") TypedFile file,
Callback<JsonElement> response);
}
So your php code should look like:
if($_REQUEST["uploadfile"] == "add"){
$uploaddir = 'C:\Users\fernando\Pictures';
$uploadfile = $uploaddir . $_FILES['userfile']['name'];
$response = array();
//param
$response["nome"] = $_REQUEST["nome"];
if (move_uploaded_file($_FILES['pathImage']['tmp_name'], $uploaddir . $_FILES['pathImage']['name']))
Final adjustments in your Retrofit client:
TypedFile typedImage = new TypedFile("application/octet-stream", photo);
For more information, you may have an error in my answer to a similar problem: Failed to load image with multifile.
source to share