Моему приложению необходимо сохранить изображение на SD-карте, чтобы поделиться им в новостной ленте Facebook.

Я пытаюсь поделиться изображением через неявное намерение. Изображение успешно передается через Messenger и Twitter, но не получается в ленте новостей Facebook, Viber и электронной почте. Я где-то читал, что перед отправкой нужно сохранить изображение на внешнюю или внутреннюю SD-карту. Я немного не понимаю, 1) как сохранить изображение на SD-карту и 2) как указать новое местоположение изображения на SD-карте, чтобы поделиться им. В настоящее время мой код для обмена изображением выглядит так:

Button share =  findViewById(R.id.sharetoapps);
        share.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Uri uri = Uri.parse("android.resource://com.testing.mypic/drawable/bad_day");
                intent = new Intent();
                intent.setAction(Intent.ACTION_SEND);
                intent.putExtra(Intent.EXTRA_STREAM,uri);
                intent.setType("image/png");

                startActivity(Intent.createChooser(intent, "share to:"));
            }
        });

И мой xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <Button
        android:id="@+id/sharetoapps"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="share" />



</LinearLayout>

Если у вас есть какие-либо указатели или вы знаете какие-либо соответствующие учебные пособия, я был бы признателен.


person Maz    schedule 08.06.2020    source источник
comment
EXTRA_STREAM не должен иметь Uri со схемой android.resource. Предполагается наличие content схемы. Скопируйте свой ресурс в файл (например, в getCacheDir()), затем используйте FileProvider и его метод getUriForFile(), чтобы получить доступ к content Uri. Не забудьте также добавить FLAG_GRANT_READ_URI_PERMISSION к Intent. Подробнее об обмене контентом в Android см. в документации.   -  person CommonsWare    schedule 08.06.2020
comment
Итак, я понял, что я не должен использовать изображения из папки с возможностью рисования для публикации в социальных сетях, а вместо этого должен использовать прямой файл. Боюсь, я не знаком с остальными терминами, которые вы упомянули, мне придется прочитать все это. Спасибо!   -  person Maz    schedule 08.06.2020
comment
@CommonsWare Я прочитал 15 различных решений, имеющих отношение к моей проблеме, но ничто из того, что я пробовал, не сработало. Я борюсь с шагом сохранения файла, чтобы поделиться им. Я должен был указать, что у меня есть база данных SQLite с именами файлов. Имя файла генерируется случайным образом и используется для захвата соответствующего изображения, которое затем отображается на экране. Я не понял, как сохранить файл на внешнюю SD-карту, но я могу запутаться, потому что я не могу жестко запрограммировать ресурс для рисования, чтобы сохранить его локально. У вас есть пример, с которым я мог бы работать?   -  person Maz    schedule 09.06.2020
comment
Лично я предпочитаю использовать assets/, а не res/drawable/ в подобных ситуациях. Это приложение Javaего аналог Kotlin) демонстрируют копирование PDF из assets/ в файл, а затем с помощью FileProvider и ACTION_VIEW отобразить его. Эти примеры описаны в этой книге.   -  person CommonsWare    schedule 09.06.2020
comment
Снова интересно. Я прочитаю все это и надеюсь, что пойму это. Спасибо! Интересно, лучше сначала прочитать это?   -  person Maz    schedule 09.06.2020
comment
Возможно нет. Эта книга (Руководство занятого кодера по разработке Android) была моей оригинальной книгой. Когда вышли Jetpack и Kotlin, я не мог разумно переписать эту книгу (все 4000+ страниц!). Книга, на которую я дал ссылку (Elements of Android Jetpack), заменяет вводные главы < i>Руководство занятого программиста по разработке для Android. Все мои книги Elements обновлены (как и Изучение Android, если вам больше нравятся практические руководства).   -  person CommonsWare    schedule 10.06.2020


Ответы (1)


ОК, я, наконец, заставил его работать, но для этого требуется ряд вещей.

Сначала необходимо добавить в файл AndroidManifest.xml следующее:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <!-- ressource file to create -->
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths">
    </meta-data>
</provider>

Затем мне пришлось создать папку с именем xml под res. Затем я создал файл с именем file_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>

В конце концов, мой метод доли выглядел так:

Button share =  findViewById(R.id.sharetoapps);
        share.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ActivityCompat.requestPermissions(QuotesActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);


                boolean success=false;
                Bitmap image = BitmapFactory.decodeResource(getResources(), getResources().getIdentifier(msg,"drawable",getPackageName()));
                final String TAG = QuotesActivity.class.getSimpleName();
                File path = Environment.getExternalStorageDirectory();
                File dir = new File(path + "/newAppFolder/");
                dir.mkdir();

                File file = new File(dir,"frs.png");

                OutputStream out = null;
                try{
                    out = new FileOutputStream(file);
                    image.compress(Bitmap.CompressFormat.PNG, 100, out);
                    success=true;
                    out.flush();
                    out.close();

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

                if (success) {
                    Toast.makeText(getApplicationContext(), "Image saved with success",
                            Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(),
                            "Error during image saving", Toast.LENGTH_LONG).show();
                }


                File f = new File(Environment.getExternalStorageDirectory() + File.separator+ "newAppFolder" + File.separator + "frs.png");
                Uri imageUri = FileProvider.getUriForFile(Objects.requireNonNull(getApplicationContext()),BuildConfig.APPLICATION_ID + ".provider", f);
                Intent shareit=new Intent(Intent.ACTION_SEND);
                shareit.setType("image/png");
                shareit.putExtra(Intent.EXTRA_STREAM, imageUri);
                startActivity(Intent.createChooser(shareit, "Share Image Via"));

                startActivity(Intent.createChooser(intent, "share to:"));
            }
        });

Примечание:

Когда я пытаюсь поделиться изображением более чем в одном месте, я получаю предупреждение о том, что мое приложение продолжает останавливаться и спрашивает меня, хочу ли я сообщить о приложении (чего я в настоящее время не делаю), хотя оно по-прежнему позволяет мне продолжать делиться изображением . Я не уверен, что вызывает это. Если у кого-то есть идея, пожалуйста, дайте мне знать.

person Maz    schedule 14.06.2020