1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2008 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage android.telephony;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.RemoteException;
21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.ServiceManager;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.ISms;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccConstants;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsRawData;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.Arrays;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.List;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * TODO(code review): Curious question... Why are a lot of these
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * methods not declared as static, since they do not seem to require
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * any local object state?  Presumably this cannot be changed without
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * interfering with the API...
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Manages SMS operations such as sending data, text, and pdu SMS messages.
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Get this object by calling the static method SmsManager.getDefault().
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic final class SmsManager {
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Singleton object constructed during class initialization. */
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final SmsManager sInstance = new SmsManager();
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Send a text based SMS.
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param destinationAddress the address to send the message to
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param scAddress is the service center address or null to use
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  the current default SMSC
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param text the body of the message to send
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param sentIntent if not NULL this <code>PendingIntent</code> is
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  broadcast when the message is successfully sent, or failed.
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  The result code will be <code>Activity.RESULT_OK</code> for success,
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  or one of these errors:<br>
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  <code>RESULT_ERROR_NULL_PDU</code><br>
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  the extra "errorCode" containing a radio technology specific value,
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  generally only useful for troubleshooting.<br>
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  is NULL the caller will be checked against all unknown applications,
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  which cause smaller number of SMS to be sent in checking period.
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  broadcast when the message is delivered to the recipient.  The
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  raw pdu of the status report is in the extended data ("pdu").
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @throws IllegalArgumentException if destinationAddress or text are empty
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void sendTextMessage(
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String destinationAddress, String scAddress, String text,
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            PendingIntent sentIntent, PendingIntent deliveryIntent) {
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (TextUtils.isEmpty(destinationAddress)) {
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new IllegalArgumentException("Invalid destinationAddress");
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (TextUtils.isEmpty(text)) {
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new IllegalArgumentException("Invalid message body");
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent);
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Divide a message text into several fragments, none bigger than
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the maximum SMS message size.
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param text the original message.  Must not be null.
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return an <code>ArrayList</code> of strings that, in order,
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   comprise the original message
101910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks     *
102910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks     * @throws IllegalArgumentException if text is null
103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public ArrayList<String> divideMessage(String text) {
105910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        if (null == text) {
106910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks            throw new IllegalArgumentException("text is null");
107910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        }
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return SmsMessage.fragmentText(text);
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Send a multi-part text based SMS.  The callee should have already
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * divided the message into correctly sized parts by calling
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * <code>divideMessage</code>.
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param destinationAddress the address to send the message to
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param scAddress is the service center address or null to use
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   the current default SMSC
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param parts an <code>ArrayList</code> of strings that, in order,
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   comprise the original message
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param sentIntents if not null, an <code>ArrayList</code> of
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   broadcast when the corresponding message part has been sent.
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   The result code will be <code>Activity.RESULT_OK</code> for success,
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   or one of these errors:<br>
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   <code>RESULT_ERROR_RADIO_OFF</code><br>
128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   <code>RESULT_ERROR_NULL_PDU</code><br>
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include
130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   the extra "errorCode" containing a radio technology specific value,
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   generally only useful for troubleshooting.<br>
132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   The per-application based SMS control checks sentIntent. If sentIntent
133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   is NULL the caller will be checked against all unknown applications,
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   which cause smaller number of SMS to be sent in checking period.
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param deliveryIntents if not null, an <code>ArrayList</code> of
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   broadcast when the corresponding message part has been delivered
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   to the recipient.  The raw pdu of the status report is in the
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   extended data ("pdu").
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @throws IllegalArgumentException if destinationAddress or data are empty
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void sendMultipartTextMessage(
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String destinationAddress, String scAddress, ArrayList<String> parts,
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (TextUtils.isEmpty(destinationAddress)) {
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new IllegalArgumentException("Invalid destinationAddress");
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (parts == null || parts.size() < 1) {
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new IllegalArgumentException("Invalid message body");
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (parts.size() > 1) {
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            try {
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (iccISms != null) {
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    iccISms.sendMultipartText(destinationAddress, scAddress, parts,
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            sentIntents, deliveryIntents);
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } catch (RemoteException ex) {
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // ignore it
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            PendingIntent sentIntent = null;
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            PendingIntent deliveryIntent = null;
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (sentIntents != null && sentIntents.size() > 0) {
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sentIntent = sentIntents.get(0);
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (deliveryIntents != null && deliveryIntents.size() > 0) {
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                deliveryIntent = deliveryIntents.get(0);
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            sendTextMessage(destinationAddress, scAddress, parts.get(0),
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    sentIntent, deliveryIntent);
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Send a data based SMS to a specific application port.
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param destinationAddress the address to send the message to
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param scAddress is the service center address or null to use
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  the current default SMSC
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param destinationPort the port to deliver the message to
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param data the body of the message to send
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param sentIntent if not NULL this <code>PendingIntent</code> is
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  broadcast when the message is successfully sent, or failed.
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  The result code will be <code>Activity.RESULT_OK</code> for success,
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  or one of these errors:<br>
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  <code>RESULT_ERROR_NULL_PDU</code><br>
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  the extra "errorCode" containing a radio technology specific value,
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  generally only useful for troubleshooting.<br>
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  is NULL the caller will be checked against all unknown applications,
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  which cause smaller number of SMS to be sent in checking period.
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  broadcast when the message is delivered to the recipient.  The
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  raw pdu of the status report is in the extended data ("pdu").
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @throws IllegalArgumentException if destinationAddress or data are empty
203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void sendDataMessage(
205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String destinationAddress, String scAddress, short destinationPort,
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (TextUtils.isEmpty(destinationAddress)) {
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new IllegalArgumentException("Invalid destinationAddress");
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (data == null || data.length == 0) {
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new IllegalArgumentException("Invalid message data");
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                iccISms.sendData(destinationAddress, scAddress, destinationPort & 0xFFFF,
219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        data, sentIntent, deliveryIntent);
220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Get the default instance of the SmsManager
228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return the default instance of the SmsManager
230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static SmsManager getDefault() {
232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return sInstance;
233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private SmsManager() {
236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        //nothing
237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Copy a raw SMS PDU to the ICC.
241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * ICC (Integrated Circuit Card) is the card of the device.
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * For example, this can be the SIM or USIM for GSM.
243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param smsc the SMSC for this message, or NULL for the default SMSC
245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param pdu the raw PDU to store
246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for success
249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
250910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks     * @throws IllegalArgumentException if pdu is NULL
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean copyMessageToIcc(byte[] smsc, byte[] pdu, int status) {
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean success = false;
255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
256910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        if (null == pdu) {
257910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks            throw new IllegalArgumentException("pdu is NULL");
258910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        }
259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                success = iccISms.copyMessageToIccEf(status, pdu, smsc);
263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return success;
269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Delete the specified message from the ICC.
273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * ICC (Integrated Circuit Card) is the card of the device.
274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * For example, this can be the SIM or USIM for GSM.
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param messageIndex is the record index of the message on ICC
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for success
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    deleteMessageFromIcc(int messageIndex) {
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean success = false;
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte[] pdu = new byte[IccConstants.SMS_RECORD_LENGTH-1];
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Arrays.fill(pdu, (byte)0xff);
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                success = iccISms.updateMessageOnIccEf(messageIndex, STATUS_ON_ICC_FREE, pdu);
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return success;
297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Update the specified message on the ICC.
301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * ICC (Integrated Circuit Card) is the card of the device.
302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * For example, this can be the SIM or USIM for GSM.
303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param messageIndex record index of message to update
305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param newStatus new message status (STATUS_ON_ICC_READ,
306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param pdu the raw PDU to store
309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for success
310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) {
314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean success = false;
315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                success = iccISms.updateMessageOnIccEf(messageIndex, newStatus, pdu);
320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return success;
326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Retrieves all messages currently stored on ICC.
330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * ICC (Integrated Circuit Card) is the card of the device.
331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * For example, this can be the SIM or USIM for GSM.
332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public static ArrayList<SmsMessage> getAllMessagesFromIcc() {
338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        List<SmsRawData> records = null;
339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                records = iccISms.getAllMessagesFromIccEf();
344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return createMessageListFromRawRecords(records);
350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Enable reception of cell broadcast (SMS-CB) messages with the given
354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier. Note that if two different clients enable the same
355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier, they must both disable it for the device to stop
356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * receiving those messages. All received messages will be broadcast in an
357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Note: This call is blocking, callers may want to avoid calling it from
359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the main thread of an application.
360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param messageIdentifier Message identifier as specified in TS 23.041
362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true if successful, false otherwise
363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @see #disableCellBroadcast(int)
364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean enableCellBroadcast(int messageIdentifier) {
368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean success = false;
369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                success = iccISms.enableCellBroadcast(messageIdentifier);
374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return success;
380c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Disable reception of cell broadcast (SMS-CB) messages with the given
384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier. Note that if two different clients enable the same
385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier, they must both disable it for the device to stop
386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * receiving those messages.
387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Note: This call is blocking, callers may want to avoid calling it from
388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the main thread of an application.
389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param messageIdentifier Message identifier as specified in TS 23.041
391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true if successful, false otherwise
392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @see #enableCellBroadcast(int)
394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean disableCellBroadcast(int messageIdentifier) {
398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean success = false;
399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                success = iccISms.disableCellBroadcast(messageIdentifier);
404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return success;
410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Enable reception of cell broadcast (SMS-CB) messages with the given
414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier range. Note that if two different clients enable the same
415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier, they must both disable it for the device to stop
416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * receiving those messages. All received messages will be broadcast in an
417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Note: This call is blocking, callers may want to avoid calling it from
419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the main thread of an application.
420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param startMessageId first message identifier as specified in TS 23.041
422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param endMessageId last message identifier as specified in TS 23.041
423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true if successful, false otherwise
424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @see #disableCellBroadcastRange(int, int)
425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
426910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks     * @throws IllegalArgumentException if endMessageId < startMessageId
427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean success = false;
431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
432910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        if (endMessageId < startMessageId) {
433910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks            throw new IllegalArgumentException("endMessageId < startMessageId");
434910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        }
435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                success = iccISms.enableCellBroadcastRange(startMessageId, endMessageId);
439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return success;
445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Disable reception of cell broadcast (SMS-CB) messages with the given
449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier range. Note that if two different clients enable the same
450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * message identifier, they must both disable it for the device to stop
451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * receiving those messages.
452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Note: This call is blocking, callers may want to avoid calling it from
453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the main thread of an application.
454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param startMessageId first message identifier as specified in TS 23.041
456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param endMessageId last message identifier as specified in TS 23.041
457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true if successful, false otherwise
458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @see #enableCellBroadcastRange(int, int)
460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
461910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks     * @throws IllegalArgumentException if endMessageId < startMessageId
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@hide}
463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean success = false;
466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
467910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        if (endMessageId < startMessageId) {
468910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks            throw new IllegalArgumentException("endMessageId < startMessageId");
469910825a2ed10bd5cc454b91380b7db0dac2e616eRika Brooks        }
470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (iccISms != null) {
473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                success = iccISms.disableCellBroadcastRange(startMessageId, endMessageId);
474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RemoteException ex) {
476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // ignore it
477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return success;
480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Create a list of <code>SmsMessage</code>s from a list of RawSmsData
484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * records returned by <code>getAllMessagesFromIcc()</code>
485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param records SMS EF records, returned by
487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *   <code>getAllMessagesFromIcc</code>
488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (records != null) {
493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int count = records.size();
494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            for (int i = 0; i < count; i++) {
495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SmsRawData data = records.get(i);
496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // List contains all records, including "free" records (null)
497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (data != null) {
498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (sms != null) {
500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        messages.add(sms);
501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return messages;
506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // see SmsMessage.getStatusOnIcc
509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int STATUS_ON_ICC_FREE      = 0;
512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Received and read (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int STATUS_ON_ICC_READ      = 1;
515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Received and unread (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int STATUS_ON_ICC_UNREAD    = 3;
518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Stored and sent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int STATUS_ON_ICC_SENT      = 5;
521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Stored and unsent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int STATUS_ON_ICC_UNSENT    = 7;
524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // SMS send failure result codes
526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Generic failure cause */
528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int RESULT_ERROR_GENERIC_FAILURE    = 1;
529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Failed because radio was explicitly turned off */
530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int RESULT_ERROR_RADIO_OFF          = 2;
531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Failed because no pdu provided */
532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int RESULT_ERROR_NULL_PDU           = 3;
533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Failed because service is currently unavailable */
534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int RESULT_ERROR_NO_SERVICE         = 4;
535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Failed because we reached the sending queue limit.  {@hide} */
536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int RESULT_ERROR_LIMIT_EXCEEDED     = 5;
537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Failed because FDN is enabled. {@hide} */
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static public final int RESULT_ERROR_FDN_CHECK_FAILURE  = 6;
539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
540