Я пытаюсь опубликовать изображения из моего android приложения в базе данных. Я успешно реализовал этот процесс в моем PHP API, и когда я тестирую его с помощью Postman, изображение загружается успешно. Чтобы добавить возможность моего приложения с помощью Retrofit 2, я прочитал несколько документов, включая этот вопрос и ответы на него, но все же мое приложение не может загрузить изображение.
Вот мой PHP API код:
$app->post('/createfood', function (Request $request, Response $response) {
if(!haveEmptyParameters(array('fname', 'unitprice', 'availcount'),$request, $response)){
if(!isset($_FILES['fpicpath']['name']))
{
$message = array();
$message['error'] = true;
$message['message'] = 'image is required';
$response->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
}
$request_data = $request->getParsedBody();
$fname = $request_data['fname'];
$unitprice = $request_data['unitprice'];
$availcount = $request_data['availcount'];
//$fpicpath = $request_data['fpicpath'];
$target_dir = "fpicuploads/";
$target_file = $target_dir . uniqid() . '.' . pathinfo($_FILES['fpicpath']['name'], PATHINFO_EXTENSION);
if(move_uploaded_file($_FILES['fpicpath']['tmp_name'], $target_file)){
$db = new DbOperations;
$result = $db->createFood($fname, $unitprice, $availcount, $target_file);
if($result == FOOD_CREATED){
$message = array();
$message['error'] = false;
$message['message'] = 'Food added successfully.';
$message['image'] = getBaseURL() . $target_file;
$response->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(201);
}else if($result == FOOD_FAILURE){
$message = array();
$message['error'] = true;
$message['message'] = 'Some error occurred while trying to add food';
$response->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
}
}else{
$message = array();
$message['error'] = true;
$message['message'] = 'Try again later!';
$response->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
}
}
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
});
public function createFood($fname, $unitprice, $availcount, $fpicpath){
$stmt = $this->con->prepare("INSERT INTO foods (fname, unitprice, availcount, fpicpath) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $fname, $unitprice, $availcount, $fpicpath);
if($stmt->execute()){
return FOOD_CREATED;
}else{
return FOOD_FAILURE;
}
}
Вот мой код активности:
public class AddFoodActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editTextFName, editTextUnitPrice, editTextAvailCount;
private ImageView image_view;
private static final int OPEN_DOCUMENT_CODE = 2;
Uri imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_food);
editTextFName = findViewById(R.id.editTextFName);
editTextUnitPrice = findViewById(R.id.editTextUnitPrice);
editTextAvailCount = findViewById(R.id.editTextAvailCount);
image_view = findViewById(R.id.image_view);
findViewById(R.id.button_add_food).setOnClickListener(this);
image_view.setOnClickListener(this);
} //End onCreate
private void addFood(){
String foodname = editTextFName.getText().toString().trim();
if(foodname.isEmpty()){
editTextFName.setError("input food name");
editTextFName.requestFocus();
return;
}
String unitprice = editTextUnitPrice.getText().toString().trim();
if(unitprice.isEmpty()){
editTextUnitPrice.setError("input unit price");
editTextUnitPrice.requestFocus();
return;
}
String availcount = editTextAvailCount.getText().toString().trim();
if(availcount.isEmpty()){
editTextAvailCount.setError("input available");
editTextAvailCount.requestFocus();
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}}
File file = new File(getRealPathFromURI(imageUri));
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("image", file.getName(), requestFile);
RequestBody fname =
RequestBody.create(MediaType.parse("multipart/form-data"), foodname);
RequestBody uprice =
RequestBody.create(MediaType.parse("multipart/form-data"), unitprice);
RequestBody acount =
RequestBody.create(MediaType.parse("multipart/form-data"), availcount);
Call<FoodPicAddedResponse> call = RetrofitClient
.getInstance()
.getApi()
.createFood(fname, uprice, acount, body);
call.enqueue(new Callback<FoodPicAddedResponse>() {
@Override
public void onResponse(Call<FoodPicAddedResponse> call, Response<FoodPicAddedResponse> response) {
if(response.code() == 201){
FoodPicAddedResponse dr = response.body();
Toast.makeText(AddFoodActivity.this, dr.getMsg(), Toast.LENGTH_LONG).show();
}else if(response.code() == 422){
Toast.makeText(AddFoodActivity.this, "This item already exists!", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<FoodPicAddedResponse> call, Throwable t) {
Toast.makeText(AddFoodActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
}
});
} // End addFood()
private void openImageChooser(){
Intent intent = new Intent(Intent.ACTION_PICK);
//intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, OPEN_DOCUMENT_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (requestCode == OPEN_DOCUMENT_CODE && resultCode == RESULT_OK) {
if (resultData != null) {
// this is the image selected by the user
imageUri = resultData.getData();
image_view.setImageURI(imageUri);
}
}
}
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_add_food:
addFood();
break;
case R.id.image_view:
openImageChooser();
break;
}
}
}
И вот мой код Api. java:
@Multipart
@POST("createfood")
Call<FoodPicAddedResponse> createFood(
@Part("fname") RequestBody fname,
@Part("unitprice") RequestBody uprice,
@Part("availcount") RequestBody acount,
@Part MultipartBody.Part body
);
Когда я бегу приложение и выберите изображение, а затем нажмите кнопку «Добавить продукт». В моем приложении отображается тост: «Этот элемент уже существует!», но это не так!
Не могли бы вы сказать мне, что не так с моим кодом? !