5

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?

L3n95
  • 1,505
  • 3
  • 25
  • 49
  • is `query()` method called in your custom `ContentProvider`? – pskink Nov 20 '16 at 11:29
  • Yes is called 3 times before openFile. First argument is always: content://com.package.example/file.txt – L3n95 Nov 20 '16 at 11:37
  • 2
    and the projection / columns are: _display_name and _size ? BTW why not to use `android.support.v4.content.FileProvider`? – pskink Nov 20 '16 at 11:38
  • Yes they are in the second argument. I only found ContentProvider when searching this. But I'll take a look at FileProvider now too. – L3n95 Nov 20 '16 at 11:40
  • 1
    but if you still want your custom `ContentProvider` see `android.provider.OpenableColumns` – pskink Nov 20 '16 at 11:41
  • Try to get it running with `ContentProvider` as it is much more flexible then `FilePrivider`. – greenapps Nov 20 '16 at 11:47
  • `they are in the second argument. ` And.. do you provide the requested info? – greenapps Nov 20 '16 at 11:49
  • just use a `MatrixCursor` if you dont know what to return from `query` method – pskink Nov 20 '16 at 11:57
  • What do you mean with flexible? All I need is the access to the private file. – L3n95 Nov 20 '16 at 11:57
  • `flexible? All I need is the access to the private file`. Maybe today only. But later... With FileProvider you only can serve files from predetermined directories. Predetermind by Google. Not by you. – greenapps Nov 20 '16 at 13:12
  • `opening the Mail App to share the file`. Which one? There mostly are more on a system. Try others too. – greenapps Nov 20 '16 at 13:14
  • Okay then I try that out again. I only have one on the device. But sending with bluetooth failed too, saying it cannot find the file. – L3n95 Nov 20 '16 at 13:23
  • To encourange you: your code looks ok. – greenapps Nov 20 '16 at 13:45

1 Answers1

7

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)));
L3n95
  • 1,505
  • 3
  • 25
  • 49