Android Share custom file

2019-02-15 12:18发布

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!

1条回答
Ridiculous、
2楼-- · 2019-02-15 12:48

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);       
}
查看更多
登录 后发表回答