Android解析メール情報

17201 ワード

最近、プロジェクトをして携帯電話のメールを解析します.メールを取得するには、2つの方法があります.1つは放送を通じて、もう1つはデータベースを通じて、プロジェクトが私が選択する必要があるのは2つ目の方法です.データベースを検索してメール情報を取得し、指定された内容を解析するメールです.
新しい機能を作るときは、まず関連する知識を調べて、demoがあるかどうかを見てみましょう.最後に、Androidアプリケーション層のソースコードを逆に見て、その中の定数の定義を見て、高バージョンのapiを使うことをお勧めします.必ずしも使用できるとは限りませんが、メールという機能を例に挙げます.
メールの情報を取得する以上、その各構成部分だけでandroidに入ります.jarの中のandroidprovider.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 CONTER_URI=Uri.parse("content://sms/inbox");SmsとTextBasedSmsColumnsインタフェースの内容をコピーしてそれぞれ2つのインタフェースの中に置いて自分の設定を命名しますが、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<SMSInfo> CREATOR = new Creator<SMSInfo>() {

		@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<SMSInfo> 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<SMSInfo>();
		this.mResolver = context.getContentResolver();
		this.context = context;
	}
	
	/**
	 *         
	 */
	public List<SMSInfo> 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;
	}
}
は、条件に合ったすべてのメールをリストに入れて読み、最後に条件を1つ1つ解析します.これは個人情報に関連しており、効果は表示されません.