zoukankan      html  css  js  c++  java
  • 接收新信息,在会话中看不到(thread表数据插入/更新失败)

    分析原因:收到短信,sms表插入信息,触发器会自动更新thread表,更新失败导致一直有一条未读信息数量显示,但在会话列表中却看不到。
          (偶现,低概率。 解决方法:接收新信息插入后,立即查询thread表,如果刚刚的信息查不到,则再次手动更新)

        androidpackagesprovidersTelephonyProvidersrccomandroidproviders elephonyMmsSmsDatabaseHelper.java中定义了触发器

    private void createCommonTriggers(SQLiteDatabase db) {
            // Updates threads table whenever a message is added to sms.
            db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
                       SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
    
            // Updates threads table whenever a message in sms is updated.
            db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
                       "  UPDATE OF " + Sms.DATE + ", " + Sms.BODY + ", " + Sms.TYPE +
                       "  ON sms " +
                       SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
    
            // Updates threads table whenever a message in sms is updated.
            db.execSQL("CREATE TRIGGER sms_update_thread_read_on_update AFTER" +
                       "  UPDATE OF " + Sms.READ +
                       "  ON sms " +
                       "BEGIN " +
                       SMS_UPDATE_THREAD_READ_BODY +
                       "END;");
    
    
            // TODO Add triggers for SMS retry-status management.
    
            // Update the error flag of threads when the error type of
            // a pending MM is updated.
            db.execSQL("CREATE TRIGGER update_threads_error_on_update_mms " +
                       "  AFTER UPDATE OF err_type ON pending_msgs " +
                       "  WHEN (OLD.err_type < 10 AND NEW.err_type >= 10)" +
                       "    OR (OLD.err_type >= 10 AND NEW.err_type < 10) " +
                       "BEGIN" +
                       "  UPDATE threads SET error = " +
                       "    CASE" +
                       "      WHEN NEW.err_type >= 10 THEN error + 1" +
                       "      ELSE error - 1" +
                       "    END " +
                       "  WHERE _id =" +
                       "   (SELECT DISTINCT thread_id" +
                       "    FROM pdu" +
                       "    WHERE _id = NEW.msg_id); " +
                       "END;");
    
            // Update the error flag of threads after a text message was
            // failed to send/receive.
            db.execSQL("CREATE TRIGGER update_threads_error_on_update_sms " +
                       "  AFTER UPDATE OF type ON sms" +
                       "  WHEN (OLD.type != 5 AND NEW.type = 5)" +
                       "    OR (OLD.type = 5 AND NEW.type != 5) " +
                       "BEGIN " +
                       "  UPDATE threads SET error = " +
                       "    CASE" +
                       "      WHEN NEW.type = 5 THEN error + 1" +
                       "      ELSE error - 1" +
                       "    END " +
                       "  WHERE _id = NEW.thread_id; " +
                       "END;");
        }
    View Code

        Ril层接收新信息会通过Framework发通知——android.provider.Telephony.SMS_DELIVER

        APP层MMS开始处理com.android.mms.transaction.PrivilegedSmsReceiver接收广播,  

    com.android.mms.transaction.SmsReceiverService调用handleSmsReceived(intent, error)方法,
    ————>saveMessageToPhone(msgs, error, format)————> insertMessage(this, msgs, error, format)
    ————>storeMessage(context, msgs, error);

    storeMessage(context, msgs, error)方法最后,增加查询thread表,确认信息更新是否成功,如果thread表信息更新失败,手动更新.
     private Uri storeMessage(Context context, SmsMessage[] msgs, int error) {
            // Check to see whether short message count is up to 2000 for cmcc
            if (MessageUtils.checkIsPhoneMessageFull(this)) {
                return null;
            }
    
            SmsMessage sms = msgs[0];
    
            // Store the message in the content provider.
            ContentValues values = extractContentValues(sms);
            values.put(Sms.ERROR_CODE, error);
            values.put(Sms.PHONE_ID, SubscriptionManager.getPhoneId(sms.getSubId()));
    
            int pduCount = msgs.length;
    
            if (pduCount == 1) {
                // There is only one part, so grab the body directly.
                values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody()));
            } else {
                // Build up the body from the parts.
                StringBuilder body = new StringBuilder();
                for (int i = 0; i < pduCount; i++) {
                    sms = msgs[i];
                    if (sms.mWrappedSmsMessage != null) {
                        body.append(sms.getDisplayMessageBody());
                    }
                }
                values.put(Inbox.BODY, replaceFormFeeds(body.toString()));
            }
    
            // Make sure we've got a thread id so after the insert we'll be able to delete
            // excess messages.
            Long threadId = values.getAsLong(Sms.THREAD_ID);
            String address = values.getAsString(Sms.ADDRESS);
    
            // Code for debugging and easy injection of short codes, non email addresses, etc.
            // See Contact.isAlphaNumber() for further comments and results.
    //        switch (count++ % 8) {
    //            case 0: address = "AB12"; break;
    //            case 1: address = "12"; break;
    //            case 2: address = "Jello123"; break;
    //            case 3: address = "T-Mobile"; break;
    //            case 4: address = "Mobile1"; break;
    //            case 5: address = "Dogs77"; break;
    //            case 6: address = "****1"; break;
    //            case 7: address = "#4#5#6#"; break;
    //        }
    
            if (!TextUtils.isEmpty(address)) {
                Contact cacheContact = Contact.get(address,true);
                if (cacheContact != null) {
                    address = cacheContact.getNumber();
                }
            } else if (TextUtils.isEmpty(address)
                    && getResources().getBoolean(R.bool.def_hide_unknown_sender)) {
                values.put(Sms.ADDRESS, "");
            } else {
                address = getString(R.string.unknown_sender);
                values.put(Sms.ADDRESS, address);
            }
    
            if (((threadId == null) || (threadId == 0)) && (address != null)) {
                threadId = Conversation.getOrCreateThreadId(context, address);
                values.put(Sms.THREAD_ID, threadId);
            }
    
            ContentResolver resolver = context.getContentResolver();
    
            Uri insertedUri = SqliteWrapper.insert(context, resolver, Inbox.CONTENT_URI, values);
    
            // Now make sure we're not over the limit in stored messages
            Recycler.getSmsRecycler().deleteOldMessagesByThreadId(context, threadId);
            MmsWidgetProvider.notifyDatasetChanged(context);
    
     //---add by antoon ----------------------------------------------------------------------------------------------------
            //query thread to check if thread update or create successfully, if not update here
            StringBuilder sbUri = new StringBuilder(3);
            sbUri.append("content://mms-sms/conversations/").append(threadId).append("/recipients");
            Cursor curosr = resolver.query(Uri.parse(sbUri.toString()),null,null,null,null);
            Log.i("antoon", "SmsReceiverService, --> storeMessage , curosr = "+curosr);
            if(curosr == null || curosr.getCount()==0){
                SqliteWrapper.insert(context, resolver, Telephony.Threads.CONTENT_URI, values);//------手动更新thread表
            }else{
                Log.d("antoon", "SmsReceiverService, --> storeMessage , curosr.getCount = " + curosr.getCount());
            }
    //---end add by antoon ------------------------------------------------------------------------------------------------- return insertedUri; }

     TelephonyProvider中增加相应的数据库处理。 androidpackagesprovidersTelephonyProvidersrccomandroidproviders elephonyMmsSmsProvider.java中增加 insert/update 处理

    @Override
        public Uri insert(Uri uri, ContentValues values) {
            if (URI_MATCHER.match(uri) == URI_PENDING_MSG) {
                SQLiteDatabase db = mOpenHelper.getWritableDatabase();
                long rowId = db.insert(TABLE_PENDING_MSG, null, values);
                return Uri.parse(uri + "/" + rowId);
            }
    //------ add by antoon
            else if(URI_MATCHER.match(uri) == URI_CONVERSATIONS){
                Log.i("antoon", "MmsSmsProvider -> insert,  URI_CONVERSATIONS");
                insertThreadsIfDataLost(values);
                return null;
            }

    //------ end add by antoon throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES + uri); }
    //------add by antoon, create thread data if thread trigger fail
        public void insertThreadsIfDataLost(ContentValues values) {
            long _id = values.getAsLong(Sms.THREAD_ID);
            long date = values.getAsLong(Sms.DATE);
            String snippet = values.getAsString(Sms.BODY);
            String address = values.getAsString(Sms.ADDRESS);
    
            //create a new thread id with new msg address, then update threadId to _id
            List<String> list = new ArrayList<String>();
            list.add(address);
            Cursor cursor = getThreadId(list, false);//------这里的查询会判断threadId是否存在,如果不存在则创建threadId新数据,如果存在则直接返回
            cursor.moveToFirst();
            long threadId = cursor.getLong(0);
            cursor.close();
            /*
            String updateSql = "UPDATE threads SET date = ?, snippet = ?, snippet_cs = 0, read=0, "
                    + "message_count = (SELECT COUNT(sms._id) FROM sms WHERE sms.thread_id = ? AND sms.type!= 3) + "
                    +"(SELECT COUNT(pdu._id) FROM pdu WHERE pdu.thread_id = ? AND (m_type=132 OR m_type=130 OR m_type=128) AND msg_box!= 3)"
                    + " WHERE threads._id = ?";
            */
    
            StringBuilder sqlSb = new StringBuilder(14);
            sqlSb.append("UPDATE threads SET _id =").append(_id)
                    .append(", date =").append(date)
                    .append(", snippet ='").append(snippet)
                    .append("', snippet_cs = 0, read=0, ")
                    .append("message_count = (SELECT COUNT(sms._id) FROM sms WHERE sms.thread_id = ").append(threadId)
                    .append(" AND sms.type!= 3) + (SELECT COUNT(pdu._id) FROM pdu WHERE pdu.thread_id =").append(threadId)
                    .append(" AND (m_type=132 OR m_type=130 OR m_type=128) AND msg_box!= 3) WHERE threads._id = ").append(threadId)
                    ;
    
    
            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
            db.execSQL(sqlSb.toString());
    
            Log.i("antoon", "sqlSb = " + sqlSb);
        }
    //------end add by antoon


  • 相关阅读:
    二分+RMQ/双端队列/尺取法 HDOJ 5289 Assignment
    思维题 HDOJ 5288 OO’s Sequence
    树形DP Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland
    最大流增广路(KM算法) HDOJ 1853 Cyclic Tour
    最大流增广路(KM算法) HDOJ 1533 Going Home
    最大流增广路(KM算法) HDOJ 2255 奔小康赚大钱
    Complete the Word CodeForces
    Gadgets for dollars and pounds CodeForces
    Vasya and Basketball CodeForces
    Carries SCU
  • 原文地址:https://www.cnblogs.com/antoon/p/Mms.html
Copyright © 2011-2022 走看看