Search code examples
androidandroid-contentproviderinternal-storageshare-intentandroid-internal-storage

Android Intent.ACTION_SEND from Internal Storage with Content Provider


I am saving a file on internal storage. It is just a .txt file with some information about objects:

    FileOutputStream outputStream;
    String filename = "file.txt";

    File cacheDir = context.getCacheDir();
    File outFile = new File(cacheDir, filename);
    outputStream = new FileOutputStream(outFile.getAbsolutePath());
    outputStream.write(myString.getBytes());
    outputStream.flush();
    outputStream.close();

Then I am creating a "shareIntent" to share this file:

    Uri notificationUri = Uri.parse("content://com.package.example/file.txt");
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, notificationUri);
    shareIntent.setType("text/plain");
    context.startActivity(Intent.createChooser(shareIntent, context.getResources().getText(R.string.chooser)));

The chosen app now needs access to the private file so I created a Content provider. I just changed the openFile method:

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    File privateFile = new File(getContext().getCacheDir(), uri.getPath());
    return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
}

The manifest:

<provider
        android:name=".ShareContentProvider"
        android:authorities="com.package.example"
        android:grantUriPermissions="true"
        android:exported="true">
    </provider>

When opening the Mail App to share the file it says, that it could not attach the file because it only has 0 Bytes. Sharing it via Bluetooth also failed. But I can read out the privateFile in the Content Provider, so it exists and it has content. What is the problem?


Solution

  • Thanks for pskink. FileProvider worked perfectly:

    Gradle dependency:

    compile 'com.android.support:support-v4:25.0.0'

    Manifest:

    <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.package.example"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    

    file_paths.xml in XML folder:

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

    Sharing Intent:

        File file = new File(context.getCacheDir(), filename);
    
        Uri contentUri = FileProvider.getUriForFile(context, "com.package.example", file);
    
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
        shareIntent.setType("text/plain");
        context.startActivity(Intent.createChooser(shareIntent, context.getResources().getText(R.string.chooser)));