Выбор изображений из любой галереи внезапно перестал работать

#android #android-studio

#Android #android-studio

Вопрос:

мое приложение внезапно начало сбоить после попытки выбрать изображение из любой галереи. Он работает с этим же кодом в течение очень долгого времени. Недавно я подготовил его для Android 11, и после того, как я закончил редактировать код, он все еще работал. Сегодня он решил выбросить это исключение:

 E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: 
/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20200915-WA0003.jpg: open failed: EACCES (Permission denied)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.file.to.text, PID: 6149
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/-1/1/content://media/external/images/media/63620/ORIGINAL/NONE/image/jpeg/2126822588 flg=0x1 clip={text/uri-list U:content://com.google.android.apps.photos.contentprovider/-1/1/content://media/external/images/media/63620/ORIGINAL/NONE/image/jpeg/2126822588} }} to activity {*mypackagename*/*mypackagename*.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4846)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4887)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7403)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
        at com.file.to.text.MainActivity.getBase64String(MainActivity.kt:171)
        at com.file.to.text.MainActivity.onActivityResult(MainActivity.kt:138)
        at android.app.Activity.dispatchActivityResult(Activity.java:8119)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4839)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4887) 
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7403) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
  

Я не знаю, что является причиной этого, разрешения на чтение из внешнего хранилища и запись во внешнее хранилище разрешены, и это исключение возникает с каждой галереей.

Я тестирую на устройстве со стандартным Android 10.

Я использовал этот код в своем приложении для выбора галерей изображений:

 fun pickimage(view: View) {
    //val getIntent = Intent(Intent.ACTION_GET_CONTENT)
    //getIntent.type = "image/*"
    val pickIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    pickIntent.type = "image/*"
    //val chooserIntent = Intent.createChooser(getIntent, "Select Image")
    //chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(pickIntent))
    startActivityForResult(pickIntent, PICK_IMAGE)
    pic.isEnabled = false
}
  

Результат onActivityResult():

 public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != RESULT_CANCELED amp;amp; resultCode == RESULT_OK) {
            if (requestCode == PICK_IMAGE) {
                val selectedImage = data!!.data
                val picturePath = getPath(applicationContext, selectedImage)
                val encoded = getBase64String(picturePath, press) //press - some integer
            }
        }
}
  

Строка getBase64String():

 private fun getBase64String(path: String, press: Int): String {
        val bitmap = BitmapFactory.decodeFile(path)
        val byteArrayOutputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, press, byteArrayOutputStream)
        val byteArray = byteArrayOutputStream.toByteArray()
        return Base64.encodeToString(byteArray, Base64.DEFAULT)
}
  

Я был бы рад любой помощи.

Комментарии:

1. Выбросьте эту функцию getPath(). Вы можете использовать полученный uri напрямую для открытия inputstream и использовать поток в decodeStream() вместо этого. Тогда вы тоже будете готовы к Android 11.

2. @blackapps Большое вам спасибо, работает отлично. У меня есть небольшой вопрос, я использую функцию getPath(), чтобы также получить размер изображений и соответственно установить целое число «press», как я могу получить размер изображения без этой функции?

Ответ №1:

 Uri uri = data.getData();   

String projection [] = {

          MediaStore.Images.Media.DATA
        , MediaStore.Images.Media.DISPLAY_NAME
        , MediaStore.Images.Media.SIZE};
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);

if ( cursor==null)
{
    Toast.makeText(context, "cursor==nullnncould not query content resolver fornn"   uri.toString(), Toast.LENGTH_LONG).show();
    
    return;
}

cursor.moveToFirst();
String data = cursor.getString(0);
String displayName = cursor.getString(1);
String size = cursor.getString(2);

Toast.makeText(context, "query() oknn"   uri.toString()
              "nnDISPLAY_NAME: "   displayName
              "nDATA: "   data
              "nSIZE: "   size
            , Toast.LENGTH_LONG).show();
cursor.close();