标签:onchange contentobserver registercontentobser sms
我大概描述下公司项目:公司App是进行手机联系人之间的加密电话,加密短信,加密密聊。
我大概描述下我接的一个任务:我是公司App的用户,并且在线,此刻其他App在线用户,用App的密信功能给我发了一条短信(注意不是手机系统短信发送的,而是App密信功能发来的),此刻我实时收到,因为我在线。
那么任务来了,我退出App,此刻对方再次给我发来一条SMS短信,任务要求是我登录App,能在密信列表收到在我退出App时候,对方给我发来的一条短信
SMSProcessor.instance.register();// 注册sms事件监听
// 注册sms短信接收监听 public void register() { context.getContentResolver().registerContentObserver( Uri.parse("content://sms/"), true, mAuthContentObserver); /** 从sp中获取保存的sms的Id值--上次App退出前,收到的最后一条短信id值 */ SharedPreferencesUtils utils = new SharedPreferencesUtils(context, "lastSMSId"); if (utils != null) { lasterId = utils.getlong("AppLastSMSId"); // 或许>0判断的不严谨,不过我测试没问题,主要意思是如果App退出前存入的最后在线接收到的最后一条短信ID,那么sp里面获取的就是有值的,短信的id都是大于0的 if (lasterId > 0) { // 如果>0,在进行判断,判断的条件会在方法里面说明 insertSysSmsToLocalDatabase(lasterId); } else { // 这里貌似可有可无,因为测试没问题,我也懒得改了,因为我在后面的onChange方法里面有操作 lasterId = getDefaultLasterId(); } } }
/** * 这里进行获取是不是在app退出后, */ private void insertSysSmsToLocalDatabase(long AppLastSMSId) { // 查询系统的短信数据库,条件是判断是否大于上次App退出时候,保存的最后一条短信id,如果在此条件下,查询出来有结果集合,就说明,在我退出app时候,对方给我发来App密信 List<IMessageDetail> smsDetails = SystemSms.querySMSById("_id > " + AppLastSMSId); if (null == smsDetails || smsDetails.size() <= 0) { Log.e("AuthContentObserver", "null"); return; } //这里是循环获取在我退出app时候,对方给我发来的App密信 for (IMessageDetail smsDetail : smsDetails) { if (null != smsDetail) { String body = smsDetail.getMessageBody(); String address = smsDetail.getMobileNum(); // 打印不出来 if (address.startsWith("+86")) address = address.substring(3); if (!TextUtils.isEmpty(body) && !TextUtils.isEmpty(address)) { //这些操作不用太理解,是获取系统短信的信息的,另外公司的app里面,还将系统内置的短信转为加密短信,下面应该是一系列操作 byte[] bMsgs = body.getBytes(); byte[] bAddress = address.getBytes(); byte[] decMsg = SMSJNI.smsDecrpRequest(bMsgs, bMsgs.length, bAddress, bAddress.length); if (decMsg == null) { // 系统短信 Log.e("AuthContentObserver", "decMsg:" + "is null"); } else { String decContentString = new String(decMsg); smsDetail.setMessageBody(decContentString); smsDetail.setMobileNum(address); smsDetail .setMessageType(SQLiteManager.IMESSENGER_TYPE_SMS); smsDetail .setSendStatus(SQLiteManager.IMESSENGER_STATUS_SUCCEED); smsDetail.setContactId(0); //插入即可 List<Long> IDList = SQLiteManager.getInstance() .insertIMessagebyMobile(smsDetail, smsDetail.getDirection()); if (IDList == null || IDList.size() == 0) return; // 收到信息的广播--这里没有必要纠结,主要是用来做推送用的 Intent intent = new Intent(Code.SMS_RECEIVED_ACTION); intent.putExtra("phoneNum", address); intent.putExtra("ISSRC", true); intent.putExtra("ID", IDList.get(0)); // 发送广播 context.sendBroadcast(intent); /** * 在接受到退出app后,发来的短信后,需要更新lasterId值 */ lasterId = getDefaultLasterId(); /** * 下面这操作也很重要,有人问这难道需要保存??? * 是的需要的,因为如果在app退出之后,收到对方app发来的密信,然后我直接关掉了,所以也得需要保存到sp中 */ SharedPreferencesUtils spUtil = new SharedPreferencesUtils( context, "lastSMSId"); // 存入sp文件中 spUtil.setlong("AppLastSMSId", lasterId); } } } } // 发送广播 }
/** * 当短信uri发生变化时候,会调用onChange里面的方法 *当app在线时候,注意是在线时候,这里很重要,监听系统url变化 */ private final class AuthContentObserver extends ContentObserver { public AuthContentObserver(Handler handler) { super(handler); } // 当所监听的Uri发生改变时,就会回调此方法 @Override public void onChange(boolean selfChange) { super.onChange(selfChange); try { // 当app在线时候,注意是在线时候,这里很重要,监听系统url变化,这里还是lasterId, //我在每个阶段都赋值了,赋值的情况有1、退出app赋值2、登录app接受到新的密信赋值 List<IMessageDetail> smsDetails = SystemSms .querySMSById("_id > " + lasterId); Log.e("AuthContentObserver", "lasterId:---+++" + lasterId); if (null == smsDetails || smsDetails.size() <= 0) { return; } //以下的操作跟上面讲的一样,差不多 for (IMessageDetail smsDetail : smsDetails) { if (null != smsDetail) { String body = smsDetail.getMessageBody(); String address = smsDetail.getMobileNum(); if (address.startsWith("+86")) address = address.substring(3); if (!TextUtils.isEmpty(body) && !TextUtils.isEmpty(address)) { byte[] bMsgs = body.getBytes(); byte[] bAddress = address.getBytes(); byte[] decMsg = SMSJNI.smsDecrpRequest(bMsgs, bMsgs.length, bAddress, bAddress.length); if (decMsg == null) { // 系统短信 Log.e("AuthContentObserver", "decMsg:" + "is null"); } else { // 国鼎加密短信 String decContentString = new String(decMsg); smsDetail.setMessageBody(decContentString); smsDetail.setMobileNum(address); smsDetail .setMessageType(SQLiteManager.IMESSENGER_TYPE_SMS); smsDetail .setSendStatus(SQLiteManager.IMESSENGER_STATUS_SUCCEED); smsDetail.setContactId(0); List<Long> IDList = SQLiteManager.getInstance() .insertIMessagebyMobile(smsDetail, smsDetail.getDirection()); if (IDList == null || IDList.size() == 0) return; // 收到信息的广播 Intent intent = new Intent( Code.SMS_RECEIVED_ACTION); intent.putExtra("phoneNum", address); intent.putExtra("ISSRC", true); intent.putExtra("ID", IDList.get(0)); // 发送广播 context.sendBroadcast(intent); } } } // 接受到消息后,重新赋值最新的信息id lasterId = smsDetail.getId(); //以下操作就是在线时候,每次收到密信,就赋值 SharedPreferencesUtils utils = new SharedPreferencesUtils( context, "lastSMSId"); // 存入sp文件中 utils.setlong("AppLastSMSId", lasterId); } } catch (Exception e) { e.printStackTrace(); } finally { } } } /** * 从收信箱中获取最近的一条信息id * * @return */ private long getDefaultLasterId() { Uri uri = Uri.parse("content://sms/inbox"); String[] projection = new String[] { "body", "_id", "date" }; Cursor cursor = null; try { cursor = context.getContentResolver().query(uri, projection, null, null, "_id DESC"); if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); long id = cursor.getLong(cursor.getColumnIndex(projection[1])); return id; } } catch (SQLException e) { Log.e("getDefaultLasterId", " " + e.toString()); } finally { if (cursor != null) { cursor.close(); cursor = null; } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:onchange contentobserver registercontentobser sms
原文地址:http://blog.csdn.net/u013210620/article/details/47664135