Как выбрать изображение из памяти телефона (внешнего/внутреннего) и загрузить в базу данных sqlite?

Я работаю над приложением, и в наиболее важном действии должно произойти следующее:

  • Пользователь заполняет форму и выбирает изображение со своего телефона.
  • Когда он нажимает «Добавить данные», я хочу сохранить выбранное изображение (или его путь, все, что позволяет мне получить его позже) в локальную базу данных и получить позже в другом действии.

Что я пробовал:

  • Сохраните изображение в БД как большой двоичный объект и извлеките его позже как растровое изображение, но, очевидно, я узнал, что это не удается, когда используется изображение большего размера, для большого двоичного объекта установлено значение null.
  • Пытался получить путь к файлу выбранного изображения, но этот путь к файлу имеет формат, подобный этому: /document/msf:35

Затем я попытался получить физический путь, используя эти ответы SO: >ссылка1, ссылка2, link3 и эти ответы в целом: link4, link5.

Пожалуйста, не отмечайте это как дубликат, потому что решение в других ответах мне не подходит

Открытие намерения загрузить фото:

// upload photo
photoActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
  public void onActivityResult(ActivityResult result) {
    if (result.getResultCode() == Activity.RESULT_OK) {
      Intent intent = result.getData();
      if (intent.getData() == null) {
        Log.d("AddTrip", "null data from image");
      }
      Uri uri = intent.getData();
      // processing here..
    }
  }
});

}
private void uploadPhotoClicked() {
  Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
  intent.setType("image/*");
  photoActivityResultLauncher.launch(intent);
}

Пожалуйста, предложите решение, чтобы обойти это, а также лучшие практики для реализации этого типа функций, я пытался использовать PathUtil, но не указывает пути для некоторых изображений.


person Ali Ahmed    schedule 03.07.2021    source источник
comment
Если вы используете хостинг, вы можете загрузить изображения в File Manager или куда-то еще (например, в cPanel) и сохранить URL-адрес в БД.   -  person David Lee    schedule 03.07.2021
comment
Я не пользуюсь услугами хостинга. Все, что я храню, находится в локальной базе данных sqlite.   -  person Ali Ahmed    schedule 03.07.2021
comment
Вы должны сохранить uri.toString() в базу данных. Не uri.getPath().   -  person blackapps    schedule 03.07.2021
comment
И используйте ACTION_OPEN_DOCUMENT вместо ACTION_GET_CONTENT, чтобы вы могли получить постоянное разрешение uri на uri.toString().   -  person blackapps    schedule 03.07.2021


Ответы (1)


Поскольку @blackapps предложил использовать ACTION_OPEN_DOCUMENT, я нашел решение. Сначала я получил Uri dataString от intent.getDataString(), затем проанализировал его, чтобы вызвать takePersistableUriPermission(). Теперь я могу получить Uri из базы данных и вызвать setImageUri(uri), чтобы получить изображение.

photoActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent intent = result.getData();
                    if (intent.getData() == null) {
                        Log.d("AddTrip", "null data from image");
                    }
                        image = intent.getDataString();
                        Uri uri = Uri.parse(image);
                         context.getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

                        imageName.setText(image);
                }
            }
        });

    }

 private void uploadPhotoClicked() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.setType("image/*");
        photoActivityResultLauncher.launch(intent);
    }
person Ali Ahmed    schedule 03.07.2021
comment
Лучше: Uri uri = намерение.getData(); - person blackapps; 03.07.2021