ArrayList
of strings that, in order,
* comprise the original msg text
*
* @hide
*/
public static ArrayListSubmitPdu
containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
*/
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message, boolean statusReportRequested) {
return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested,
SubscriptionManager.getDefaultSmsSubscriptionId());
}
/**
* Get an SMS-SUBMIT PDU for a destination address and a message.
* This method will not attempt to use any GSM national language 7 bit encodings.
*
* @param scAddress Service Centre address. Null means use default.
* @param destinationAddress the address of the destination for the message.
* @param message String representation of the message payload.
* @param statusReportRequested Indicates whether a report is requested for this message.
* @param subId Subscription of the message
* @return a SubmitPdu
containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
* @hide
*/
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message, boolean statusReportRequested, int subId) {
SubmitPduBase spb;
if (useCdmaFormatForMoSms(subId)) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested, null);
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested);
}
return new SubmitPdu(spb);
}
/**
* Get an SMS-SUBMIT PDU for a data message to a destination address & port.
* This method will not attempt to use any GSM national language 7 bit encodings.
*
* @param scAddress Service Centre address. null == use default
* @param destinationAddress the address of the destination for the message
* @param destinationPort the port to deliver the message to at the
* destination
* @param data the data for the message
* @return a SubmitPdu
containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
*/
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, short destinationPort, byte[] data,
boolean statusReportRequested) {
SubmitPduBase spb;
if (useCdmaFormatForMoSms()) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, destinationPort, data, statusReportRequested);
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, destinationPort, data, statusReportRequested);
}
return new SubmitPdu(spb);
}
/**
* Returns the address of the SMS service center that relayed this message
* or null if there is none.
*/
public String getServiceCenterAddress() {
return mWrappedSmsMessage.getServiceCenterAddress();
}
/**
* Returns the originating address (sender) of this SMS message in String
* form or null if unavailable.
*
* If the address is a GSM-formatted address, it will be in a format specified by 3GPP
* 23.040 Sec 9.1.2.5. If it is a CDMA address, it will be a format specified by 3GPP2
* C.S005-D Table 2.7.1.3.2.4-2. The choice of format is carrier-specific, so callers of the
* should be careful to avoid assumptions about the returned content.
*
* @return a String representation of the address; null if unavailable.
*/
@Nullable
public String getOriginatingAddress() {
return mWrappedSmsMessage.getOriginatingAddress();
}
/**
* Returns the originating address, or email from address if this message
* was from an email gateway. Returns null if originating address
* unavailable.
*/
public String getDisplayOriginatingAddress() {
return mWrappedSmsMessage.getDisplayOriginatingAddress();
}
/**
* Returns the message body as a String, if it exists and is text based.
* @return message body is there is one, otherwise null
*/
public String getMessageBody() {
return mWrappedSmsMessage.getMessageBody();
}
/**
* Returns the class of this message.
*/
public MessageClass getMessageClass() {
switch(mWrappedSmsMessage.getMessageClass()) {
case CLASS_0: return MessageClass.CLASS_0;
case CLASS_1: return MessageClass.CLASS_1;
case CLASS_2: return MessageClass.CLASS_2;
case CLASS_3: return MessageClass.CLASS_3;
default: return MessageClass.UNKNOWN;
}
}
/**
* Returns the message body, or email message body if this message was from
* an email gateway. Returns null if message body unavailable.
*/
public String getDisplayMessageBody() {
return mWrappedSmsMessage.getDisplayMessageBody();
}
/**
* Unofficial convention of a subject line enclosed in parens empty string
* if not present
*/
public String getPseudoSubject() {
return mWrappedSmsMessage.getPseudoSubject();
}
/**
* Returns the service centre timestamp in currentTimeMillis() format
*/
public long getTimestampMillis() {
return mWrappedSmsMessage.getTimestampMillis();
}
/**
* Returns true if message is an email.
*
* @return true if this message came through an email gateway and email
* sender / subject / parsed body are available
*/
public boolean isEmail() {
return mWrappedSmsMessage.isEmail();
}
/**
* @return if isEmail() is true, body of the email sent through the gateway.
* null otherwise
*/
public String getEmailBody() {
return mWrappedSmsMessage.getEmailBody();
}
/**
* @return if isEmail() is true, email from address of email sent through
* the gateway. null otherwise
*/
public String getEmailFrom() {
return mWrappedSmsMessage.getEmailFrom();
}
/**
* Get protocol identifier.
*/
public int getProtocolIdentifier() {
return mWrappedSmsMessage.getProtocolIdentifier();
}
/**
* See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
* SMS
*/
public boolean isReplace() {
return mWrappedSmsMessage.isReplace();
}
/**
* Returns true for CPHS MWI toggle message.
*
* @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
* B.4.2
*/
public boolean isCphsMwiMessage() {
return mWrappedSmsMessage.isCphsMwiMessage();
}
/**
* returns true if this message is a CPHS voicemail / message waiting
* indicator (MWI) clear message
*/
public boolean isMWIClearMessage() {
return mWrappedSmsMessage.isMWIClearMessage();
}
/**
* returns true if this message is a CPHS voicemail / message waiting
* indicator (MWI) set message
*/
public boolean isMWISetMessage() {
return mWrappedSmsMessage.isMWISetMessage();
}
/**
* returns true if this message is a "Message Waiting Indication Group:
* Discard Message" notification and should not be stored.
*/
public boolean isMwiDontStore() {
return mWrappedSmsMessage.isMwiDontStore();
}
/**
* returns the user data section minus the user data header if one was
* present.
*/
public byte[] getUserData() {
return mWrappedSmsMessage.getUserData();
}
/**
* Returns the raw PDU for the message.
*
* @return the raw PDU for the message.
*/
public byte[] getPdu() {
return mWrappedSmsMessage.getPdu();
}
/**
* Returns the status of the message on the SIM (read, unread, sent, unsent).
*
* @return the status of the message on the SIM. These are:
* SmsManager.STATUS_ON_SIM_FREE
* SmsManager.STATUS_ON_SIM_READ
* SmsManager.STATUS_ON_SIM_UNREAD
* SmsManager.STATUS_ON_SIM_SEND
* SmsManager.STATUS_ON_SIM_UNSENT
* @deprecated Use getStatusOnIcc instead.
*/
@Deprecated public int getStatusOnSim() {
return mWrappedSmsMessage.getStatusOnIcc();
}
/**
* Returns the status of the message on the ICC (read, unread, sent, unsent).
*
* @return the status of the message on the ICC. These are:
* SmsManager.STATUS_ON_ICC_FREE
* SmsManager.STATUS_ON_ICC_READ
* SmsManager.STATUS_ON_ICC_UNREAD
* SmsManager.STATUS_ON_ICC_SEND
* SmsManager.STATUS_ON_ICC_UNSENT
*/
public int getStatusOnIcc() {
return mWrappedSmsMessage.getStatusOnIcc();
}
/**
* Returns the record index of the message on the SIM (1-based index).
* @return the record index of the message on the SIM, or -1 if this
* SmsMessage was not created from a SIM SMS EF record.
* @deprecated Use getIndexOnIcc instead.
*/
@Deprecated public int getIndexOnSim() {
return mWrappedSmsMessage.getIndexOnIcc();
}
/**
* Returns the record index of the message on the ICC (1-based index).
* @return the record index of the message on the ICC, or -1 if this
* SmsMessage was not created from a ICC SMS EF record.
*/
public int getIndexOnIcc() {
return mWrappedSmsMessage.getIndexOnIcc();
}
/**
* GSM:
* For an SMS-STATUS-REPORT message, this returns the status field from
* the status report. This field indicates the status of a previously
* submitted SMS, if requested. See TS 23.040, 9.2.3.15 TP-Status for a
* description of values.
* CDMA:
* For not interfering with status codes from GSM, the value is
* shifted to the bits 31-16.
* The value is composed of an error class (bits 25-24) and a status code (bits 23-16).
* Possible codes are described in C.S0015-B, v2.0, 4.5.21.
*
* @return 0 indicates the previously sent message was received.
* See TS 23.040, 9.9.2.3.15 and C.S0015-B, v2.0, 4.5.21
* for a description of other possible values.
*/
public int getStatus() {
return mWrappedSmsMessage.getStatus();
}
/**
* Return true iff the message is a SMS-STATUS-REPORT message.
*/
public boolean isStatusReportMessage() {
return mWrappedSmsMessage.isStatusReportMessage();
}
/**
* Returns true iff the TP-Reply-Path
bit is set in
* this message.
*/
public boolean isReplyPathPresent() {
return mWrappedSmsMessage.isReplyPathPresent();
}
/**
* Determines whether or not to use CDMA format for MO SMS.
* If SMS over IMS is supported, then format is based on IMS SMS format,
* otherwise format is based on current phone type.
*
* @return true if Cdma format should be used for MO SMS, false otherwise.
*/
private static boolean useCdmaFormatForMoSms() {
// IMS is registered with SMS support, check the SMS format supported
return useCdmaFormatForMoSms(SubscriptionManager.getDefaultSmsSubscriptionId());
}
/**
* Determines whether or not to use CDMA format for MO SMS.
* If SMS over IMS is supported, then format is based on IMS SMS format,
* otherwise format is based on current phone type.
*
* @param subId Subscription for which phone type is returned.
*
* @return true if Cdma format should be used for MO SMS, false otherwise.
*/
private static boolean useCdmaFormatForMoSms(int subId) {
SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
if (!smsManager.isImsSmsSupported()) {
// use Voice technology to determine SMS format.
return isCdmaVoice(subId);
}
// IMS is registered with SMS support, check the SMS format supported
return (SmsConstants.FORMAT_3GPP2.equals(smsManager.getImsSmsFormat()));
}
/**
* Determines whether or not to current phone type is cdma.
*
* @return true if current phone type is cdma, false otherwise.
*/
private static boolean isCdmaVoice() {
return isCdmaVoice(SubscriptionManager.getDefaultSmsSubscriptionId());
}
/**
* Determines whether or not to current phone type is cdma
*
* @return true if current phone type is cdma, false otherwise.
*/
private static boolean isCdmaVoice(int subId) {
int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(subId);
return (PHONE_TYPE_CDMA == activePhone);
}
/**
* Decide if the carrier supports long SMS.
* {@hide}
*/
public static boolean hasEmsSupport() {
if (!isNoEmsSupportConfigListExisted()) {
return true;
}
String simOperator;
String gid;
final long identity = Binder.clearCallingIdentity();
try {
simOperator = TelephonyManager.getDefault().getSimOperatorNumeric();
gid = TelephonyManager.getDefault().getGroupIdLevel1();
} finally {
Binder.restoreCallingIdentity(identity);
}
if (!TextUtils.isEmpty(simOperator)) {
for (NoEmsSupportConfig currentConfig : mNoEmsSupportConfigList) {
if (simOperator.startsWith(currentConfig.mOperatorNumber) &&
(TextUtils.isEmpty(currentConfig.mGid1) ||
(!TextUtils.isEmpty(currentConfig.mGid1) &&
currentConfig.mGid1.equalsIgnoreCase(gid)))) {
return false;
}
}
}
return true;
}
/**
* Check where to add " x/y" in each SMS segment, begin or end.
* {@hide}
*/
public static boolean shouldAppendPageNumberAsPrefix() {
if (!isNoEmsSupportConfigListExisted()) {
return false;
}
String simOperator;
String gid;
final long identity = Binder.clearCallingIdentity();
try {
simOperator = TelephonyManager.getDefault().getSimOperatorNumeric();
gid = TelephonyManager.getDefault().getGroupIdLevel1();
} finally {
Binder.restoreCallingIdentity(identity);
}
for (NoEmsSupportConfig currentConfig : mNoEmsSupportConfigList) {
if (simOperator.startsWith(currentConfig.mOperatorNumber) &&
(TextUtils.isEmpty(currentConfig.mGid1) ||
(!TextUtils.isEmpty(currentConfig.mGid1)
&& currentConfig.mGid1.equalsIgnoreCase(gid)))) {
return currentConfig.mIsPrefix;
}
}
return false;
}
private static class NoEmsSupportConfig {
String mOperatorNumber;
String mGid1;
boolean mIsPrefix;
public NoEmsSupportConfig(String[] config) {
mOperatorNumber = config[0];
mIsPrefix = "prefix".equals(config[1]);
mGid1 = config.length > 2 ? config[2] : null;
}
@Override
public String toString() {
return "NoEmsSupportConfig { mOperatorNumber = " + mOperatorNumber
+ ", mIsPrefix = " + mIsPrefix + ", mGid1 = " + mGid1 + " }";
}
}
private static NoEmsSupportConfig[] mNoEmsSupportConfigList = null;
private static boolean mIsNoEmsSupportConfigListLoaded = false;
private static boolean isNoEmsSupportConfigListExisted() {
if (!mIsNoEmsSupportConfigListLoaded) {
Resources r = Resources.getSystem();
if (r != null) {
String[] listArray = r.getStringArray(
com.android.internal.R.array.no_ems_support_sim_operators);
if ((listArray != null) && (listArray.length > 0)) {
mNoEmsSupportConfigList = new NoEmsSupportConfig[listArray.length];
for (int i=0; i