Create and Share a File (Also a mysterious error)

Posted by Kirk on Stack Overflow See other posts from Stack Overflow or by Kirk
Published on 2012-08-29T03:11:04Z Indexed on 2012/08/30 3:38 UTC
Read the original article Hit count: 222

My goal is to create a XML file and then send it through the share Intent.

I'm able to create a XML file using this code

FileOutputStream outputStream = context.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
PrintStream printStream = new PrintStream(outputStream);
String xml = this.writeXml(); // get XML here
printStream.println(xml);
printStream.close();

I'm stuck trying to retrieve a Uri to the output file in order to share it. I first tried to access the file by converting the file to a Uri

File outFile = context.getFileStreamPath(fileName);
return Uri.fromFile(outFile);

This returns file:///data/data/com.my.package/files/myfile.xml but I cannot appear to attach this to an email, upload, etc.

If I manually check the file length, it's proper and shows there is a reasonable file size.

Next I created a content provider and tried to reference the file and it isn't a valid handle to the file. The ContentProvider doesn't ever seem to be called a any point.

Uri uri = Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/" + fileName);
return uri;

This returns content://com.my.package.provider/myfile.xml but I check the file and it's zero length.

How do I access files properly? Do I need to create the file with the content provider? If so, how?

Update

Here is the code I'm using to share. If I select Gmail, it does show as an attachment but when I send it gives an error Couldn't show attachment and the email that arrives has no attachment.

public void onClick(View view) {
    Log.d(TAG, "onClick " + view.getId());

    switch (view.getId()) {
        case R.id.share_cancel:
            setResult(RESULT_CANCELED, getIntent());
            finish();
            break;

        case R.id.share_share:

            MyXml xml = new MyXml();
            Uri uri;
            try {
                uri = xml.writeXmlToFile(getApplicationContext(), "myfile.xml");
                //uri is  "file:///data/data/com.my.package/files/myfile.xml"
                Log.d(TAG, "Share URI: " + uri.toString() + " path: " + uri.getPath());

                File f = new File(uri.getPath());
                Log.d(TAG, "File length: " + f.length());
                // shows a valid file size

                Intent shareIntent = new Intent();
                shareIntent.setAction(Intent.ACTION_SEND);
                shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
                shareIntent.setType("text/plain");
                startActivity(Intent.createChooser(shareIntent, "Share"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            break;
    }
}

I noticed that there is an Exception thrown here from inside createChooser(...), but I can't figure out why it's thrown.

E/ActivityThread(572): Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver com.android.internal.app.ResolverActivity$1@4148d658 that was originally registered here. Are you missing a call to unregisterReceiver()?

I've researched this error and can't find anything obvious. Both of these links suggest that I need to unregister a receiver.

I have a receiver setup, but it's for an AlarmManager that is set elsewhere and doesn't require the app to register / unregister.

Code for openFile(...)

In case it's needed, here is the content provider I've created.

public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    String fileLocation = getContext().getCacheDir() + "/" + uri.getLastPathSegment();

    ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);
    return pfd;
}

© Stack Overflow or respective owner

Related posts about android

Related posts about android-contentprovider