点击短信内容,获取短信内的号码和链接(2)
来源:互联网 发布:软件销售提成方案 编辑:程序博客网 时间:2024/05/21 11:29
[转]点击短信内容,获取短信内的号码和链接(2)
转自:MrDemigod的专栏http://m.blog.csdn.net/blog/MrDemigod/12911659
上次分析了点击短信产生对应号码和链接的主要方法,现在需要考虑的问题是,怎样才能将这些系统识别出来的号码和链接区分开,而不是一起显示。
分析过程:
1,首先焦点不能落在item上,这样通过item获取到的肯定是所有被autoLink的对象;
2,不能通过onItemClick来触发号码或者链接的菜单栏,甚至不能设置onItemClick事件,因为我们希望获得焦点的是item里面的link而不是item。
既然想到了焦点问题,我们不妨再深入一点,我不在onItemClick里面的onMessageListItemClick()里面来触发,只能通过link来触发,link又没法获取到焦点,这是怎么回事?
(1)查看xml不难发现,listView为了让item始终获得焦点将短信的textview焦点获取设置成了false(不仅仅是短信textview,item内的所有view的焦点获取都被设置成了false),那我们先把这个焦点获取设置成true,然后添加android:linksClickable="true" 再点击短信里面的链接,发现可以直接打开网页了,点击号码可以直接拨号了。
(2)但这不是我们想要的效果。我们还是先把上面两个属性改成原来的样子(为什么?因为考虑到短信的多选,item的焦点获取必须要保证)
既然不能在配置文件里面将短信内容TextView的焦点属性定为true,那我只能在短信会话ListView更新数据并列出的时候就让这些TextView可以获得焦点,这就要对adapter做处理了。
(3)上文我们分析到了MessageListView使用到的适配器是MessageListAdapter,分析MessageListAdapter我们惊奇的发现他居然连一个adapter最需要的getView()都没有!其实也是,他本意就不想我们去处理item里面的子view,何须getView。但是这里我们就是要获取子View,还要写他们的onClick事件,决不能少了getView()!
(4)开始重写getView():
public View getView(int position, View convertView, ViewGroup parent) {View v = super.getView(position, convertView, parent);TextView tv = (TextView) v.findViewById(R.id.text_view);tv.setFocusableInTouchMode(true);tv.setFocusable(true);tv.setLinksClickable(true);urls = tv.getUrls();Log.i("Fred", "textView = " + tv.getText());SpannableStringBuilder str = new SpannableStringBuilder(tv.getText());Spannable sp = (Spannable) str;SpannableStringBuilder style = new SpannableStringBuilder(tv.getText());style.clearSpans();for (URLSpan url : urls) {MyURLSpan myURLSpan = new MyURLSpan(url.getURL());style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);}tv.setText(style);return v;}
getView()做的事情其实很简单,就是想法设法在短信内容TextView写入之前重新组合,变成链接和号码可点击的item中的子view。
(5)继续看看MyURLSpan这个类:
class MyURLSpan extends ClickableSpan {private String mUrl;private String mms;private String phone;MyURLSpan(String url) {mUrl = url;mms = "smsto:";phone = "tel:";}@Overridepublic void onClick(View widget) {// Toast.makeText(mContext," hello! "+mUrl,// Toast.LENGTH_SHORT).show();links = new ArrayList<String>();mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso();if (mUrl.contains(phone)) {links.add(mUrl);links.add(mUrl.replaceAll(phone, mms));} elselinks.add(mUrl);ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,android.R.layout.select_dialog_item, links) {@Overridepublic View getView(int position, View convertView,ViewGroup parent) {View v = super.getView(position, convertView, parent);TextView tv = (TextView) v;String url = getItem(position).toString();Uri uri = Uri.parse(url);final String telPrefix = "tel:";Drawable d = null;try {d = mContext.getPackageManager().getActivityIcon(new Intent(Intent.ACTION_VIEW, uri));} catch (android.content.pm.PackageManager.NameNotFoundException ex) {}if (d != null) {d.setBounds(0, 0, d.getIntrinsicHeight(),d.getIntrinsicHeight());tv.setCompoundDrawablePadding(10);tv.setCompoundDrawables(d, null, null, null);} else {if (url.startsWith(telPrefix)) {d = mContext.getResources().getDrawable(R.drawable.ic_launcher_phone);d.setBounds(0, 0, d.getIntrinsicHeight(),d.getIntrinsicHeight());tv.setCompoundDrawablePadding(10);tv.setCompoundDrawables(d, null, null, null);} else {tv.setCompoundDrawables(null, null, null, null);}}final String smsPrefix = "smsto:";final String mailPrefix = "mailto";if (url.startsWith(telPrefix)) {url = PhoneNumberUtils.formatNumber(url.substring(telPrefix.length()),mDefaultCountryIso);if (url == null) {url = getItem(position).toString().substring(telPrefix.length());}} else if (url.startsWith(smsPrefix)) { url = PhoneNumberUtils.formatNumber(url.substring(smsPrefix.length()),mDefaultCountryIso);if (url == null) {url = getItem(position).toString().substring(smsPrefix.length());}} else if (url.startsWith(mailPrefix)) {MailTo mt = MailTo.parse(url);url = mt.getTo();}tv.setText(url);return v;}};AlertDialog.Builder b = new AlertDialog.Builder(mContext);DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() {@Overridepublic final void onClick(DialogInterface dialog, int which) {if (which >= 0) {Uri uri = Uri.parse(links.get(which));Intent intent = new Intent(Intent.ACTION_VIEW, uri);intent.putExtra(Browser.EXTRA_APPLICATION_ID,mContext.getPackageName());if (links.get(which).startsWith("smsto:")) {intent.setClassName(mContext,"com.android.mms.ui.SendMessageToActivity");}intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);mContext.startActivity(intent);if (links.get(which).startsWith("smsto:")) {intent.setClassName(mContext,"com.android.mms.ui.SendMessageToActivity");}}dialog.dismiss();}};b.setTitle(R.string.select_link_title);b.setCancelable(true);b.setAdapter(adapter, click);b.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener() {@Overridepublic final void onClick(DialogInterface dialog,int which) {dialog.dismiss();}});b.show();}}
(6)好吧,不难看出,我这个类里面除了构造方法和一些数组处理,其他基本都是照抄的MessageListItem类的onMessageListItemClick()方法里面的内容。确实,他们获取链接或者号码然后生成菜单的方式确实就是一样的 =。=
(7)到了这里,基本的修改都已经完成了,在生成ListView的时候才修改TextView的焦点属性,让短信列表中号码和链接可以被点击。但总觉得还有不妥。我这样将MessageListAdapter类修改了,多了这个getView()方法,并且写入了onClick事件,会导致所有用到这个adapter的listView的ltem被注册这些事件,这不符合我们代码涉及的原则。所以我们新建一个类MessageListAdapterHistory继承MessageListAdapter,然后将关于getView()的部分移动到MessageListAdapterHistory中,然后只修改
mMsgListAdapter = new MessageListAdapterHistory();即可。也不会影响到其他列表(比如多选等)对item的操作。
转自:MrDemigod的专栏http://m.blog.csdn.net/blog/MrDemigod/12911659
- 点击短信内容,获取短信内的号码和链接
- 点击短信内容,获取短信内的号码和链接(2)
- 点击短信内容,获取短信内的号码和链接(2)
- Android 监听短信接收 获取发件号码、短信内容
- 短信中心号码获取
- android获取短信的内容
- Android 调用系统发送短信界面,预设号码和短信内容
- Android 调用系统发送短信界面,预设号码和短信内容
- 获取手机的短信内容和联系人信息
- 调用系统界面,给指定的号码发送短信,附带短信内容
- android 获取手机电话号码和短信内容
- Android 获取通话记录和短信内容
- 获取短信内容
- 获取短信内容
- Android 获取短信内容
- 获取短信内容
- 如何获取短信内容
- android学习笔记22--------------通过短信的号码获取联系人
- (五十七)指针、数组、指针算数
- Struts2-ActionMethod
- C++ vector用法
- 关于各种字符编码
- Codeblocks 安装
- 点击短信内容,获取短信内的号码和链接(2)
- opencv2.2以上不支持CvvImage的解决办法
- android studio安装出现两个图标的问题
- class_create
- POST和GET
- bootstrap 模态框显示时点击遮罩层禁止关闭,点击按钮时关闭模态框。
- SDUTOJ 树的同构
- mysql下事务和锁
- Aprior算法 -- Java实现