Android 共享自定义文件
Android Share custom file
我创建了自己的文件扩展名 (.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-app,我会收到一条消息,指出此文件无法共享。
所以总而言之,我只想在选择器列表中显示可以处理共享我的扩展名为 .oli 的文件的应用程序。我怎么做?提前致谢!
setType()
intent 方法实际上使用 MIME 类型根据 docs 过滤应用程序。因此,您将只能根据以下过滤器过滤可用的应用程序:
1.Text
sendIntent.setType("text/plain");
2。二进制
shareIntent.setType("image/jpeg");
3。多个内容项
shareIntent.setType("image/*");
编辑
这是我可能会做的事情,我会知道我希望哪些应用程序能够共享该文件,例如 gmail,因为您知道它可以工作,而且我会选择列表中的哪些应用程序。以下代码来自本SOlink中的答案: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);
}
我创建了自己的文件扩展名 (.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-app,我会收到一条消息,指出此文件无法共享。
所以总而言之,我只想在选择器列表中显示可以处理共享我的扩展名为 .oli 的文件的应用程序。我怎么做?提前致谢!
setType()
intent 方法实际上使用 MIME 类型根据 docs 过滤应用程序。因此,您将只能根据以下过滤器过滤可用的应用程序:
1.Text
sendIntent.setType("text/plain");
2。二进制
shareIntent.setType("image/jpeg");
3。多个内容项
shareIntent.setType("image/*");
编辑
这是我可能会做的事情,我会知道我希望哪些应用程序能够共享该文件,例如 gmail,因为您知道它可以工作,而且我会选择列表中的哪些应用程序。以下代码来自本SOlink中的答案: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);
}