My retrofit instance is working fine with localhost (both android code and postman), and working fine online with postman. But when I go to Amazon AWS instance (a.k.a online) the android part is not working. Please see my code below. The error log from android is D/response: {"error":true,"message":"Required parameters are not available"}
Interestingly the problem is with large file sizes 2M, small file sizes 24KB are getting uploaded fine. I have already checked the php.ini file the max sizes there are 25MB
I am following this tutorial : https://www.simplifiedcoding.net/retrofit-upload-file-tutorial/
public interface Api {
//the base URL for our API
//make sure you are not using localhost
//find the ip usinc ipconfig command
String BASE_URL = "http://creative-thinker.com/files/images/secret_crushes/";
//this is our multipart request
//we have two parameters on is name and other one is description
@Multipart
@POST("Api.php?apicall=upload")
Call<MyResponse> uploadImage(@Part("image"; filename="myfile.jpg" ")
RequestBody file, @Part("desc") RequestBody desc);
}
My Object Class
public class MyResponse {
public boolean error;
String message;
}
My Fragment
ivImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Open The File Choose And Send To Activity For Result
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 100);
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && data != null) {
//the image URI
Uri selectedImage = data.getData();
//calling the upload file method after choosing the file
uploadFile(selectedImage, "My Image");
}
}
private void uploadFile(Uri fileUri, String desc) {
//creating a file
File file = new File(getRealPathFromURI(fileUri));
//creating request body for file
RequestBody requestFile = RequestBody.create(MediaType.parse(getContext().getContentResolver().getType(fileUri)), file);
RequestBody descBody = RequestBody.create(MediaType.parse("text/plain"), desc);
//The gson builder
Gson gson = new GsonBuilder()
.setLenient()
.create();
//creating retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
//creating our api
Api api = retrofit.create(Api.class);
//creating a call and calling the upload image method
Call<MyResponse> call = api.uploadImage(requestFile, descBody);
//finally performing the call
call.enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (!response.body().error) {
Toast.makeText(getContext().getApplicationContext(), "File Uploaded Successfully...", Toast.LENGTH_LONG).show();
} else {
MyResponse res= response.body();
Log.d("response", new Gson().toJson(res));
Toast.makeText(getContext().getApplicationContext(), "Some error occurred...", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<MyResponse> call, Throwable t) {
Toast.makeText(getContext().getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
/*
* This method is fetching the absolute path of the image file
* if you want to upload other kind of files like .pdf, .docx
* you need to make changes on this method only
* Rest part will be the same
* */
private String getRealPathFromURI(Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
CursorLoader loader = new CursorLoader(getContext(), contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String result = cursor.getString(column_index);
cursor.close();
return result;
}
FileHandler.php
<?php
class FileHandler
{
private $con;
public function __construct()
{
require_once dirname(__FILE__) . '/DbConnect.php';
$db = new DbConnect();
$this->con = $db->connect();
}
public function saveFile($file, $extension, $desc)
{
$name = round(microtime(true) * 1000) . '.' . $extension;
$filedest = dirname(__FILE__) . UPLOAD_PATH . $name;
move_uploaded_file($file, $filedest);
$url = $server_ip = gethostbyname(gethostname());
$stmt = $this->con->prepare("INSERT INTO images (description, image) VALUES (?, ?)");
$stmt->bind_param("ss", $desc, $name);
if ($stmt->execute()) {
return true;
}
return false;
}
public function getAllFiles()
{
$stmt = $this->con->prepare("SELECT id, description, image FROM images ORDER BY id DESC");
$stmt->execute();
$stmt->bind_result($id, $desc, $url);
$images = array();
while ($stmt->fetch()) {
$temp = array();
$absurl = 'http://' . gethostbyname(gethostname()) . '/files/images/secret_crushes' . UPLOAD_PATH . $url;
$temp['id'] = $id;
$temp['desc'] = $desc;
$temp['url'] = $absurl;
array_push($images, $temp);
}
return $images;
}
}
Api.php
<?php
require_once dirname(__FILE__) . '/FileHandler.php';
$response = array();
if (isset($_GET['apicall'])) {
switch ($_GET['apicall']) {
case 'upload':
if (isset($_POST['desc']) && strlen($_POST['desc']) > 0 && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
$upload = new FileHandler();
$file = $_FILES['image']['tmp_name'];
$desc = $_POST['desc'];
if ($upload->saveFile($file, getFileExtension($_FILES['image']['name']), $desc)) {
$response['error'] = false;
$response['message'] = 'File Uploaded Successfullly';
}
} else {
$response['error'] = true;
$response['message'] = 'Required parameters are not available';
}
break;
case 'getallimages':
$upload = new FileHandler();
$response['error'] = false;
$response['images'] = $upload->getAllFiles();
break;
}
}
echo json_encode($response);
function getFileExtension($file)
{
$path_parts = pathinfo($file);
return $path_parts['extension'];
}
I am trying to catch the values of items in Api.php using
$response['message'] = $string;
just where $response['message'] = 'Required parameters are not available';
and getting the following results
$string = $_POST['desc'];
D/response: {"error":true,"message":"My Image"}
$string = $_POST['desc'];
$string = strlen($string);
D/response: {"error":true,"message":"8"}
$string = $_FILES['image']['error'];
D/response: {"error":true}
$string = UPLOAD_ERR_OK;
D/response: {"error":true,"message":"0"}
And removing && $_FILES['image']['error'] === UPLOAD_ERR_OK
enters the data into database but no image still uploaded
See Question&Answers more detail:
os