My app needs to store an image on SD card to share on Facebook News Feed

51 Views Asked by At

I am trying to share an image through implicit intent. The image is shared successfully through Messenger and Twitter but fails on Facebook News Feed, Viber and Email. I read somewhere that I need to save the image to the external or internal SD card first before sharing. I am a little lost on 1) how to save the image to the SD card and 2) how to point to the new image location on the SD card in order to share it. Currently my code for sharing the image looks like this:

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:"));
            }
        });

And my xml is:

<?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>

If you have any pointers or know of any relevant tutorials I would appreciate it.

1

There are 1 best solutions below

0
Maz On

OK I finally got it to work but it requires a number of things.

First the following needs to be added to the AndroidManifest.xml file:

<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>

Then I had to create a folder named xml under res. Then I created a file called file_paths.xml inside that folder. The file contains the following:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="." />
</paths>

Finally my share method ended up looking like this:

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:"));
            }
        });

Note:

When I try to share the image in more than one place I get a warning saying my application keeps stopping and asking me whether I want to report the app (which I don't at present) though it still allows me to continue sharing the image. I am not sure what is causing this. If anyone has an idea please let me know.