Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android解析短信信息

Android解析短信信息

編輯:關於Android編程

最近做項目要解析手機中短信,獲取短信有兩種方式:一種是通過廣播另一種就是通過數據庫,由於項目需要我選擇的是第二種方式,檢索數據庫來獲取短信信息並且進行解析指定內容的短信。

在做任何一個新的功能的時候,我們首先查閱一下相關的知識,然後看看有沒有相關的demo,最後建議反過來看Android應用層源碼,看看它裡面的一些常量的定義,建議使用高版本的api,你不一定能夠使用它,但是它會給你指出一些思路,就拿短信這個功能為例:

既然我們要獲取短信的信息,那就要只要它的各個組成部分,我們進入到android.jar裡面中的android.provider.Telephony,我們可以看到Sms的相關的屬性。如果你調用這裡面的內容的話,會提示Field requires API level 19 (current min is ),但是這並不妨礙我們去模仿他, 我的需要是要檢索收件箱,所以搜索數據庫的時候,我只需要搜索收件箱裡面的短信,在Telephony中TextBasedSmsColumns接口裡面Message type根據需要我選擇的是MESSAGE_TYPE_INBOX,接下來我們看一下Sms這個接口:

/**
     * Contains all text-based SMS messages.
     */
    public static final class Sms implements BaseColumns, TextBasedSmsColumns {

        /**
         * Not instantiable.
         * @hide
         */
        private Sms() {
        }

        /**
         * Used to determine the currently configured default SMS package.
         * @param context context of the requesting application
         * @return package name for the default SMS package or null
         */
        public static String getDefaultSmsPackage(Context context) {
            ComponentName component = SmsApplication.getDefaultSmsApplication(context, false);
            if (component != null) {
                return component.getPackageName();
            }
            return null;
        }

        /**
         * Return cursor for table query.
         * @hide
         */
        public static Cursor query(ContentResolver cr, String[] projection) {
            return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
        }

        /**
         * Return cursor for table query.
         * @hide
         */
        public static Cursor query(ContentResolver cr, String[] projection,
                String where, String orderBy) {
            return cr.query(CONTENT_URI, projection, where,
                    null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
        }

        /**
         * The {@code content://} style URL for this table.
         */
        public static final Uri CONTENT_URI = Uri.parse("content://sms");

        /**
         * The default sort order for this table.
         */
        public static final String DEFAULT_SORT_ORDER = "date DESC";

        /**
         * Add an SMS to the given URI.
         *
         * @param resolver the content resolver to use
         * @param uri the URI to add the message to
         * @param address the address of the sender
         * @param body the body of the message
         * @param subject the pseudo-subject of the message
         * @param date the timestamp for the message
         * @param read true if the message has been read, false if not
         * @param deliveryReport true if a delivery report was requested, false if not
         * @return the URI for the new message
         * @hide
         */
        public static Uri addMessageToUri(ContentResolver resolver,
                Uri uri, String address, String body, String subject,
                Long date, boolean read, boolean deliveryReport) {
            return addMessageToUri(resolver, uri, address, body, subject,
                    date, read, deliveryReport, -1L);
        }

        /**
         * Add an SMS to the given URI with the specified thread ID.
         *
         * @param resolver the content resolver to use
         * @param uri the URI to add the message to
         * @param address the address of the sender
         * @param body the body of the message
         * @param subject the pseudo-subject of the message
         * @param date the timestamp for the message
         * @param read true if the message has been read, false if not
         * @param deliveryReport true if a delivery report was requested, false if not
         * @param threadId the thread_id of the message
         * @return the URI for the new message
         * @hide
         */
        public static Uri addMessageToUri(ContentResolver resolver,
                Uri uri, String address, String body, String subject,
                Long date, boolean read, boolean deliveryReport, long threadId) {
            ContentValues values = new ContentValues(7);

            values.put(ADDRESS, address);
            if (date != null) {
                values.put(DATE, date);
            }
            values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
            values.put(SUBJECT, subject);
            values.put(BODY, body);
            if (deliveryReport) {
                values.put(STATUS, STATUS_PENDING);
            }
            if (threadId != -1L) {
                values.put(THREAD_ID, threadId);
            }
            return resolver.insert(uri, values);
        }

        /**
         * Move a message to the given folder.
         *
         * @param context the context to use
         * @param uri the message to move
         * @param folder the folder to move to
         * @return true if the operation succeeded
         * @hide
         */
        public static boolean moveMessageToFolder(Context context,
                Uri uri, int folder, int error) {
            if (uri == null) {
                return false;
            }

            boolean markAsUnread = false;
            boolean markAsRead = false;
            switch(folder) {
            case MESSAGE_TYPE_INBOX:
            case MESSAGE_TYPE_DRAFT:
                break;
            case MESSAGE_TYPE_OUTBOX:
            case MESSAGE_TYPE_SENT:
                markAsRead = true;
                break;
            case MESSAGE_TYPE_FAILED:
            case MESSAGE_TYPE_QUEUED:
                markAsUnread = true;
                break;
            default:
                return false;
            }

            ContentValues values = new ContentValues(3);

            values.put(TYPE, folder);
            if (markAsUnread) {
                values.put(READ, 0);
            } else if (markAsRead) {
                values.put(READ, 1);
            }
            values.put(ERROR_CODE, error);

            return 1 == SqliteWrapper.update(context, context.getContentResolver(),
                            uri, values, null, null);
        }

        /**
         * Returns true iff the folder (message type) identifies an
         * outgoing message.
         * @hide
         */
        public static boolean isOutgoingFolder(int messageType) {
            return  (messageType == MESSAGE_TYPE_FAILED)
                    || (messageType == MESSAGE_TYPE_OUTBOX)
                    || (messageType == MESSAGE_TYPE_SENT)
                    || (messageType == MESSAGE_TYPE_QUEUED);
        }

裡面給出了查詢功能和添加功能,由於我只需要查詢功能,但是裡面public static final Uri CONTENT_URI = Uri.parse("content://sms");說明查詢的是所有的短信,而我只要查詢收件箱裡面的,所以上面這就話改成public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");把Sms和TextBasedSmsColumns接口的內容拷貝出來分別放在兩個接口裡面命名自己設置,而Sms裡面會有一些報錯,有些我們引用了系統不開放的方法,把不相關的代碼進行刪除,整理後的代碼如下:

package com.jwzhangjie.smarttv_client.support.sms1;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;

public final class Sms implements BaseColumns, TextBasedSmsColumns{
	 /**
     * Not instantiable.
     * @hide
     */
    private Sms() {
    }


    /**
     * Return cursor for table query.
     * @hide
     */
    public static Cursor query(ContentResolver cr, String[] projection) {
        return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
    }

    /**
     * Return cursor for table query.
     * @hide
     */
    public static Cursor query(ContentResolver cr, String[] projection,
            String where, String orderBy) {
        return cr.query(CONTENT_URI, projection, where,
                null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
    }

    /**
     * The {@code content://} style URL for this table.
     */
//    public static final Uri CONTENT_URI = Uri.parse("content://sms");
    public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");

    /**
     * The default sort order for this table.
     */
    public static final String DEFAULT_SORT_ORDER = "date DESC";

    /**
     * Add an SMS to the given URI.
     *
     * @param resolver the content resolver to use
     * @param uri the URI to add the message to
     * @param address the address of the sender
     * @param body the body of the message
     * @param subject the pseudo-subject of the message
     * @param date the timestamp for the message
     * @param read true if the message has been read, false if not
     * @param deliveryReport true if a delivery report was requested, false if not
     * @return the URI for the new message
     * @hide
     */
    public static Uri addMessageToUri(ContentResolver resolver,
            Uri uri, String address, String body, String subject,
            Long date, boolean read, boolean deliveryReport) {
        return addMessageToUri(resolver, uri, address, body, subject,
                date, read, deliveryReport, -1L);
    }

    /**
     * Add an SMS to the given URI with the specified thread ID.
     *
     * @param resolver the content resolver to use
     * @param uri the URI to add the message to
     * @param address the address of the sender
     * @param body the body of the message
     * @param subject the pseudo-subject of the message
     * @param date the timestamp for the message
     * @param read true if the message has been read, false if not
     * @param deliveryReport true if a delivery report was requested, false if not
     * @param threadId the thread_id of the message
     * @return the URI for the new message
     * @hide
     */
    public static Uri addMessageToUri(ContentResolver resolver,
            Uri uri, String address, String body, String subject,
            Long date, boolean read, boolean deliveryReport, long threadId) {
        ContentValues values = new ContentValues(7);

        values.put(ADDRESS, address);
        if (date != null) {
            values.put(DATE, date);
        }
        values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
        values.put(SUBJECT, subject);
        values.put(BODY, body);
        if (deliveryReport) {
            values.put(STATUS, STATUS_PENDING);
        }
        if (threadId != -1L) {
            values.put(THREAD_ID, threadId);
        }
        return resolver.insert(uri, values);
    }

    /**
     * Returns true iff the folder (message type) identifies an
     * outgoing message.
     * @hide
     */
    public static boolean isOutgoingFolder(int messageType) {
        return  (messageType == MESSAGE_TYPE_FAILED)
                || (messageType == MESSAGE_TYPE_OUTBOX)
                || (messageType == MESSAGE_TYPE_SENT)
                || (messageType == MESSAGE_TYPE_QUEUED);
}
}


上面的代碼不會有錯誤,查詢功能有了之後,我們還要寫一個保存查詢出來的內容的類,根據自己的項目編寫,例如:

package com.jwzhangjie.smarttv_client.support.sms1;
/**
 * 數據庫中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
 */
import android.os.Parcel;
import android.os.Parcelable;
/**
 * 保存短息信息
 * @author jwzhangjie
 *
 */
public class SMSInfo implements Parcelable{

	@Override
	public int describeContents() {
		return 0;
	}
	
	/**
	 * 短信序號
	 */
	private long id;
	/**
	 * 協議 0:SMS_PROTO 短信 1:MMS_PROTO彩信
	 */
	private int protocol;
	/**
	 * 短信內容
	 */
	private String smsBody;
	/**
	 * 發送短息的電話號碼
	 */
	private String smsPhoneNum;
	/**
	 * 發送短信的日期和時間
	 */
	private String smsDateTime;
	/**
	 * 發送短信人
	 */
	private String smsSender;
	/**
	 * 短信類型:1是接收到的 2是已發送的
	 */
	private int smsType;
	
	public SMSInfo(){
		
	}
	
	private SMSInfo(Parcel source){
		readFromParcel(source);
	}
	
	public void readFromParcel(Parcel source){
		id = source.readLong();
		protocol = source.readInt();
		smsBody = source.readString();
		smsPhoneNum = source.readString();
		smsDateTime = source.readString();
		smsSender = source.readString();
		smsType = source.readInt();
	}
	
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeLong(id);
		dest.writeInt(protocol);
		dest.writeString(smsBody);
		dest.writeString(smsPhoneNum);
		dest.writeString(smsDateTime);
		dest.writeString(smsSender);
		dest.writeInt(smsType);
	}
	
	public static Creator CREATOR = new Creator() {

		@Override
		public SMSInfo createFromParcel(Parcel source) {
			return new SMSInfo(source);
		}

		@Override
		public SMSInfo[] newArray(int size) {
			return new SMSInfo[size];
		}
	};

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("id :"+id+"  協議:"+protocol+"  內容:"+smsBody);
		return builder.toString();
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public int getProtocol() {
		return protocol;
	}

	public void setProtocol(int protocol) {
		this.protocol = protocol;
	}

	public String getSmsBody() {
		return smsBody;
	}

	public void setSmsBody(String smsBody) {
		this.smsBody = smsBody;
	}

	public String getSmsPhoneNum() {
		return smsPhoneNum;
	}

	public void setSmsPhoneNum(String smsPhoneNum) {
		this.smsPhoneNum = smsPhoneNum;
	}

	public String getSmsDateTime() {
		return smsDateTime;
	}

	public void setSmsDateTime(String smsDateTime) {
		this.smsDateTime = smsDateTime;
	}

	public String getSmsSender() {
		return smsSender;
	}

	public void setSmsSender(String smsSender) {
		this.smsSender = smsSender;
	}

	public int getSmsType() {
		return smsType;
	}

	public void setSmsType(int smsType) {
		this.smsType = smsType;
	}
	
}


接下來就是獲取數據庫內容,我們先看一下查詢數據庫的方法:

 /**
     * Return cursor for table query.
     * @hide
     */
    public static Cursor query(ContentResolver cr, String[] projection,
            String where, String orderBy) {
        return cr.query(CONTENT_URI, projection, where,
                null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
    }


CONTENT_URI:就是我們上面定義的public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");

projection:這個可以是null,那就是把所有的列都獲取出來,不過不必,你需要什麼就獲取什麼,不然既浪費時間又浪費內存

where:查詢條件

orderBy:排序

package com.jwzhangjie.smarttv_client.support.sms1;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;

public class GetSMSInfo {
	private ContentResolver mResolver;
	private Context context;
	private List infos;
	
	private static final String[] PROJECTION = new String[]{
		Sms._ID,//0:作為一個標志位,記錄最後一個,作為下一次掃描的第一個
		Sms.TYPE,//1:收還是發
		Sms.ADDRESS,//2手機號
		Sms.BODY,//3內容
		Sms.DATE,//4日期
		Sms.PROTOCOL//5協議
	};
	
	public static final int COLUMN_INDEX_ID = 0;
	public static final int COLUMN_INDEX_TYPE  = 1;
        public static final int COLUMN_INDEX_PHONE = 2;
        public static final int COLUMN_INDEX_BODY  = 3;
        public static final int COLUMN_INDEX_DATE = 4;
        public static final int COLUMN_INDEX_PROTOCOL = 5;
	
	public GetSMSInfo(Context context){
		this.infos = new ArrayList();
		this.mResolver = context.getContentResolver();
		this.context = context;
	}
	
	/**
	 * 獲取短信各種信息
	 */
	public List getSmsInfo(){
		//獲取上一次檢索的最後一個ID
		long last_sms_id = UPSharedPreferences.getLong(context, "card", "last_sms_id", 0);
		Cursor cursor = Sms.query(mResolver, PROJECTION, "_id >" + last_sms_id, "_id");
		int protocol;
		String body, date;
		if (cursor != null) {
			while (cursor.moveToNext()) {
				last_sms_id = cursor.getLong(COLUMN_INDEX_ID);
				body = cursor.getString(COLUMN_INDEX_BODY);
				date = cursor.getString(COLUMN_INDEX_DATE);
				protocol = cursor.getInt(COLUMN_INDEX_PROTOCOL);
				if (protocol == 0) {//收信息
					SMSInfo info = new SMSInfo();
					info.setId(last_sms_id);
					info.setSmsBody(body);
					info.setSmsDateTime(date);
					infos.add(info);
				}
			}
			cursor.close();
		}
		//保存當前最新的ID
		UPSharedPreferences.setLong(context, "card", "last_sms_id", last_sms_id);
		return infos;
	}
}
讀取得所有符合條件的短信都放在List裡面,然後我們最後解析條件一個一個解析,這個涉及一些私人信息,就不顯示效果了。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved