Android Поделиться пользовательским файлом

Я создал свое собственное расширение файла (.oli). Если пользователь нажимает на файл с этим расширением, мое приложение запускается и загружает включенные данные. Это работает как ожидалось. Проблема в том, что я хотел бы предоставить пользователю моего приложения возможность поделиться файлом (пример: filename.oli).

Я реализовал это до сих пор:

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)));
}

Проблема в том, что список приложений, которые считают, что могут обрабатывать общий доступ к моему файлу, очень велик из-за shareIntent.setType ("/"); Вот два случая, которые происходят, если вы делитесь с разными приложениями:

Если я выбираю почтовое приложение, такое как Gmail, чтобы поделиться своим файлом, оно работает так, как должно. Письмо включает в себя файл как filename.oli. Когда я нажимаю на него, мое приложение запускается.

Но если я выбираю, например, Quickmemo-приложение, я получаю сообщение, что этот файл не может быть передан этим.

В общем, я просто хочу показать приложения в списке выбора, которые могут обработать, чтобы поделиться моим файлом с расширением .oli. Как я могу это сделать? Заранее спасибо!

Ответы на вопрос(1)

Решение Вопроса

setType() Метод намерения на самом деле использует типы MIME для фильтрации приложений в соответствии сдокументы, Таким образом, вы сможете фильтровать только доступные приложения на основе следующих фильтров:

1.Text

sendIntent.setType("text/plain");

2. Бинарный

shareIntent.setType("image/jpeg");

3. Несколько элементов контента

shareIntent.setType("image/*");

РЕДАКТИРОВАТЬ

Вот что я, скорее всего, буду делать: я буду знать, какие приложения я хочу иметь для общего доступа к файлу, например, gmail, поскольку вы знаете, что это работает, и я бы выбрал, какие приложения есть в списке. Следующий код взят из ответа в этой ссылке SO:Как отфильтровать определенные приложения для намерения ACTION_SEND (и задать отдельный текст для каждого приложения)

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);       
}
 XxGoliathusxX22 июн. 2016 г., 20:20
Я заменил это нормальной строкой, а не html. Это тоже нормально? intent.putExtra (Intent.EXTRA_TEXT, getString (R.string.shareEmailText));
 XxGoliathusxX22 июн. 2016 г., 19:51
Хорошо, список выбора содержит: Email-приложения, File Explorer, Google Drive. Это выглядит действительно хорошо! Как добавить файл сейчас и для чего используется emailIntent, потому что он не используется ???
 XxGoliathusxX22 июн. 2016 г., 20:27
Для MMS это не работает! иначе if (packageName.contains ("mms")) {intent.putExtra (Intent.EXTRA_TEXT, "teile mms"); intent.putExtra (Intent.EXTRA_SUBJECT, имя тренинга + "-" + getString (R.string.datei)); intent.setType ( "сообщение / RFC822"); intent.putExtra (Intent.EXTRA_STREAM, uri); } Там написано: не могу добавить этот файл!
 XxGoliathusxX22 июн. 2016 г., 19:16
Хорошо я понял. Какой лучший способ справиться с этим?
 user333114222 июн. 2016 г., 19:25
Лучше всего, если бы другие приложения не включали пользовательский фильтр ContentProvider только для вашего расширения. Возможно, вам стоит работать с выбранным пользователем, если он у вас есть, или я могу использовать тип text / plain, но мне неизвестен формат ваших данных. ,
 XxGoliathusxX22 июн. 2016 г., 20:10
Я не понимаю этот код
 user333114222 июн. 2016 г., 19:34
Это довольно умно! Мне нравится. Я отредактировал свой ответ с чем-то, что я думаю, будет работать. Вы сами выбираете, какие приложения включены в селектор. Таким образом, вы можете выбрать только те приложения, которые будут работать, чтобы поделиться расширением.
 user333114222 июн. 2016 г., 20:30
 user333114222 июн. 2016 г., 20:06
Он используется в качестве основы дляopenInChooser намерение.Intent openInChooser = Intent.createChooser(emailIntent, resources.getString(R.string.share_chooser_text));  Он будет автоматически включать любые почтовые приложения на устройстве. Вы должны быть в состоянии добавить свой файл, как и раньше, сshareIntent.putExtra(Intent.EXTRA_STREAM, uri);
 user333114222 июн. 2016 г., 20:21
Я не использовал это, но из того, что я прочитал, это должно быть хорошо
 XxGoliathusxX22 июн. 2016 г., 19:27
Это просто код XML, но с расширением .oli. Потому что, если вы нажмете на файл, мое приложение запустится с кодом XML через фильтр намерений. Это работает! Но как поделиться файлом это проблема.
 user333114222 июн. 2016 г., 20:30
Это, вероятно, означает, что mms не разрешает неизвестные типы файлов. Мы должны перенести это обсуждение в чат для решения конкретных мелких вопросов. Я считаю, что на этот вопрос ответили
 XxGoliathusxX22 июн. 2016 г., 20:11
Для чего эта строка ?: emailIntent.putExtra (Intent.EXTRA_TEXT, Html.fromHtml (getString (R.string.share_email_native))));
 user333114222 июн. 2016 г., 20:18
EXTRA_TEXT помещает текст в тело письма. Я полагаю, что R.string.share_email_native - это «Отправлено с моего [phone_type]»

Ваш ответ на вопрос