3

I create a bunch of text files which I created like in the code below. I saved those files in internal storage. My goal now is to display it in ListView and if user gonna click on an item it should open or send the file via intent (e.g. email).

static void createFile (Context context) {
    mTimeStamp = String.valueOf(System.currentTimeMillis()/1000);
    try {
        String fileName = "File_" + mTimeStamp + ".txt";
        mContext = context;
        mOutputStreamWriter = new 
        OutputStreamWriter(context.openFileOutput(fileName ,Context.MODE_PRIVATE));
        String path = mContext.getFilesDir().getAbsolutePath();
        Toast.makeText(mContext, "Creating file: " +  path, 
        Toast.LENGTH_LONG).show();

    } catch (FileNotFoundException e) {
        Log.e(TAG,"Error with creating file writer...");
        e.printStackTrace();
    }
}

static void writeToFileData(String dataToSave) {
    try {
        Toast.makeText(mContext, "Saving data to file: " +  dataToSave, Toast.LENGTH_SHORT).show();
        mOutputStreamWriter.write(dataToSave);
    } catch (IOException e) {
        Log.e(TAG,"Error with writing to file...");
        e.printStackTrace();
    }
}

static void closeFileWriter() {
    try {
        Toast.makeText(mContext, "Closing file... ", Toast.LENGTH_SHORT).show();
        mOutputStreamWriter.close();

    } catch (IOException e) {
        Log.e(TAG,"Error with closing file writer...");
        e.printStackTrace();
    }
}

Then I list my all files like this (not in ListView but only for test now):

static void testDispFiles (Context context) {
    mContext = context;
    String path = mContext.getFilesDir().getAbsolutePath();
    Log.v(TAG, "testDisp path: " + path);
    File dirFile = new File(path);

    File[] files = dirFile.listFiles();
    Log.v(TAG, "testDisp length: " + files.length);

    for (File f: files) {
        Log.v(TAG, "testDisp file: " + f.getName());
    }
}

And now I want to share one of the files by sending it through e.g. email. How to send the text file from internal storage via intent?

//Edit:

I create an Intent which returning the toast "You can't add this file" message from Gmail app.

String path = mContext.getFilesDir().getAbsolutePath();
File f = new File(path);
File[] files = f.listFiles();
Uri data = Uri.fromFile(files[0]);
Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_STREAM,data);
i.setType("plain/text");
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
i.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
startActivity(i);
chebad
  • 919
  • 1
  • 13
  • 29
  • You can use TinyDB to store String in the internal storage and then can get it: TinyDB.class [here](https://github.com/kcochibili/TinyDB--Android-Shared-Preferences-Turbo/blob/master/TinyDB.java) – Tarlan Ahad Dec 23 '17 at 19:50
  • Use `FileProvider`: https://developer.android.com/reference/android/support/v4/content/FileProvider.html – CommonsWare Dec 23 '17 at 20:13
  • @CommonsWare Could you help me with this? I never use the FileProvider. – chebad Dec 23 '17 at 20:16
  • 1
    I pointed you to documentation, and [here is some more](https://developer.android.com/training/secure-file-sharing/setup-sharing.html). [Here is a sample app](https://github.com/commonsguy/cw-omnibus/tree/v8.9/Camera/FileProvider) from [one of my books](https://commonsware.com/Android) that shows using `FileProvider` for `ACTION_IMAGE_CAPTURE` and `ACTION_VIEW`. If you have additional concerns about how to use `FileProvider`, and you cannot find existing materials on the topic, ask a separate Stack Overflow question with your specific problems. – CommonsWare Dec 23 '17 at 20:20
  • For Kotlin, you can try this: https://stackoverflow.com/a/62928442/2462531 – Shailendra Madda Jul 16 '20 at 06:09

2 Answers2

15

I found one of solution for this problem. How @CommonsWare suggested I used a FileProvider. I follow this example. But in provider_paths.xml I put this code, because I use a internal storage.

<Paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="files" path="."/>
</Paths>

Then in activity I send a file via intent like this:

       Uri path = FileProvider.getUriForFile(this,"same_authoritory_which_was_in_manifest", new File(FILE_TO_SAVE.getPath()));
       Intent i = new Intent(Intent.ACTION_SEND);
       i.putExtra(Intent.EXTRA_TEXT, "Test");
       i.putExtra(Intent.EXTRA_STREAM, path);
       i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
       i.setType("plain/*");
       startActivity(i);
chebad
  • 919
  • 1
  • 13
  • 29
1

You store your files using openFileOutput() which is indeed in internal private memory of your app. Like getFilesDir().

No other apps have access.

If you want to share the files then you have to serve them using a file provider.

For the rest sharing a file is a standard action.

You can find code all over the place.

greenapps
  • 11,154
  • 2
  • 16
  • 19
  • Could you help me with this one? Because I never use file providers and I don't know how to work with it. – chebad Dec 23 '17 at 19:56
  • Google for it. You can find code all over the place. – greenapps Dec 23 '17 at 19:56
  • You could just start with code for the share intent. Please post. Google for Intent.ACTION.SEND and Intent.EXTRA_STREAM. – greenapps Dec 23 '17 at 19:58
  • I tried to send it with this code: [my code](https://pastebin.com/3ZLywpaC). But when I choose a gmail app, I get a "You can't add this file". – chebad Dec 23 '17 at 20:09