Не удается прочитать изображение с помощью BitmapFactory.decodeFile - PullRequest
0 голосов
/ 25 февраля 2020

Размер растрового изображения составляет всего 49 КБ.

У меня есть разрешения в моем AndroidManifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Но следующий код возвращает null , он не может прочитать изображение из файла.

Im = BitmapFactory.decodeFile(file.absolutePath) // <== file: "/storage/emulated/0/Android/data/com.example.App1/files/MyImages/MyImg.png"

BitmapFactory.decodeFile возвращает значение NULL.

Я искал и пробовал предложения с помощью Filestream следующим образом:

try {
    val dest = File(fullPath, fileName)  // dest: "/storage/emulated/0/Android/data/com.example.App1/files/MyImages/MyImage.png"
    var fis: FileInputStream
    fis = FileInputStream(dest)      // <= Jumps to catch section from this line
    Img = BitmapFactory.decodeStream(fis)
}
catch (e: Exception) {
    Log.e("File could not be found", e.message)    
}
return Img 

Но, когда я отлаживаю, курсор переходит в раздел catch из строки fis = FileInputStream (dest). Это выдает эту ошибку:

e=java.io.FileNotFoundException (No such file or directory)

Когда я помещаю этот try-catch блок в оператор "if", например,

val file = File(fullPath, fileName)
if (file.exists()){
      // the above try-catch block is here
 }

тогда условие " file.exists () " равно НЕ true (но я вижу в устройстве, файл существует. Он находится в тот же путь, взятый с параметром " dest ", значение которого указано выше, как вы видите)

Я сохранил файл PNG с кодами на как сохранить растровое изображение в android галерее от Бао Лея. Эти коды приведены ниже:

/// @param folderName can be your app's name
    private fun saveImage(bitmap: Bitmap, context: Context, folderName: String) {
        if (android.os.Build.VERSION.SDK_INT >= 29) {
            val values = contentValues()
            values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + folderName)
            values.put(MediaStore.Images.Media.IS_PENDING, true)
            // RELATIVE_PATH and IS_PENDING are introduced in API 29.

            val uri: Uri? = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
            if (uri != null) {
                saveImageToStream(bitmap, context.contentResolver.openOutputStream(uri))
                values.put(MediaStore.Images.Media.IS_PENDING, false)
                context.contentResolver.update(uri, values, null, null)
            }
        } else {
            val directory = File(Environment.getExternalStorageDirectory().toString() + separator + folderName)
            // getExternalStorageDirectory is deprecated in API 29

            if (!directory.exists()) {
                directory.mkdirs()
            }
            val fileName = System.currentTimeMillis().toString() + ".png"
            val file = File(directory, fileName)
            saveImageToStream(bitmap, FileOutputStream(file))
            if (file.absolutePath != null) {
                val values = contentValues()
                values.put(MediaStore.Images.Media.RELATIVE_PATH, folderName)
                // .DATA is deprecated in API 29
                context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
            }
        }
    }

    private fun contentValues() : ContentValues {
        val values = ContentValues()
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/png")
        values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
        return values
    }

    private fun saveImageToStream(bitmap: Bitmap, outputStream: OutputStream?) {
        if (outputStream != null) {
            try {
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
                outputStream.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

Оператор if; if (android .os.Build.VERSION.SDK_INT> = 29) равно , а не true. Поэтому работает только оставшаяся секция else . В этом разделе else я удалил этот код;

    if (file.absolutePath != null) {
        val values = contentValues()
        values.put(MediaStore.Images.Media.DATA, file.absolutePath)
        // .DATA is deprecated in API 29
        context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
    }

Поскольку он вызывает эту ошибку:

Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=14668, uid=10271 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()

Итак, Функция saveImageToStream в приведенном выше коде сохраняет изображение.

Теперь проблема с чтением PNG составляет

 e=java.io.FileNotFoundException (No such file or directory)

, хотя PNG существует. Как решить эту проблему?

Код fis = FileInputStream (dest) находится в файле DidtodayActivity.kt. И этот файл активности определяется в файле манифеста как:

<activity android:name=".DidtodayActivity">
    <intent-filter>
        <action android:name="com.mystudio.otherlab.MainActivity" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name=".secondActivity" />
<activity android:name=".loginActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Есть ли проблема в файле манифеста?

Почему возникает ошибка (файл не найден), хотя путь правильный и файл PNG существует? Я надеюсь, что кто-то может помочь

1 Ответ

0 голосов
/ 25 февраля 2020

Что это выдает

try {
   // Img = BitmapFactory.decodeFile(file.absolutePath) //<= returns null

    val dest = File(fullPath, fileName)  // dest: "/storage/emulated/0/Android/data/com.example.App1/files/MyImages/MyImage.png"

    System.out.println("DEST IS: " + dest);  // <= Check this in Logcat

    var fis: FileInputStream
    fis = FileInputStream(dest)      // <= Jumps to catch section from this line
    Img = BitmapFactory.decodeStream(fis)
}
catch (e: Exception) {
    Log.e("File could be find", e.message)    
}

...