StorageException (No Content Providor) при попытке загрузить сжатое изображение в firebase - PullRequest
0 голосов
/ 29 сентября 2019

Я работаю над приложением для Android, которое управляет пациентами.В приложении есть возможность захвата изображения пациента с камеры - и это изображение загружается в облако базы данных.Я решил сжать изображения, прежде чем загружать их в Firebase.До сих пор все работало нормально, но по какой-то причине после сжатия изображения (следуя инструкциям здесь: http://voidcanvas.com/whatsapp-like-image-compression-in-android/) я получаю много ошибок ...

Изображение сжимается успешно, и когдая пытаюсь установить ImageView на Uri фотографии, это работает, но когда я использую glide, это не работает :( Кроме того, когда я пытаюсь загрузить изображение в хранилище Firebase позже, это дает мне No Content ProvidorОшибка.

Я думаю, что ошибка исходит из сгенерированного имени файла, в функции сжатия изображения - но я не знаю, что изменить, и что вызывает ошибку ...

Вкл.С другой стороны, если у кого-то есть более простой метод сжатия изображений, который использует URI изображения контента (который был передан из провайдера файла), я всегда буду в долгу!

Большое спасибо!

Призыв к сжатию захваченного изображения:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("request_code", String.valueOf(requestCode));
    if (requestCode == Constants.REQUEST_PATIENT_IMAGE_CAPTURE) {
        if (resultCode == RESULT_OK) {
            //Previously was just patientImage.setImageUri(newPatientImage)
            Uri tempImage = ImageHandler.compressImage(newPatientImage);
//           Glide.with(PatientCardActivity.getInstance())
//          .load(tempImage)
//          .fitCenter()
//          .error(R.drawable.no_image_icon)
//          .fallback(R.drawable.empty_user)
//          .into(patientImage);
            patientImage.setImageURI(tempImage);
            newPatientImage = tempImage;
            changedSuccess = true;
        }
        else newPatientImage = null;
    }

Как сгенерировать Uri для сжатого файла:

 protected static File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Constants.EXTERNAL_FILES_DIR;
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    return image;
}

 protected static Uri createImageUri() {
    Uri photoURI = Uri.parse("");
    File photoFile = null;
    try {
        photoFile = createImageFile();
    } catch (IOException ex) {
        photoFile.delete();
    }
    // Error occurred while creating the File
    // Continue only if the File was successfully created
    if (photoFile != null) {
        photoURI = Uri.fromFile(photoFile.getAbsoluteFile());
    }
    return photoURI;
}

Функция сжатия изображения:

public static Uri compressImage(Uri imageUri) {

    if (imageUri == null)
        return imageUri;

    Bitmap scaledBitmap = null;
    Bitmap bmp = null;

    BitmapFactory.Options options = new BitmapFactory.Options();
    ContentResolver cr = PatientCardActivity.getInstance().getContentResolver();
    try {
        InputStream is = cr.openInputStream(imageUri);

        //      by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
        //      you try the use the bitmap here, you will get null.
        options.inJustDecodeBounds = true;
        bmp = BitmapFactory.decodeStream(is, null, options);
        if (is != null) {
            is.close();
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }

    int actualHeight = options.outHeight;
    int actualWidth = options.outWidth;


    float maxHeight = 816.0f;
    float maxWidth = 612.0f;
    float imgRatio = actualWidth / actualHeight;
    float maxRatio = maxWidth / maxHeight;


    if (actualHeight > maxHeight || actualWidth > maxWidth) {
        if (imgRatio < maxRatio) {
            imgRatio = maxHeight / actualHeight;
            actualWidth = (int) (imgRatio * actualWidth);
            actualHeight = (int) maxHeight;
        } else if (imgRatio > maxRatio) {
            imgRatio = maxWidth / actualWidth;
            actualHeight = (int) (imgRatio * actualHeight);
            actualWidth = (int) maxWidth;
        } else {
            actualHeight = (int) maxHeight;
            actualWidth = (int) maxWidth;

        }
    }

    options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);

    options.inJustDecodeBounds = false;

    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inTempStorage = new byte[16 * 1024];

    try {
        InputStream is = cr.openInputStream(imageUri);
        bmp = BitmapFactory.decodeStream(is, null, options);
    } catch (Exception e) {
        e.printStackTrace();

    }
    try {
        scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
    } catch (OutOfMemoryError exception) {
        exception.printStackTrace();
    }

    float ratioX = actualWidth / (float) options.outWidth;
    float ratioY = actualHeight / (float) options.outHeight;
    float middleX = actualWidth / 2.0f;
    float middleY = actualHeight / 2.0f;

    Matrix scaleMatrix = new Matrix();
    scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

    Canvas canvas = new Canvas(scaledBitmap);
    canvas.setMatrix(scaleMatrix);
    canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new 
    Paint(Paint.FILTER_BITMAP_FLAG));



    FileOutputStream out = null;
    String filename = createImageUri().getPath();
    try {
        out = new FileOutputStream(filename);

//          write the compressed bitmap at the destination specified by filename.
        scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    return Uri.parse(filename);

}

Функция, котораязагружает изображение в базу:

protected static String uploadImageToStorage(String imagesFolderName, String uid, Uri imageUri){
    String storagePath = imagesFolderName + Constants.DATABASE_SEP_CHAR +
            createStorageImageName(uid, imageUri);
    StorageReference imageRef = storageRef.child(storagePath);
    UploadTask uploadTask = imageRef.putFile(imageUri);
    final Boolean [] completedSuccessfully = {true};
    // Register observers to listen for when the download is done or if it fails
     uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            //TODO Handle unsuccessful uploads
            completedSuccessfully[0] = false;
            Log.d("UnSuccessfull upload", exception.toString());
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
            // ...
        }
    });
     if (completedSuccessfully[0])
         return storagePath;
     else
         return "";
}

Ошибка, которую я получаю:

E/UploadTask: could not locate file for 

uploading:/storage/emulated/0/Android/data/com.example.myapp/files/Pictures/JPEG_20190929_123827_6249547593857539634.jpg
E/StorageException: StorageException has occurred.
    An unknown error occurred, please check the HTTP result code and inner exception for server response.
     Code: -13000 HttpResult: 0
E/StorageException: No content provider: /storage/emulated/0/Android/data/com.example.myapp/files/Pictures/JPEG_20190929_123827_6249547593857539634.jpg
    java.io.FileNotFoundException: No content provider: /storage/emulated/0/Android/data/com.example.myapp/files/Pictures/JPEG_20190929_123827_6249547593857539634.jpg
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1451)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1302)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1022)
        at com.google.firebase.storage.UploadTask.<init>(com.google.firebase:firebase-storage@@19.0.1:131)
        at com.google.firebase.storage.StorageReference.putFile(com.google.firebase:firebase-storage@@19.0.1:251)
        at com.example.myapp.UploadDownload.uploadImageToStorage(UploadDownload.java:136)
        at com.example.myapp.UploadDownload.uploadPatientImage(UploadDownload.java:215)
        at com.example.myapp.UploadDownload.updatePatient(UploadDownload.java:184)
        at com.example.myapp.PatientCardActivity.addInfo(PatientCardActivity.java:476)
        at com.example.myapp.PatientCardActivity.addInfo(PatientCardActivity.java:410)
        at com.example.myapp.PatientCardActivity.access$1800(PatientCardActivity.java:58)
        at com.example.myapp.PatientCardActivity$8.onClick(PatientCardActivity.java:285)
        at android.view.View.performClick(View.java:7352)
        at android.view.View.performClickInternal(View.java:7318)
        at android.view.View.access$3200(View.java:846)
        at android.view.View$PerformClick.run(View.java:27801)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7045)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
E/StorageException: StorageException has occurred.
...