Почему он отправляет sh при отправке растрового изображения - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь поделиться изображением, отправив растровое изображение. Решение, которое я нашел, работает на эмуляторе для Android 10.0, но не на Android 7.0 (ни на моем LG V20 с Android 9), где оно падает.

Вот мой текущий код. Любая идея, как избежать крэ sh? Заранее благодарим за вашу помощь.

            picIV.buildDrawingCache();
            Bitmap bitmap = picIV.getDrawingCache();

            String path = MediaStore.Images.Media.insertImage(getContentResolver(),
            bitmap, "Challengers", null);

            Uri uri = Uri.parse(path);

            Intent share = new Intent(Intent.ACTION_SEND);
            share.setType("image/*");
            share.putExtra(Intent.EXTRA_STREAM, uri);
            //share.putExtra(Intent.EXTRA_TEXT, "I found something cool!");
            startActivity(Intent.createChooser(share, "Share Your Design!"));

Кажется, что cra sh происходит при запуске этой строки

            Uri uri = Uri.parse(path);

Ответы [ 4 ]

0 голосов
/ 11 апреля 2020

Наконец-то нашел проблему. Это были разрешения. Несмотря на то, что я поместил разрешения в Манифест. xml также необходимо добавить пару строк в onCreate.

    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
    onRequestPermissionsResult(requestCode,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},grantResults);

Спасибо всем за ваши ответы, очень полезно!

0 голосов
/ 05 апреля 2020

Нашел другой метод, который работал на Android 7, но не на Android 10. Итак, нашел способ заставить их работать вместе.

                Uri uri;
                String path = MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "Challengers", null);

                if (path!=null) {
                    uri = Uri.parse(path);
                }else{
                    uri = null;
                    String string="" ;
                    try {
                        File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "to-share.png");
                        FileOutputStream stream = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
                        stream.close();
                        uri = Uri.fromFile(file);
                    } catch (IOException e) {
                        Log.d(string, "IOException while trying to write file for sharing: " + e.getMessage());
                    }
                }

                Intent share = new Intent(Intent.ACTION_SEND);
                share.setType("image/*");
                share.putExtra(Intent.EXTRA_STREAM, uri);
                //share.putExtra(Intent.EXTRA_TEXT, "I found something cool!");
                startActivity(Intent.createChooser(share, "Share Your Design!"));
0 голосов
/ 05 апреля 2020

Это должно работать для каждого API - Ответ в Koltin

  1. Создать Bitmap С View

    fun createBitmapFromView(view: View): Bitmap {
            val bitmap = Bitmap.createBitmap(view.measuredWidth, 
            view.measuredHeight, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            view.layout(view.left, view.top, view.right, view.bottom)
            view.draw(canvas)
            return bitmap
        }
    
  2. Создать File для сохранения Bitmap

    fun getFileFromBitmap(bitmap: Bitmap): File? {
    val parentDirectory = File(externalCacheDir, "reminder_images")  //image file is stored in external cache directory/reminder_images
    if (!parentDirectory.exists()) {
        parentDirectory.mkdirs()
    }
    val externalCacheFile = File(parentDirectory, "name_of_your_file.png")
    return writeBitmapToFile(externalCacheFile, bitmap)
    

    }

  3. Записать Bitmap в File, используя Stream

    fun writeBitmapToFile(externalCacheFile: File, bitmap: Bitmap): File? {
        return try {
            val fOut = FileOutputStream(externalCacheFile)
            bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut)
            fOut.flush()
            fOut.close()
            externalCacheFile
        } catch (e: Exception) {
            null
        }
    }
    
  4. Создать FileProvider в манифесте

             <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="com.your_package_name.FileProvider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_paths" />
            </provider>
    
  5. 5.Создать файл ресурса provider_paths.xml

     <?xml version="1.0" encoding="utf-8"?>
      <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="external_files" path="."/>
      </paths>
    
  6. Получить Uri Из File с использованием FileProvider

    val uri = FileProvider.getUriForFile(context,"com.your_package_name.FileProvider", externalCacheFile)
    

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

В моем решении файл изображения хранится во внешних каталогах app-Speci c. Этот файл изображения будет удален, если ваше приложение будет удалено. Если вам нужно другое поведение, проверьте data-storage .

0 голосов
/ 05 апреля 2020

Может быть, ваш path равен null? Вы отлаживали его?

Из источника метода Uri.parse(...) Я заметил, что он возвращает ошибку, если в качестве аргумента принимает null, а MediaStore.Images.Media.insertImage(...) возвращает null ", если изображение не удалось храниться по любой причине ".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...