TextView的autoLink属性为咱们提供了很大的便利性,当文本中有网址,邮箱或电话的时候可让咱们方便地执行打电话发邮件等动做,不过也有一些问题,好比说设置autoLink包含email属性,当文本中有邮件地址时只要点击就能够调用邮件客户端来发邮件,可是若是当前系统中没有邮件客户端可供调用,程序会直接挂掉。ide
经过看Log能够发现,系统抛出了ActivityNotFoundException异常,而且Exception的getMessage中包含"mailto:xxxx@xxx.xxx"字样,当时第一反应是设置Thread.uncaughtExceptionHandler,判断若是异常的类型是ActivityNotFoundException而且Error Message中有"mailto"字样直接让uncaughtException函数返回,试了一下,程序确实没挂掉,窃喜中,可是接下来点击了一下屏幕,5秒钟后ANR了,好吧这个方法不行。函数
又想到当点击连接后会调用邮件客户端发邮件,确定有startActivity的调用,因而重载Activity的startActivity函数,把参数 intent的内容打出来(直接toString()就好了),发如今Intent的内容是ACTIVION_VIEW,并有extra data:mailto:xxxx@xxx.xxx,因此就经过intent包含的信息判断若是包含mailto字样就认为是系统调用邮件客户端发邮件,此时判断系统中是否有邮件客户端可处理这个请求,若是没有就把这个startActivity事件拦截下来。this
@Override public void startActivity(Intent intent) { if (intent.toString().indexOf("mailto") != -1) { // Any way to judge that this is to sead an email PackageManager pm = getPackageManager(); // The first Method List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0); if (activities == null || activities.size() == 0) { // Do anything you like, or just return return; } // Another method // ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); // if (resolveInfo == null) // Yet another metod // Intent.createChooser(intent, "Choose email client"); } super.startActivity(intent); }
代码就是上面这样,很简单,提到了三种方法,第一种和第二种都是经过PackageManager判断是否有能够处理这个Intent的请求的组件,若是没有就直接让startActivity返回,在返回以前你想干吗干吗,第三种方法是经过 Intent.createChoose手动弹出一个选择器,这个方法记得之前用是不行的,此次试了下居然能够,难道是我记错了?反正用前两种方法就行了。spa
不仅是邮件,若是你想经过如下代码跳转到应用市场让用户为你的应用评分code
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("market://details?id=" + getPackageName())); startActivity(intent);
若是用户系统中没有安装任何应用市场,很不幸,你的程序同样会挂掉,和前面说的email同样的问题:ActivityNotFoundException,不知道Google为何不处理一下,也许人家觉得手机上怎么可能没有邮件客户端和应用市场,不了解中国国情啊,不知道若是没有电话应用会是什么样?没有应用市场的处理是同样的方法,重载startActivity,只要你能判断这个请求是跳往市场的就好了。不过这个已经有了Intent对象,直接判断就好了,判断到没有市场直接不startActivity。对象