Android実戦テクニックの三十九:メール送受信


7月4日に広州から出張から帰ってきてから執筆計画を立てたが、なかなか筆を執らなかった.遅れた原因は相変わらずで、仕事には新しい任務があり、すべての精力が投入され、毎日疲れ果てて帰ってきても他のことをする元気がありません.これは精力管理が不適切なためで、私が多くのしなければならないことを非情に“時間があることを待っています”に置いて更にするようです.今晩、私は必ず自分に1つを渡します.文章がどう書いても、ペンを動かさないと永遠にゼロです.
本文は下にあります
Androidの携帯電話機能(通話とメール)はandroidに置かれてきた.telephonyパッケージでは、4.4時(API 19)android.provider.Telephonyおよび関連類の横空出世補助電話機能およびアンドロイド世界の携帯電話機能の新しい秩序を制定する.私たちのメール機能はSmsManagerとSmsMessageの2つの主要クラスを使用しています.
メール送信via Intent
万能のintentは私たちに多くのことをすることができて、あなたが“意図”があればそれはあなたを満たすことができます.
    private void sendMessageViaSystem() {
        Uri uri = Uri.parse("smsto:"+etNumber.getText());
        Intent intent = new Intent(Intent.ACTION_VIEW,uri);
        intent.putExtra("sms_body",etMessage.getText().toString());
//        intent.setType("rnd");
        startActivity(intent);
    }

メール送信via SmsManager
    private void sendMessage() {        
        SmsManager smsManager = SmsManager.getDefault();
        smsManager.sendTextMessage(etNumber.getText().toString(), null,
                etMessage.getText().toString(), null, null);
    }

最も簡単なメール送信条件は、電話番号とメール内容があり、SmsManagerのsendTextMessageメソッドを呼び出すことです.
傍受メールの送信状態
sendTextMessageメソッドの後の2つのパラメータはPendingIntentであり、関数のプロトタイプは以下の通りである.
     * @param sentIntent if not NULL this <code>PendingIntent</code> is
     *  broadcast when the message is successfully sent, or failed.
     *  The result code will be <code>Activity.RESULT_OK</code> for success,
     *  or one of these errors:<br>
     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
     *  <code>RESULT_ERROR_NULL_PDU</code><br>
     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
     *  the extra "errorCode" containing a radio technology specific value,
     *  generally only useful for troubleshooting.<br>
     *  The per-application based SMS control checks sentIntent. If sentIntent
     *  is NULL the caller will be checked against all unknown applications,
     *  which cause smaller number of SMS to be sent in checking period.
     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
     *  broadcast when the message is delivered to the recipient.  The
     *  raw pdu of the status report is in the extended data ("pdu").
    public void sendTextMessage(
            String destinationAddress, String scAddress, String text,
            PendingIntent sentIntent, PendingIntent deliveryIntent) 

送信ステータスをリスニングするには、この2つのパラメータを使用します.この2つのPendingIntentには、送信中のステータスブロードキャストを受信する2つのBroadcast Receiverが接続されています.上記のパラメータで説明したように.コードの例は次のとおりです.
    private String SMS_SEND_ACTIOIN = "SMS_SEND";
    private String SMS_DELIVERED_ACTION = "SMS_DELIVERED";

    private SmsStatusReceiver mSmsStatusReceiver;
    private SmsDeliveryStatusReceiver mSmsDeliveryStatusReceiver;

    @Override
    protected void onResume() {
        super.onResume();
        mSmsStatusReceiver = new SmsStatusReceiver();
        registerReceiver(mSmsStatusReceiver,new IntentFilter(SMS_SEND_ACTIOIN));

        mSmsDeliveryStatusReceiver = new SmsDeliveryStatusReceiver();
        registerReceiver(mSmsDeliveryStatusReceiver,new IntentFilter(SMS_DELIVERED_ACTION));
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mSmsStatusReceiver);
        unregisterReceiver(mSmsDeliveryStatusReceiver);
    }

    private void sendMessage() {        
        SmsManager smsManager = SmsManager.getDefault();
        PendingIntent sentIntent = PendingIntent.getBroadcast(this, 0, new Intent(SMS_SEND_ACTIOIN), 0);
        PendingIntent deliveryIntent = PendingIntent.getBroadcast(this, 0,
                new Intent(SMS_DELIVERED_ACTION), 0);
        smsManager.sendTextMessage(etNumber.getText().toString(), null,
                etMessage.getText().toString(), sentIntent, deliveryIntent);
        Log.d(TAG,"sent message.");
    }

    public class SmsStatusReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG,"SmsStatusReceiver onReceive.");
            switch(getResultCode()) {
                case Activity.RESULT_OK:
                    Log.d(TAG, "Activity.RESULT_OK");
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Log.d(TAG, "RESULT_ERROR_GENERIC_FAILURE");
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Log.d(TAG, "RESULT_ERROR_NO_SERVICE");
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Log.d(TAG, "RESULT_ERROR_NULL_PDU");
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Log.d(TAG, "RESULT_ERROR_RADIO_OFF");
                    break;
            }
        }
    }

    public class SmsDeliveryStatusReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG,"SmsDeliveryStatusReceiver onReceive.");
            switch(getResultCode()) {
                case Activity.RESULT_OK:
                    Log.i(TAG, "RESULT_OK");
                    break;
                case Activity.RESULT_CANCELED:
                    Log.i(TAG, "RESULT_CANCELED");
                    break;
            }
        }
    }

メール受信
送信状態傍受と同様に,メールの受信もブロードキャスト受信機を用いる.メール放送の受信を続けるために、Manifestに放送を登録する方法を採用しました.
        <receiver android:name="com.linc.intercept.SmsReceiver" >
            <intent-filter android:priority="1000" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

また、メール受信クラスとして1つの個別クラスが用いられる(このような方法では内部クラスに配置できない).
package com.linc.intercept;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;

/** * Created by linc on 15-7-12. */
public class SmsReceiver extends BroadcastReceiver {
    private static final String TAG = "SmsReceiver";
    public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Log.d(TAG,"action: "+action);
        if (SMS_RECEIVED_ACTION.equals(action)) {
            Bundle bundle = intent.getExtras();
            StringBuffer messageContent = new StringBuffer();
            if (bundle != null) {
                Object[] pdus = (Object[]) bundle.get("pdus");
                for (Object pdu : pdus) {
                    SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
                    String sender = message.getOriginatingAddress();
                    Log.d(TAG,"sender: "+sender);
                    if ("10086".equals(sender) || "10010".equals(sender) ||
                            "10001".equals(sender)) {
                        messageContent.append(message.getMessageBody());
                    }
                }
                if(!messageContent.toString().isEmpty()) {
                    Log.d(TAG,"send message broadcast.");
                    Intent intentBroadcast = new Intent();
                    intentBroadcast.putExtra("message", messageContent.toString());
                    intentBroadcast.setAction("sms_received");
                    context.sendBroadcast(intentBroadcast);
                    Log.d(TAG, "send broadcast and abort");
// abortBroadcast();
                }
            }
        }
    }
}

しかし、このような弊害は、受信したメールがどのようにインタフェースに表示されるかということです.道がいくつかあって、私は最後にラジオを選んだ.
    private SmsReceiver mSmsReceiver;
        @Override
    protected void onResume() {
        super.onResume();
        mSmsReceiver = new SmsReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("sms_received");
        registerReceiver(mSmsReceiver, intentFilter);
    }
        @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mSmsReceiver);
    }
    public class SmsReceiver extends BroadcastReceiver {
        public static final String SMS_RECEIVED_ACTION = "sms_received";

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG,"action: "+action);
            if (SMS_RECEIVED_ACTION.equals(action)) {
                Bundle bundle = intent.getExtras();

                String messageContent = bundle.getString("message");
                tvMessage.setText(messageContent);
            }
        }
    }

デバッグtip
私は本体でデバッグする傾向があり、運営者にメールを送ることができ、費用の問題を心配する必要はありません.移動番号:10086内容:119などの一連の消費を照会するコード連通番号:10010内容:101当月費用;102使用可能残高103先月の請求書...電気通信番号:10001内容:101リアルタイム費用;102口座残高...