现在的位置: 首页 > 综合 > 正文

SMS Android SMS(一) —— 读取短信Android SMS(二)—— 读取短信保存到 SQLite

2017年12月12日 ⁄ 综合 ⁄ 共 15510字 ⁄ 字号 评论关闭

Android SMS(一) —— 读取短信

分类: Android 9440人阅读 评论(9) 收藏 举报

Android SMS Read

  1. package com.homer.sms;  
  2.   
  3. import java.sql.Date;  
  4. import java.text.SimpleDateFormat;  
  5.   
  6.   
  7. import android.app.Activity;  
  8. import android.database.Cursor;  
  9. import android.database.sqlite.SQLiteException;  
  10. import android.net.Uri;  
  11. import android.os.Bundle;  
  12. import android.util.Log;  
  13. import android.widget.ScrollView;  
  14. import android.widget.TableLayout;  
  15. import android.widget.TextView;  
  16.   
  17. /** 
  18.  * 读取手机短信 
  19.  *  
  20.  * @author sunboy_2050 
  21.  * @since  http://blog.csdn.net/sunboy_2050 
  22.  * @date   2012.03.06 
  23.  */  
  24. public class smsRead extends Activity {  
  25.   
  26.     @Override  
  27.     public void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.   
  30.         TextView tv = new TextView(this);  
  31.         tv.setText(getSmsInPhone());  
  32.   
  33.         ScrollView sv = new ScrollView(this);  
  34.         sv.addView(tv);  
  35.           
  36.         setContentView(sv);  
  37.     }  
  38.   
  39.     public String getSmsInPhone() {  
  40.         final String SMS_URI_ALL = "content://sms/";  
  41.         final String SMS_URI_INBOX = "content://sms/inbox";  
  42.         final String SMS_URI_SEND = "content://sms/sent";  
  43.         final String SMS_URI_DRAFT = "content://sms/draft";  
  44.         final String SMS_URI_OUTBOX = "content://sms/outbox";  
  45.         final String SMS_URI_FAILED = "content://sms/failed";  
  46.         final String SMS_URI_QUEUED = "content://sms/queued";  
  47.   
  48.         StringBuilder smsBuilder = new StringBuilder();  
  49.   
  50.         try {  
  51.             Uri uri = Uri.parse(SMS_URI_ALL);  
  52.             String[] projection = new String[] { "_id""address""person""body""date""type" };  
  53.             Cursor cur = getContentResolver().query(uri, projection, nullnull"date desc");      // 获取手机内部短信  
  54.   
  55.             if (cur.moveToFirst()) {  
  56.                 int index_Address = cur.getColumnIndex("address");  
  57.                 int index_Person = cur.getColumnIndex("person");  
  58.                 int index_Body = cur.getColumnIndex("body");  
  59.                 int index_Date = cur.getColumnIndex("date");  
  60.                 int index_Type = cur.getColumnIndex("type");  
  61.   
  62.                 do {  
  63.                     String strAddress = cur.getString(index_Address);  
  64.                     int intPerson = cur.getInt(index_Person);  
  65.                     String strbody = cur.getString(index_Body);  
  66.                     long longDate = cur.getLong(index_Date);  
  67.                     int intType = cur.getInt(index_Type);  
  68.   
  69.                     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");  
  70.                     Date d = new Date(longDate);  
  71.                     String strDate = dateFormat.format(d);  
  72.   
  73.                     String strType = "";  
  74.                     if (intType == 1) {  
  75.                         strType = "接收";  
  76.                     } else if (intType == 2) {  
  77.                         strType = "发送";  
  78.                     } else {  
  79.                         strType = "null";  
  80.                     }  
  81.   
  82.                     smsBuilder.append("[ ");  
  83.                     smsBuilder.append(strAddress + ", ");  
  84.                     smsBuilder.append(intPerson + ", ");  
  85.                     smsBuilder.append(strbody + ", ");  
  86.                     smsBuilder.append(strDate + ", ");  
  87.                     smsBuilder.append(strType);  
  88.                     smsBuilder.append(" ]\n\n");  
  89.                 } while (cur.moveToNext());  
  90.   
  91.                 if (!cur.isClosed()) {  
  92.                     cur.close();  
  93.                     cur = null;  
  94.                 }  
  95.             } else {  
  96.                 smsBuilder.append("no result!");  
  97.             } // end if  
  98.   
  99.             smsBuilder.append("getSmsInPhone has executed!");  
  100.   
  101.         } catch (SQLiteException ex) {  
  102.             Log.d("SQLiteException in getSmsInPhone", ex.getMessage());  
  103.         }  
  104.   
  105.         return smsBuilder.toString();  
  106.     }  
  107. }  

AndroidManifest.xml 权限

 记得在AndroidManifest.xml中加入android.permission.READ_SMS这个permission

<uses-permission android:name="android.permission.READ_SMS" />


运行结果:

代码示例



URI主要有:

content://sms/               所有短信
content://sms/inbox        收件箱
content://sms/sent          已发送
content://sms/draft         草稿
content://sms/outbox     发件箱
content://sms/failed       发送失败
content://sms/queued    待发送列表

sms主要结构: 

  1. _id => 短消息序号 如100  
  2. thread_id => 对话的序号 如100  
  3. address => 发件人地址,手机号.如+8613811810000  
  4. person => 发件人,返回一个数字就是联系人列表里的序号,陌生人为null  
  5. date => 日期  long型。如1256539465022  
  6. protocol => 协议 0 SMS_RPOTO, 1 MMS_PROTO   
  7. read => 是否阅读 0未读, 1已读   
  8. status => 状态 -1接收,0 complete, 64 pending, 128 failed   
  9. type => 类型 1是接收到的,2是已发出   
  10. body => 短消息内容   
  11. service_center => 短信服务中心号码编号。如+8613800755500  

String[] projection = new String[]{"address", "body"};
Cursor cursor = getContentResolver().query(uri, projection, "where .." new String[]{"", ""}, "order by ..")


Android短信存储数据库

偶然发现了Android源码中的一个类MmsSmsDatabaseHelper.java,原来android将所有的短信信息都存入了mmssms.db中。

公开的SDK中没有这个类,不能直接使用。于是自己写了一个SQLiteOpenHelper,但是查询的时候发生SQL异常。看来不能为所欲为了,不过据网上资料介绍可以拷贝db文件来实现短信数据备份。

MmsSmsDatabaseHelper.java在Android源码中的路径:

packages/providers/TelephonyProvider/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java


sms数据库中的字段如下:

_id               一个自增字段,从1开始
thread_id    序号,同一发信人的id相同
address      发件人手机号码
person        联系人列表里的序号,陌生人为null 
date            发件日期
protocol      协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO  
read           是否阅读 0未读, 1已读  
status         状态 -1接收,0 complete, 64 pending, 128 failed 
type     
    ALL    = 0;
    INBOX  = 1;
    SENT   = 2;
    DRAFT  = 3;
    OUTBOX = 4;
    FAILED = 5;
    QUEUED = 6;
 
body                     短信内容
service_center     短信服务中心号码编号
subject                  短信的主题
reply_path_present     TP-Reply-Path
locked    


sms数据库表字段类型的源码:

  1. private void createSmsTables(SQLiteDatabase db) {  
  2.         // N.B.: Whenever the columns here are changed, the columns in  
  3.         // {@ref MmsSmsProvider} must be changed to match.  
  4.         db.execSQL("CREATE TABLE sms (" +  
  5.                    "_id INTEGER PRIMARY KEY," +  
  6.                    "thread_id INTEGER," +  
  7.                    "address TEXT," +  
  8.                    "person INTEGER," +  
  9.                    "date INTEGER," +  
  10.                    "date_sent INTEGER DEFAULT 0," +  
  11.                    "protocol INTEGER," +  
  12.                    "read INTEGER DEFAULT 0," +  
  13.                    "status INTEGER DEFAULT -1," + // a TP-Status value  
  14.                                                   // or -1 if it  
  15.                                                   // status hasn't  
  16.                                                   // been received  
  17.                    "type INTEGER," +  
  18.                    "reply_path_present INTEGER," +  
  19.                    "subject TEXT," +  
  20.                    "body TEXT," +  
  21.                    "service_center TEXT," +  
  22.                    "locked INTEGER DEFAULT 0," +  
  23.                    "error_code INTEGER DEFAULT 0," +  
  24.                    "seen INTEGER DEFAULT 0" +  
  25.                    ");");  
  26. ....  
  27. }  

packages/providers/TelephonyProvider/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java


联系人为空

短信数据库里面如果你是先受到陌生短信之后再把陌生人添加到联系人列表的话,短信数据库里面的person字段就为null,如果你是先添加联系人再发短信的话,短信数据库里面的person字段就不为空了,所以你要是想通过短信数据库里的字段取得联系人的其他信息的话,只能通过地址来取。

Android SMS(二)—— 读取短信保存到 SQLite

分类: Android 3895人阅读 评论(12) 收藏 举报

Android 之 SMS 短信在Android系统中是保存在SQLite数据库中的,但不让其它程序访问(Android系统的安全机制)

现在我们在读取手机内的SMS短信,先保存在我们自己定义的SQLite数据库中,然后读取SQLite数据库提取短信,并显示

SMS短信SQLite存取代码:

  1. package com.homer.sms;  
  2.   
  3. import java.sql.Date;  
  4. import java.text.SimpleDateFormat;  
  5.   
  6. import org.loon.wsi.R;  
  7.   
  8. import android.app.Activity;  
  9. import android.content.Context;  
  10. import android.database.Cursor;  
  11. import android.database.sqlite.SQLiteDatabase;  
  12. import android.graphics.Color;  
  13. import android.net.Uri;  
  14. import android.os.Bundle;  
  15. import android.util.Log;  
  16. import android.widget.TableLayout;  
  17. import android.widget.TableRow;  
  18. import android.widget.TableRow.LayoutParams;  
  19. import android.widget.TextView;  
  20.   
  21. /** 
  22.  * 读取手机短信, 先保存到SQLite数据,然后再读取数据库显示 
  23.  *  
  24.  * @author sunboy_2050 
  25.  * @since  http://blog.csdn.net/sunboy_2050 
  26.  * @date   2012.03.06 
  27.  */  
  28. public class smsRead4 extends Activity {  
  29.   
  30.     TableLayout tableLayout;  
  31.     int index = 0;  
  32.   
  33.     @Override  
  34.     public void onCreate(Bundle savedInstanceState) {  
  35.         super.onCreate(savedInstanceState);  
  36.   
  37.         setContentView(R.layout.main);  
  38.   
  39.         tableLayout = (TableLayout) findViewById(R.id.tableLayout);  
  40.         showSMS();  
  41.     }  
  42.   
  43.     private void showSMS() {  
  44.         SmsHander smsHander = new SmsHander(this);  
  45.   
  46.         smsHander.createSMSDatabase();                          // 创建SQLite数据库  
  47.         smsHander.insertSMSToDatabase();                        // 读取手机短信,插入SQLite数据库  
  48.         Cursor cursor = smsHander.querySMSInDatabase(100);      // 获取前100条短信(日期排序)  
  49.   
  50.         cursor.moveToPosition(-1);  
  51.         while (cursor.moveToNext()) {  
  52.             String strAddress = cursor.getString(cursor.getColumnIndex("address"));  
  53.             String strDate = cursor.getString(cursor.getColumnIndex("date"));  
  54.             String strBody = cursor.getString(cursor.getColumnIndex("body"));  
  55.   
  56.             SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  57.             Date date = new Date(Long.parseLong(strDate));  
  58.             strDate = dateFormat.format(date);  
  59.   
  60.             String smsTitle = strAddress + "\t\t" + strDate;  
  61.             String smsBody = strBody + "\n";  
  62.             Log.i("tableRow", smsTitle + smsBody);  
  63.   
  64.             // title Row  
  65.             TableRow trTitle = new TableRow(this);  
  66.             trTitle.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
  67.   
  68.             TextView tvTitle = new TextView(this);  
  69.             tvTitle.setText(smsTitle);  
  70.             tvTitle.getPaint().setFakeBoldText(true); // 加粗字体  
  71.             tvTitle.setTextColor(Color.RED);  
  72.             tvTitle.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
  73.             trTitle.addView(tvTitle);  
  74.             tableLayout.addView(trTitle, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));  
  75.   
  76.             // body Row  
  77.             TableRow trBody = new TableRow(this);  
  78.             trBody.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
  79.   
  80.             TextView tvBody = new TextView(this);  
  81.             tvBody.setText(smsBody);  
  82.             tvBody.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
  83.             trBody.addView(tvBody);  
  84.             tableLayout.addView(trBody, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));  
  85.         }  
  86.   
  87.         if (!cursor.isClosed()) {  
  88.             cursor.close();  
  89.             cursor = null;  
  90.         }  
  91.   
  92.         smsHander.closeSMSDatabase();  
  93.         index = 0;  
  94.     }  
  95.   
  96.     public class SmsHander {  
  97.   
  98.         SQLiteDatabase db;  
  99.         Context context;  
  100.   
  101.         public SmsHander(Context context) {  
  102.             this.context = context;  
  103.         }  
  104.   
  105.         public void createSMSDatabase() {  
  106.             String sql = "create table if not exists sms("  
  107.                     + "_id integer primary key autoincrement,"  
  108.                     + "address varchar(255)," + "person varchar(255),"  
  109.                     + "body varchar(1024)," + "date varchar(255),"  
  110.                     + "type integer)";  
  111.             db = SQLiteDatabase.openOrCreateDatabase(context.getFilesDir().toString() + "/data.db3"null);         // 创建数据库  
  112.             db.execSQL(sql);  
  113.         }  
  114.   
  115.         // 获取手机短信  
  116.         private Cursor getSMSInPhone() {  
  117.             Uri SMS_CONTENT = Uri.parse("content://sms/");  
  118.             String[] projection = new String[] { "_id""address""person""body""date""type" };  
  119.             Cursor cursor = context.getContentResolver().query(SMS_CONTENT, projection, nullnull"date desc");   // 获取手机短信  
  120.   
  121.             while (cursor.moveToNext()) {  
  122.                 System.out.println("--sms-- : " + cursor.getString(cursor.getColumnIndex("body")));  
  123.             }  
  124.   
  125.             return cursor;  
  126.         }  
  127.   
  128.         // 保存手机短信到 SQLite 数据库  
  129.         public void insertSMSToDatabase() {  
  130.             Long lastTime;  
  131.             Cursor dbCount = db.rawQuery("select count(*) from sms"null);  
  132.             dbCount.moveToFirst();  
  133.             if (dbCount.getInt(0) > 0) {  
  134.                 Cursor dbcur = db.rawQuery("select * from sms order by date desc limit 1"null);  
  135.                 dbcur.moveToFirst();  
  136.                 lastTime = Long.parseLong(dbcur.getString(dbcur.getColumnIndex("date")));  
  137.             } else {  
  138.                 lastTime = new Long(0);  
  139.             }  
  140.             dbCount.close();  
  141.             dbCount = null;  
  142.   
  143.             Cursor cur = getSMSInPhone(); // 获取短信(游标)  
  144.             db.beginTransaction(); // 开始事务处理  
  145.             if (cur.moveToFirst()) {  
  146.                 String address;  
  147.                 String person;  
  148.                 String body;  
  149.                 String date;  
  150.                 int type;  
  151.   
  152.                 int iAddress = cur.getColumnIndex("address");  
  153.                 int iPerson = cur.getColumnIndex("person");  
  154.                 int iBody = cur.getColumnIndex("body");  
  155.                 int iDate = cur.getColumnIndex("date");  
  156.                 int iType = cur.getColumnIndex("type");  
  157.   
  158.                 do {  
  159.                     address = cur.getString(iAddress);  
  160.                     person = cur.getString(iPerson);  
  161.                     body = cur.getString(iBody);  
  162.                     date = cur.getString(iDate);  
  163.                     type = cur.getInt(iType);  
  164.   
  165.                     if (Long.parseLong(date) > lastTime) {  
  166.                         String sql = "insert into sms values(null, ?, ?, ?, ?, ?)";  
  167.                         Object[] bindArgs = new Object[] { address, person, body, date, type };  
  168.                         db.execSQL(sql, bindArgs);  
  169.                     } else {  
  170.                         break;  
  171.                     }  
  172.                 } while (cur.moveToNext());  
  173.   
  174.                 cur.close();  
  175.                 cur = null;  
  176.                 db.setTransactionSuccessful();  // 设置事务处理成功,不设置会自动回滚不提交  
  177.                 db.endTransaction();            // 结束事务处理  
  178.             }  
  179.   
  180.         }  
  181.   
  182.         // 获取 SQLite 数据库中的全部短信  
  183.         public Cursor querySMSFromDatabase() {  
  184.             String sql = "select * from sms order by date desc";  
  185.             return db.rawQuery(sql, null);  
  186.         }  
  187.   
  188.         // 获取 SQLite 数据库中的最新 size 条短信  
  189.         public Cursor querySMSInDatabase(int size) {  
  190.             String sql;  
  191.   
  192.             Cursor dbCount = db.rawQuery("select count(*) from sms"null);  
  193.             dbCount.moveToFirst();  
  194.             if (size < dbCount.getInt(0)) { // 不足 size 条短信,则取前 size 条  
  195.                 sql = "select * from sms order by date desc limit " + size;  
  196.             } else {  
  197.                 sql = "select * from sms order by date desc";  
  198.             }  
  199.             dbCount.close();  
  200.             dbCount = null;  
  201.   
  202.             return db.rawQuery(sql, null);  
  203.         }  
  204.   
  205.         // 获取 SQLite数据库的前 second秒短信  
  206.         public Cursor getSMSInDatabaseFrom(long second) {  
  207.             long time = System.currentTimeMillis() / 1000 - second;  
  208.             String sql = "select * from sms order by date desc where date > " + time;  
  209.             return db.rawQuery(sql, null);  
  210.         }  
  211.   
  212.         // 关闭数据库  
  213.         public void closeSMSDatabase() {  
  214.             if (db != null && db.isOpen()) {  
  215.                 db.close();  
  216.                 db = null;  
  217.             }  
  218.         }  
  219.   
  220.     }  
  221. }  

运行结果:

代码示例

推荐参考:

Android 之 SMS 短信读取

抱歉!评论已关闭.