首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

怎么自定义Intent.createChooser的显示结果

2013-09-15 
如何自定义Intent.createChooser的显示结果Intent是android核心的概念之一,Intent为android系统提供了真正

如何自定义Intent.createChooser的显示结果

Intent是android核心的概念之一,Intent为android系统提供了真正的开放。android的姿态是开放了,但却没有做到位。

拿“发邮件”这一功能来说,为了使用Intent机制来发送邮件,调用方需要知道Intent的规则,如action、uri、MIMEtype和category。但是在哪里能找到这些规则呢?官方文档里没有,还好能求助google,然后就发现StackOverflow有无数的人提过或者困惑于这个问题。从google搜索结果里没有看到导向官方文档的链接,由此大胆推测,官方文档确实没有相关的说明。

再者,从编写mail应用程序的角度来说,他们也迷茫-到底要支持那些Intent呢?我的Intent-filter到底要怎么写?难道是android team的geek精神作祟,一定要广大开发者分析gmail的apk才甘心?忍不住吐槽啊,这直接导致了用户体验不统一,程序猿编程不统一。

以上感受均来自我的一个非常合理的需求 - 发送多个附件的邮件

开始,我是这么做的

    Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);    emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{emailTo});    emailIntent.putExtra(Intent.EXTRA_CC, new String[]{emailCC});    emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);     emailIntent.putExtra(Intent.EXTRA_TEXT, emailText);    ArrayList<Uri> uris = new ArrayList<Uri>();    for (String file : filePaths) {        File fileIn = new File(file);        Uri u = Uri.fromFile(fileIn);        uris.add(u);    }    emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);    PackageManager pm = context.getPackageManager();    Intent sendMultipleIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);    List<ResolveInfo> aList = pm.queryIntentActivities(sendMultipleIntent, PackageManager.MATCH_DEFAULT_ONLY);    Intent mailIntent = new Intent(Intent.ACTION_SEND);    mailIntent.setData(Uri.fromParts("mailto", "", null));    List<ResolveInfo> bList = pm.queryIntentActivities(mailIntent, PackageManager.MATCH_DEFAULT_ONLY);    //TODO find out all target ResolbeInfo using aList and bList    List<ResolveInfo> targets = ...;    ArrayList<Intent> targetIntents = new ArrayList<Intent>();    for (ResolveInfo info : targets) {        ActivityInfo ai = info.activityInfo;        Intent intent = new Intent(emailIntent);        intent.setPackageName(ai.packageName);        intent.setClass(ai.packageName, ai.name);        targetIntents.add(intent);    }    Intent chooser = Intent.createChooser(targetIntents.remove(0), "Send mail...");    chooser.putParcelableArrayListExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents);    context.startActivity(chooser);

最终展现给用户的选择包括,符合createChooser第一个参数的应用(其实是指定了packageName和className的Intent),以及由EXTRA_INITIAL_INTENTS指定的应用。

注意,这里没有使用Intent.setComponent来明确指定要启动的Activity,而是通过setPackageName和setClass来指定。这是因为,在createChooser处理过程中,第一个参数intent指定的component会在ResolverActivity中强制被设置为null这样的结果是什么呢?当component被设置为null后,targetIntents.remove(0)其实就是emailIntent,那么createChooser会显示所有满足emailIntent的应用,然后在加上由EXTRA_INITIAL_INTENTS指定的应用。你会发现选择界面中出现了重复的应用。

热点排行