Search code examples
androidcsvandroid-activityshare

How to send(share) csv file?


How to send(share) *csv file?

I have an Android app, which creates a csv file. And I want to share it: send to email, open at Excel and so on. I read tutorials:set up file sharing and sharing a file, but can not understand: is it for my option or not?

I declare a manifest:

  <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.nam1.name2.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
    </provider>

But what I should do next?

Can you tell me some simple code example (maybe git-repo) how to share file to another apps? Thank you!

EDIT: I write some new code to share files (look at FileProvider example)

public class ExportActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_export);

    Intent intentShareFile = new Intent(Intent.ACTION_SEND);
    intentShareFile.setAction(Intent.ACTION_SEND);        
    File imagePath = new File(getApplicationContext().getFilesDir(), "statistics");
    File newFile = new File(imagePath, "stat.csv");
    CSVHelper csvHelper = new CSVHelper(SharedData.AllPlayersColl);
    try {
        String path=imagePath.getAbsolutePath();
        csvHelper.SaveToCSV(path);
    } catch (IOException e) {
        e.printStackTrace();
    }

    Context context=getApplicationContext();
    Uri contentUri = getUriForFile(context, "com.name1.name2.fileprovider", newFile);

    List<ResolveInfo> resInfoList = getApplicationContext().getPackageManager()
            .queryIntentActivities(intentShareFile, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        getApplicationContext()
                .grantUriPermission(packageName, contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

    intentShareFile.setData(contentUri);
    intentShareFile.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    setResult(100, intentShareFile);
    startActivityForResult(intentShareFile,100);
  }
}

Where CSVHelper is:

 fun SaveToCSV(fileName: String?) {
    if (fileName == null)
        throw NullPointerException("fileName is null!")

    val writer = CSVWriter(FileWriter(fileName), '\t')

      // make csv file
       writer.writeNext(firstLine);
  }

And filepaths is:

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

But, I get a error:

          Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.SEND dat=content://com.name1.name2.fileprovider/stat/stat.csv flg=0x2 }

I want, that when I start an Intent a list of variants shows (at android device): email_app, excel_app and so on. So, I want to send noname intent.


Solution

  • FileProvider is a helper class designed to share files as content:// URIs instead of file:// URIs which have been deprecated for some time and forbidden since API level 24.

    You have declared the content provider, you need now to configure it, i.e. choose what file it can serve. This is done in the xml/filepath file that you have declared in the meta-data. You will then be able to generate shareable content URIs using FileProvider.getUriForFile().

    There is a complete wrap up

    Unfortunately not all application understand content:// URIs. If you need to share a file with a (very old or badly written) application which only handle file:// URIs you may still use them if you set the target level of your application to 23 or lower.