Android短信和彩信探秘threads


Android源代码在  彩信sms 表和彩信 pdu表,增加了一个触发器

  1. CREATE TRIGGER delete_obsolete_threads_pdu AFTER   
  2. DELETE ON pdu BEGIN     
  3. DELETE FROM threads     
  4. WHERE     _id = old.thread_id     AND _id NOT IN      
  5.  (SELECT thread_id FROM sms      UNION SELECT thread_id from pdu);  
  6.  END  

仔细看下就明白,如果threads表没有sms和pdu外部引用的时候,这条thread就会被删除。

thread被删除后,你再插入一条短信或者彩信(当然是代码插入),这时候因为没有thread id,所以就会不显示。

有人可能想到对threads表一起进行维护不就行了吗?  很不幸 ,系统对这个表的providers并不完全开放,只能用于查找。

但我们这时候又需要thread_id,   我对源代码进行了一些修改,把thread类提取了出来,仅供大家参考

  1. package com.sweetop.provider;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5. import java.util.regex.Matcher;  
  6. import java.util.regex.Pattern;  
  7.   
  8. import android.content.Context;  
  9. import android.database.Cursor;  
  10. import android.net.Uri;  
  11. import android.text.TextUtils;  
  12. import android.util.Log;  
  13. import android.util.Patterns;  
  14.   
  15. public final class Threads implements ThreadsColumns {  
  16.     private static final String[] ID_PROJECTION = { BaseColumns._ID };  
  17.     private static final String STANDARD_ENCODING = "UTF-8";  
  18.     private static final Uri THREAD_ID_CONTENT_URI = Uri  
  19.             .parse("content://mms-sms/threadID");  
  20.     public static final Uri CONTENT_URI = Uri.withAppendedPath(  
  21.             Uri.parse("content://mms-sms/"), "conversations");  
  22.     public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(  
  23.             CONTENT_URI, "obsolete");  
  24.     public static final Pattern NAME_ADDR_EMAIL_PATTERN = Pattern  
  25.             .compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");  
  26.   
  27.     public static final int COMMON_THREAD = 0;  
  28.     public static final int BROADCAST_THREAD = 1;  
  29.   
  30.     // No one should construct an instance of this class.   
  31.     private Threads() {  
  32.     }  
  33.   
  34.     /** 
  35.      * This is a single-recipient version of getOrCreateThreadId. It's 
  36.      * convenient for use with SMS messages. 
  37.      */  
  38.     public static long getOrCreateThreadId(Context context, String recipient) {  
  39.         Set<String> recipients = new HashSet<String>();  
  40.   
  41.         recipients.add(recipient);  
  42.         return getOrCreateThreadId(context, recipients);  
  43.     }  
  44.   
  45.     /** 
  46.      * Given the recipients list and subject of an unsaved message, return its 
  47.      * thread ID. If the message starts a new thread, allocate a new thread ID. 
  48.      * Otherwise, use the appropriate existing thread ID. 
  49.      *  
  50.      * Find the thread ID of the same set of recipients (in any order, without 
  51.      * any additions). If one is found, return it. Otherwise, return a unique 
  52.      * thread ID. 
  53.      */  
  54.     public static long getOrCreateThreadId(Context context,  
  55.             Set<String> recipients) {  
  56.         Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();  
  57.   
  58.         for (String recipient : recipients) {  
  59.             if (isEmailAddress(recipient)) {  
  60.                 recipient = extractAddrSpec(recipient);  
  61.             }  
  62.   
  63.             uriBuilder.appendQueryParameter("recipient", recipient);  
  64.         }  
  65.   
  66.         Uri uri = uriBuilder.build();  
  67.         // if (DEBUG) Log.v(TAG, "getOrCreateThreadId uri: " + uri);   
  68.   
  69.         Cursor cursor = context.getContentResolver().query(uri, ID_PROJECTION,  
  70.                 nullnullnull);  
  71.         if (true) {  
  72.             Log.v("Threads",  
  73.                     "getOrCreateThreadId cursor cnt: " + cursor.getCount());  
  74.         }  
  75.         if (cursor != null) {  
  76.             try {  
  77.                 if (cursor.moveToFirst()) {  
  78.                     return cursor.getLong(0);  
  79.                 } else {  
  80.                     Log.e("Threads""getOrCreateThreadId returned no rows!");  
  81.                 }  
  82.             } finally {  
  83.                 cursor.close();  
  84.             }  
  85.         }  
  86.   
  87.         Log.e("Threads",  
  88.                 "getOrCreateThreadId failed with uri " + uri.toString());  
  89.         throw new IllegalArgumentException(  
  90.                 "Unable to find or allocate a thread ID.");  
  91.     }  
  92.   
  93.     public static String extractAddrSpec(String address) {  
  94.         Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);  
  95.   
  96.         if (match.matches()) {  
  97.             return match.group(2);  
  98.         }  
  99.         return address;  
  100.     }  
  101.   
  102.     /** 
  103.      * Returns true if the address is an email address 
  104.      *  
  105.      * @param address 
  106.      *            the input address to be tested 
  107.      * @return true if address is an email address 
  108.      */  
  109.     public static boolean isEmailAddress(String address) {  
  110.         if (TextUtils.isEmpty(address)) {  
  111.             return false;  
  112.         }  
  113.   
  114.         String s = extractAddrSpec(address);  
  115.         Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);  
  116.         return match.matches();  
  117.     }  
  118. }  
当你需要获得一个thread id时,仅需调用
  1. Threads.getOrCreateThreadId(this, address)  

address是发送方的手机地址

相关内容