2

I created my own file extension (.oli). If the user clicks on a file with this extension my app starts and loads the included data. This works like expected. The problem is I would like to give the user of my app the opportunity to share a file (Example: filename.oli).

I implemented this so far:

public void shareFile(){
        File file = getShareableFile(); //Creates a .oli-file
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        Uri uri = Uri.fromFile(file);
        shareIntent.setType("*/*"); //Maybe the problem
        shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
        shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, name);
        startActivity(Intent.createChooser(shareIntent, getString(R.string.shareDatei)));
}

The problem is, the list of apps that think they could handle sharing my file is very large because of shareIntent.setType("/"); Here are two cases that happen if you share with different apps:

If I choose an Email-app like Gmail to share my file it works how it should. The email includes the file as filename.oli . When I click on it my app gets started.

But If I choose for example the Quickmemo-app I get a message that this file can not be shared by this.

So all in all I just want to show apps in the chooserlist that can handle to share my file with the .oli extension . How do I do that? Thanks in advance!

XxGoliathusxX
  • 922
  • 13
  • 34

1 Answers1

0

The setType() intent method actually uses MIME types to filter apps according to the docs. So, you'll only be able to filter the apps available based on the following filters:

1.Text

sendIntent.setType("text/plain");

2. Binary

shareIntent.setType("image/jpeg");

3. Multiple content items

shareIntent.setType("image/*");

EDIT

Here's what I would likely do, I would know which apps I want to be able to share the file, like gmail since you know that works, and I would be selective about which apps are in the list. The following code comes from the answer in this SO link: How to filter specific apps for ACTION_SEND intent (and set a different text for each app)

public void onShareClick(View v) {
    Resources resources = getResources();

    Intent emailIntent = new Intent();
    emailIntent.setAction(Intent.ACTION_SEND);
    // Native email client doesn't currently support HTML, but it doesn't hurt to try in case they fix it
    emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(resources.getString(R.string.share_email_native)));
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.share_email_subject));
    emailIntent.setType("message/rfc822");

    PackageManager pm = getPackageManager();
    Intent sendIntent = new Intent(Intent.ACTION_SEND);     
    sendIntent.setType("text/plain");


    Intent openInChooser = Intent.createChooser(emailIntent, resources.getString(R.string.share_chooser_text));

    List<ResolveInfo> resInfo = pm.queryIntentActivities(sendIntent, 0);
    List<LabeledIntent> intentList = new ArrayList<LabeledIntent>();        
    for (int i = 0; i < resInfo.size(); i++) {
        // Extract the label, append it, and repackage it in a LabeledIntent
        ResolveInfo ri = resInfo.get(i);
        String packageName = ri.activityInfo.packageName;
        if(packageName.contains("android.email")) {
            emailIntent.setPackage(packageName);
        } else if(packageName.contains("twitter") || packageName.contains("facebook") || packageName.contains("mms") || packageName.contains("android.gm")) {
            Intent intent = new Intent();
            intent.setComponent(new ComponentName(packageName, ri.activityInfo.name));
            intent.setAction(Intent.ACTION_SEND);
            intent.setType("text/plain");
            if(packageName.contains("twitter")) {
                intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_twitter));
            } else if(packageName.contains("facebook")) {
                // Warning: Facebook IGNORES our text. They say "These fields are intended for users to express themselves. Pre-filling these fields erodes the authenticity of the user voice."
                // One workaround is to use the Facebook SDK to post, but that doesn't allow the user to choose how they want to share. We can also make a custom landing page, and the link
                // will show the <meta content ="..."> text from that page with our link in Facebook.
                intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_facebook));
            } else if(packageName.contains("mms")) {
                intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_sms));
            } else if(packageName.contains("android.gm")) { // If Gmail shows up twice, try removing this else-if clause and the reference to "android.gm" above
                intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(resources.getString(R.string.share_email_gmail)));
                intent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.share_email_subject));               
                intent.setType("message/rfc822");
            }

            intentList.add(new LabeledIntent(intent, packageName, ri.loadLabel(pm), ri.icon));
        }
    }

    // convert intentList to array
    LabeledIntent[] extraIntents = intentList.toArray( new LabeledIntent[ intentList.size() ]);

    openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
    startActivity(openInChooser);       
}
Community
  • 1
  • 1
user3331142
  • 1,222
  • 1
  • 11
  • 22
  • Ok I understand. Whats the best way to deal with that? – XxGoliathusxX Jun 22 '16 at 17:16
  • Your best bet without having other apps include a custom ContentProvider filter just for your extension, would probably be to work with the chooser as you have it or I might use the text/plain type, but I'm unaware of the format of your data. – user3331142 Jun 22 '16 at 17:25
  • Its simply xml code but with .oli extension. Because if you click on the file my app gets started with the xml code through an intent filter. This works! But how to share the file is the problem. – XxGoliathusxX Jun 22 '16 at 17:27
  • That's pretty clever! I like. I edited my answer with something that I think will work. You custom select which apps are included in the chooser. That way, you can select only the apps that will work to share the extension. – user3331142 Jun 22 '16 at 17:34
  • Ok the list of choosers contains: Email-apps, File explorer, google drive. This looks really good! How to add the file now and what is the emailIntent for because it does not get used??? – XxGoliathusxX Jun 22 '16 at 17:51
  • It's used as the base for the `openInChooser` intent. `Intent openInChooser = Intent.createChooser(emailIntent, resources.getString(R.string.share_chooser_text));` It will automatically include any email apps on the device. You should be able to add your file just like before with `shareIntent.putExtra(Intent.EXTRA_STREAM, uri);` – user3331142 Jun 22 '16 at 18:06
  • What is this line for?: emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(getString(R.string.share_email_native))); – XxGoliathusxX Jun 22 '16 at 18:11
  • EXTRA_TEXT puts text into the body of the email. I imagine that the R.string.share_email_native is the "Sent from my [phone_type]" – user3331142 Jun 22 '16 at 18:18
  • I replaced that with a normal string and not with html. Is that ok too? intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.shareEmailText)); – XxGoliathusxX Jun 22 '16 at 18:20
  • I haven't used it, but from what I've read, that should be fine – user3331142 Jun 22 '16 at 18:21
  • For MMS this does not work! else if(packageName.contains("mms")) { intent.putExtra(Intent.EXTRA_TEXT, "teile mms"); intent.putExtra(Intent.EXTRA_SUBJECT, trainingsname + " - " + getString(R.string.datei)); intent.setType("message/rfc822"); intent.putExtra(Intent.EXTRA_STREAM, uri); } It says: Cant add this file! – XxGoliathusxX Jun 22 '16 at 18:27
  • That probably means mms doesn't allow unknown filetypes. We should move this discussion to chat for specific smaller issues. I believe this question is answered – user3331142 Jun 22 '16 at 18:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/115341/discussion-between-user3331142-and-xxgoliathusxx). – user3331142 Jun 22 '16 at 18:30