안드로이드 실전 기교의 39:문자 수발

7월 4일 광저우에서 출장을 다녀온 후 작문 계획을 세웠지만 꾸물거리며 붓을 대지 않았다.지체한 원인은 여전하고 업무에 또 새로운 임무가 있어서 모든 정력을 다 쏟았고 매일 기진맥진하게 돌아와도 다른 일을 할 정신을 차리지 못했다.이것이 바로 정력 관리가 부적절한 탓이다. 마치 내가 해야 할 많은 일을 무자비하게 시간을 두고 하는 것과 같다.오늘 밤 나는 반드시 나 자신에게 맡길 것이다.글을 어떻게 쓰든지 간에 붓을 대지 않으면 영원히 제로이다.
본문은 아래에 있다
지금까지 안드로이드의 휴대전화 기능(통화와 문자)은 모두 안드로이드에 놓여 있다.telephony 가방에서 4.4시(즉 API19)android가 왔습니다.provider.텔레포니 및 관련 분야 횡공출세 보조전화 기능 및 안드로이드 세계 휴대전화 기능의 새로운 질서 제정.SmsManager와 SmsMessage 두 가지 주요 카테고리가 사용됩니다.
문자 보내기
만능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 메서드의 다음 두 매개변수는 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) 

우리가 송신 상태를 감청하려면 이 두 파라미터가 필요하다.이 두 Pending Intent와 연결된 두 개의 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;
            }
        }
    }

문자 수신
송신 상태 감청과 유사하게 문자 수신도 방송 수신기로 한다.문자 방송의 수신을 계속하기 위해 매니페스트에 방송을 등록하는 방법을 사용했다.
        <receiver android:name="com.linc.intercept.SmsReceiver" >
            <intent-filter android:priority="1000" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

또한 하나의 단독 클래스를 문자 수신 클래스로 한다(이런 방식은 내부 클래스에 넣을 수 없다).
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 계좌 잔액...

좋은 웹페이지 즐겨찾기