最近在写一个接收短信的APP,在这次的学习中其实收货还是挺多的,了解了基本的短信接收模式、数据库(SQLite)的创建和CROD操作的基本应用、适配器类的新建、SDK版本的获取的方法、接口的应用和UI线程的更新的思想;在开始写程序之前由于基本工比较差,所以我是在同事的指导下将项目划分若干部分进行写的,然后将各部分功能组合起来;
下面先来介绍下短信的接收代码:
1.首先需要在主函数里面注册一个广播接收器,在这里我是创建了一个SMSTools类,将注册方法写在类里面的,这样便于封装。
这些步骤就是注册一个广播的基本要求,对于广播也分有序广播和无序广播,我们可以抽空针对广播机制进行好好学习下,因为在android系统中广播的应够还是非常多的,基本上可以这样说,每一个APP都会用到广播,所以可想而知是多么重要了,他也是四大组件之一;
下面先来介绍下短信的接收代码:
1.首先需要在主函数里面注册一个广播接收器,在这里我是创建了一个SMSTools类,将注册方法写在类里面的,这样便于封装。
public void registerSmsReceiver(Context context, BroadcastReceiver ReceiverName) { ReceiverName = new SmsReceiver(); // 实例化一个广播接收器 IntentFilter filter = new IntentFilter(SMS_Action); // 设置Action // SMS_Action = "android.provider.Telephony.SMS_RECEIVED"; context.registerReceiver(ReceiverName, filter); // 注册广播接收器 }
这些步骤就是注册一个广播的基本要求,对于广播也分有序广播和无序广播,我们可以抽空针对广播机制进行好好学习下,因为在android系统中广播的应够还是非常多的,基本上可以这样说,每一个APP都会用到广播,所以可想而知是多么重要了,他也是四大组件之一;
2.下面我们来看广播接收器,看看他的实现以及短信内容的介绍方式,同样的我们是放在SmsTools类里面的。
package com.development.util.sms; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; /** * Created by Andy on 2015/6/5. */ public class SmsReceiver extends BroadcastReceiver{ SmsTools smsTools; @Override public void onReceive(Context context, Intent intent) { smsTools = SmsTools.getInstance(context); Log.d("MainActivity", "[1] SmsReceiver smsTools = " + smsTools); Log.d("MainActivity", "Action " + intent.getAction()); smsTools.getBroadcastData(intent); // 接收广播的短信内容 abortBroadcast(); // 终止广播接收 } }
在这里我们可以看到这是一个基本的广播接收器的模版,对于广播我们可以参照这个模版写,在这里我们是建一个单独的类来实现的,而不是内部类,这样做的主要原因是为了考虑后期项目工程的管理;下面我们再来看看广播接收对短信内容的解析处理。
/** * 通过广播来获取短信信息并更新UI界面 * * @param intent */ public void getBroadcastData(Intent intent) { if (intent.getAction().equals(SMS_Action)) { Bundle bundle = intent.getExtras(); if (bundle != null) { Object[] pdus = (Object[]) bundle.get("pdus"); //解析短信puds封装 SmsMessage[] messages = new SmsMessage[pdus.length]; //解析短信内容 for (int i = 0; i < pdus.length; i++) { byte[] pdu = (byte[]) pdus[i]; messages[i] = SmsMessage.createFromPdu(pdu); Log.d("MainActivity", "====== SmsReceiver[" + i + "]========"); } getSmsData(messages); // 获取每条短信的具体内容 smsUpdateData data = new MainActivity(); data.updataListView(); // 调用接口更新UI界面 Log.d("MainActivity", "[2] ReceiverBroast : " + data); } } }由于短信息是通过puds的方式通过电信运营商传递到android手机的,所以我们在接收到数据后就要求对数据进行puds解析,然后再分别取出每条短信的具体内容,最后进行短信内容的处理,在这里主要输将数据写入数据库中,让后再去读取数据库的数据, 记得在开始测试短信接收模块的时候我们是通过打印log的形式来测试短信内容是否读取到了,以及读取到的数据是否正确。我们来详细看看短信内容的具体读取方式,来具体了解下短信的接收。
/** * 读取短信的具体内容存入数据库中 * @param messages */ private void getSmsData(SmsMessage[] messages) { String temp = null ; SmsMessage sms = messages[0]; ContentValues values = new ContentValues(); Date date = new Date(sms.getTimestampMillis()); // 获取短信日期 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 转化日期格式 String receiveTime = format.format(date); values.put("date", receiveTime.trim()); // 将日期存入以键值对形式放入values 中;从该函数的实现中我们可以看出,主要是将短信内容存入数据库中,在这里需要注意的是短信大于170个字符或者67个汉字时是会自动分为多条发送的,所以我们在读取短信内容时也需要将短信还原为一条,不能让它显示多条,还有要注意的是在根据电话号码获取联系人的名字;temp = dealWithTel(sms.getOriginatingAddress()); // 由于电话号码前面运营商加入了“+86”字符。 Log.d(Tag,"temp = "+temp); smsUpdateData mdata = new MainActivity(); String name = mdata.getContactsName(temp,mContext); // 根据号码获得联系中的备注姓名Log.d(Tag, "name = " + name); values.put("telphone", name); // 将拆分的短信合并成一条信息存入数据库 if (messages.length == 1) { values.put("body", sms.getDisplayMessageBody()); } else { StringBuilder body = new StringBuilder(); for (int i = 0; i < messages.length; i++) { sms = messages[i]; body.append(sms.getDisplayMessageBody()); Log.d("MainActivity","sms = "+sms.getDisplayMessageBody()); } values.put("body", body.toString()); } values.put("status", sms.getStatus()); values.put("read", 0); values.put("ServiceCenterAddress", sms.getServiceCenterAddress()); insert(values); // 将数据插入数据库 }