版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35427437/article/details/88766137
上一篇内容太多发布失败,分开发布 点击继续 彩信发送过程第一篇
Transaction.java
这个类主要是sendPdu方法 也挺简单的
/*
* Copyright (C) 2007-2008 Esmertec AG.
* Copyright (C) 2007-2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.mms.transaction;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Uri;
import com.android.mms.MmsConfig;
import com.android.mms.ui.MessageUtils;
import com.android.mms.util.SendingProgressTokenManager;
import com.android.mmswrapper.TelephonyManagerWrapper;
import com.google.android.mms.MmsException;
/**
* Transaction is an abstract class for notification transaction, send transaction
* and other transactions described in MMS spec.
* It provides the interfaces of them and some common methods for them.
*/
public abstract class Transaction extends Observable {
private final int mServiceId;
protected Context mContext;
protected String mId;
protected TransactionState mTransactionState;
protected TransactionSettings mTransactionSettings;
protected int mSubId;
protected int mFailReason;
/**
* Identifies push requests.
*/
public static final int NOTIFICATION_TRANSACTION = 0;
/**
* Identifies deferred retrieve requests.
*/
public static final int RETRIEVE_TRANSACTION = 1;
/**
* Identifies send multimedia message requests.
*/
public static final int SEND_TRANSACTION = 2;
/**
* Identifies send read report requests.
*/
public static final int READREC_TRANSACTION = 3;
public static final int FAIL_REASON_NONE = 0;
public static final int FAIL_REASON_CAN_NOT_SETUP_DATA_CALL = 1;
public Transaction(Context context, int serviceId,
TransactionSettings settings) {
mContext = context;
mTransactionState = new TransactionState();
mServiceId = serviceId;
mTransactionSettings = settings;
mFailReason = FAIL_REASON_NONE;
}
/**
* Returns the transaction state of this transaction.
*
* @return Current state of the Transaction.
*/
@Override
public TransactionState getState() {
return mTransactionState;
}
/**
* An instance of Transaction encapsulates the actions required
* during a MMS Client transaction.
*/
public abstract void process();
/**
* Used to determine whether a transaction is equivalent to this instance.
*
* @param transaction the transaction which is compared to this instance.
* @return true if transaction is equivalent to this instance, false otherwise.
*/
public boolean isEquivalent(Transaction transaction) {
return mId.equals(transaction.mId);
}
/**
* Get the service-id of this transaction which was assigned by the framework.
* @return the service-id of the transaction
*/
public int getServiceId() {
return mServiceId;
}
public int getSubId() {
return mSubId;
}
public void setSubId(int subId) {
mSubId = subId;
}
public TransactionSettings getConnectionSettings() {
return mTransactionSettings;
}
public void setConnectionSettings(TransactionSettings settings) {
mTransactionSettings = settings;
}
public int getFailReason() {
return mFailReason;
}
/**
* A common method to send a PDU to MMSC.
*
* @param pdu A byte array which contains the data of the PDU.
* @return A byte array which contains the response data.
* If an HTTP error code is returned, an IOException will be thrown.
* @throws IOException if any error occurred on network interface or
* an HTTP error code(>=400) returned from the server.
* @throws MmsException if pdu is null.
*/
protected byte[] sendPdu(byte[] pdu) throws IOException, MmsException {
return sendPdu(SendingProgressTokenManager.NO_TOKEN, pdu,
mTransactionSettings.getMmscUrl(),null);
}
/**
* A common method to send a PDU to MMSC.
*
* @param pdu A byte array which contains the data of the PDU.
* @param mmscUrl Url of the recipient MMSC.
* @return A byte array which contains the response data.
* If an HTTP error code is returned, an IOException will be thrown.
* @throws IOException if any error occurred on network interface or
* an HTTP error code(>=400) returned from the server.
* @throws MmsException if pdu is null.
*/
protected byte[] sendPdu(byte[] pdu, String mmscUrl) throws IOException, MmsException {
return sendPdu(SendingProgressTokenManager.NO_TOKEN, pdu, mmscUrl,null);
}
/**
* A common method to send a PDU to MMSC.
*
* @param token The token to identify the sending progress.
* @param pdu A byte array which contains the data of the PDU.
* @return A byte array which contains the response data.
* If an HTTP error code is returned, an IOException will be thrown.
* @throws IOException if any error occurred on network interface or
* an HTTP error code(>=400) returned from the server.
* @throws MmsException if pdu is null.
*/
protected byte[] sendPdu(long token, byte[] pdu,Uri uri) throws IOException, MmsException {
return sendPdu(token, pdu, mTransactionSettings.getMmscUrl(),uri);
}
/**
* A common method to send a PDU to MMSC.
*
* @param token The token to identify the sending progress.
* @param pdu A byte array which contains the data of the PDU.
* @param mmscUrl Url of the recipient MMSC.
* @return A byte array which contains the response data.
* If an HTTP error code is returned, an IOException will be thrown.
* @throws IOException if any error occurred on network interface or
* an HTTP error code(>=400) returned from the server.
* @throws MmsException if pdu is null.
*/
protected byte[] sendPdu(long token, byte[] pdu,
String mmscUrl,Uri SendReqURI) throws IOException, MmsException {
if (pdu == null) {
throw new MmsException();
}
setSocketTimeOut();
return HttpUtils.httpConnection(
mContext, token,
mmscUrl,
pdu, HttpUtils.HTTP_POST_METHOD,
mTransactionSettings.isProxySet(),
mTransactionSettings.getProxyAddress(),
mTransactionSettings.getProxyPort(), mSubId,SendReqURI);
}
/**
* A common method to retrieve a PDU from MMSC.
*
* @param url The URL of the message which we are going to retrieve.
* @return A byte array which contains the data of the PDU.
* If the status code is not correct, an IOException will be thrown.
* @throws IOException if any error occurred on network interface or
* an HTTP error code(>=400) returned from the server.
*/
protected byte[] getPdu(String url,Uri downloadUri) throws IOException {
setSocketTimeOut();
return HttpUtils.httpConnection(
mContext,url, HttpUtils.HTTP_GET_METHOD,
mTransactionSettings.isProxySet(),
mTransactionSettings.getProxyAddress(),
mTransactionSettings.getProxyPort(),mSubId,downloadUri);
}
private void setSocketTimeOut() {
if (TelephonyManagerWrapper.is1xNetwork(mContext, mSubId)) {
MmsConfig.setHttpSocketTimeout(60*1000*3);
} else {
MmsConfig.setHttpSocketTimeout(60*1000);
}
}
public void cancelTransaction(Uri uri) {
}
public abstract void abort();
@Override
public String toString() {
return getClass().getName() + ": serviceId=" + mServiceId + " subId= " + mSubId;
}
/**
* Get the type of the transaction.
*
* @return Transaction type in integer.
*/
abstract public int getType();
}
HttpUtils.java这个类主要是上传将彩信基站,或者图片下载 ,这个类注释可理解
/*
* Copyright (C) 2008 Esmertec AG.
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.mms.transaction;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.greenrobot.eventbus.EventBus;
import org.w3c.dom.events.Event;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
import com.android.mms.LogTag;
import com.android.mms.MmsConfig;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.Map;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.HttpURLConnection;
import com.android.i18n.phonenumbers.NumberParseException;
import com.android.i18n.phonenumbers.PhoneNumberUtil;
import com.android.i18n.phonenumbers.Phonenumber;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.util.Base64;
import android.view.View;
import java.io.UnsupportedEncodingException;
import com.android.mms.event.MmsDownloadEvent;
import com.android.mms.event.MmsProgresEvent;
import com.android.mms.event.UpDataUI;
import com.android.mmswrapper.TelephonyManagerWrapper;
import com.android.mmswrapper.SubscriptionManagerWrapper;
import com.google.android.mms.MmsException;
public class HttpUtils {
private static final String TAG = LogTag.TRANSACTION;
private static final boolean DEBUG = false;
private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
public static final int HTTP_POST_METHOD = 1;//发送短信
public static final int HTTP_GET_METHOD = 2;//接收短信
private static final int MMS_READ_BUFFER = 4096;
// This is the value to use for the "Accept-Language" header.
// Once it becomes possible for the user to change the locale
// setting, this should no longer be static. We should call
// getHttpAcceptLanguage instead.
private static final String HDR_VALUE_ACCEPT_LANGUAGE;
static {
HDR_VALUE_ACCEPT_LANGUAGE = getCurrentAcceptLanguage(Locale.getDefault());
}
// Definition for necessary HTTP headers.
private static final String HDR_KEY_ACCEPT = "Accept";
private static final String HDR_KEY_ACCEPT_LANGUAGE = "Accept-Language";
private static final String HEADER_USER_AGENT = "User-Agent";
private static final String HDR_VALUE_ACCEPT =
"*/*, application/vnd.wap.mms-message, application/vnd.wap.sic";
private static final String INTENT_HTTP_TIMEOUT_ALARM = "org.codeaurora.mms.http_timeout";
private static final String INTENT_EXTRA_TAG = "mmstag";
// 3min default timeout
private static final int HTTP_TIMEOUT = 3 * 60 * 1000;
private static long sAlarmTag = 0;
private static HttpRequestBase sHttpReq = null;
private static PendingIntent sAlarmIntent = null;
private static IntentFilter sIntentFilter = new IntentFilter(INTENT_HTTP_TIMEOUT_ALARM);
private static final Pattern MACRO_P = Pattern.compile("##(\\S+)##");
private static final String MACRO_LINE1 = "LINE1";
private static final String MACRO_LINE1NOCOUNTRYCODE = "LINE1NOCOUNTRYCODE";
private static final String MACRO_NAI = "NAI";
private static final String HEADER_CONTENT_TYPE = "Content-Type";
private static final String HEADER_VALUE_CONTENT_TYPE_WITHOUT_CHARSET =
"application/vnd.wap.mms-message";
// The "Content-Type" header value
private static final String HEADER_VALUE_CONTENT_TYPE_WITH_CHARSET =
"application/vnd.wap.mms-message; charset=utf-8";
private static final String METHOD_POST = "POST";
private static final String METHOD_GET = "GET";
private static HttpURLConnection mConnection = null;
private static BroadcastReceiver sIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (INTENT_HTTP_TIMEOUT_ALARM.equals(intent.getAction())) {
long tag = intent.getLongExtra(INTENT_EXTRA_TAG, -1);
Log.d(TAG, "[HttpUtils] HTTP timeout alarm. tag = " + tag
+ " sAlarmTag = " + sAlarmTag);
abortHttpRequest(tag);
}
}
};
private int responseCode;
private OutputStream out;
private HttpUtils() {
// To forbidden instantiate this class.
}
private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US";
/**
* Return the Accept-Language header. Use the current locale plus
* US if we are in a different locale than US.
* This code copied from the browser's WebSettings.java
* @return Current AcceptLanguage String.
*/
public static String getCurrentAcceptLanguage(Locale locale) {
StringBuilder buffer = new StringBuilder();
addLocaleToHttpAcceptLanguage(buffer, locale);
if (!Locale.US.equals(locale)) {
if (buffer.length() > 0) {
buffer.append(", ");
}
buffer.append(ACCEPT_LANG_FOR_US_LOCALE);
}
return buffer.toString();
}
/**
* Convert obsolete language codes, including Hebrew/Indonesian/Yiddish,
* to new standard.
*/
private static String convertObsoleteLanguageCodeToNew(String langCode) {
if (langCode == null) {
return null;
}
if ("iw".equals(langCode)) {
// Hebrew
return "he";
} else if ("in".equals(langCode)) {
// Indonesian
return "id";
} else if ("ji".equals(langCode)) {
// Yiddish
return "yi";
}
return langCode;
}
private static void addLocaleToHttpAcceptLanguage(StringBuilder builder,
Locale locale) {
String language = convertObsoleteLanguageCodeToNew(locale.getLanguage());
if (language != null) {
builder.append(language);
String country = locale.getCountry();
if (country != null) {
builder.append("-");
builder.append(country);
}
}
}
private static synchronized void startAlarmForTimeout(Context context) {
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
Log.d(TAG, "[HttpUtils] startAlarmForTimeout for " + HTTP_TIMEOUT);
}
Intent intent = new Intent(INTENT_HTTP_TIMEOUT_ALARM);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
sAlarmTag++;
intent.putExtra(INTENT_EXTRA_TAG, sAlarmTag);
sAlarmIntent = PendingIntent.getBroadcast (context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + HTTP_TIMEOUT, sAlarmIntent);
context.registerReceiver(sIntentReceiver, sIntentFilter);
}
private static synchronized void cancelTimeoutAlarm(Context context) {
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
Log.d(TAG, "HttpUtils: cancelTimeoutAlarm");
}
if (sAlarmIntent != null) {
context.unregisterReceiver(sIntentReceiver);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(sAlarmIntent);
sAlarmIntent = null;
}
}
private static void abortHttpRequest(final long tag) {
Runnable runnable = new Runnable() {
@Override
public void run() {
synchronized(HttpUtils.class) {
Log.d(TAG, "[HttpUtils] abortHttpRequest. tag = " + tag
+ " sAlarmTag = " + sAlarmTag);
if (tag == sAlarmTag && mConnection != null) {
try {
mConnection.disconnect();
} catch (Exception e) {
Log.w(TAG, "[HttpUtils] abortHttpRequest: Ex:" + e);
}
} else {
Log.d(TAG, "[HttpUtils] Alarm tags not matching or no req. Ignore!");
}
}
}
};
Thread abortThread = new Thread(runnable);
abortThread.start();
}
/**
* A helper method to send or retrieve data through HTTP protocol.
*
* @param token The token to identify the sending progress.
* @param pdu The data to be POST. Null when the method is HTTP_GET_METHOD.
* @param method HTTP_POST_METHOD or HTTP_GET_METHOD.
* @return A byte array which contains the response data.
* If an HTTP error code is returned, an IOException will be thrown.
* @throws IOException if any error occurred on network interface or
* an HTTP error code(>=400) returned from the server.
*/
protected static byte[] httpConnection(Context context, long token,
String urlString, byte[] pdu, int method, boolean isProxySet,
String proxyHost, int proxyPort, int subId, Uri SendReqURI) throws IOException {
Log.v("liwangjianghttpConnection","----httpConnection---- pdu= "+pdu+" method = "+method+" isProxySet = "+isProxySet);
if (method==HTTP_GET_METHOD){
}
MmsProgresEvent event=null;
EventBus eventBus=null;
if (SendReqURI!=null){//判断是否是发送
eventBus = EventBus.getDefault();
Log.v("liwangjiangSendReqURI","SendReqURI = "+SendReqURI);
eventBus.post(new UpDataUI(SendReqURI));
//liwangjiang传输更新进度条数据
event = new MmsProgresEvent();
}
if (urlString == null) {
throw new IllegalArgumentException("URL must not be null.");
}
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
Log.v(TAG, "httpConnection: params list");
Log.v(TAG, "\ttoken\t\t= " + token);
Log.v(TAG, "\turl\t\t= " + urlString);
Log.v(TAG, "\tmethod\t\t= "
+ ((method == HTTP_POST_METHOD) ? "POST"
: ((method == HTTP_GET_METHOD) ? "GET" : "UNKNOWN")));
Log.v(TAG, "\tisProxySet\t= " + isProxySet);
Log.v(TAG, "\tproxyHost\t= " + proxyHost);
Log.v(TAG, "\tproxyPort\t= " + proxyPort);
// TODO Print out binary data more readable.
//Log.v(TAG, "\tpdu\t\t= " + Arrays.toString(pdu));
}
ByteArrayInputStream inputStreamByte=null;
HttpURLConnection connection = null;
OutputStream out=null;
try {
startAlarmForTimeout(context);
checkMethod(method);
Proxy proxy = Proxy.NO_PROXY;
if (isProxySet) {
proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(proxyHost, proxyPort));
}
final URL url = new URL(urlString);
// Now get the connection
connection = (HttpURLConnection) url.openConnection(proxy);
connection.setDoInput(true);
connection.setConnectTimeout(HTTP_TIMEOUT);
connection.setReadTimeout(MmsConfig.getHttpSocketTimeout());
// ------- COMMON HEADERS ---------
// Header: Accept
connection.setRequestProperty(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);
// Header: Accept-Language
connection.setRequestProperty(HDR_KEY_ACCEPT_LANGUAGE,
HDR_VALUE_ACCEPT_LANGUAGE);
// Header: User-Agent
Log.i(TAG, "HTTP: User-Agent=" + MmsConfig.getUserAgent());
connection.setRequestProperty(HEADER_USER_AGENT, MmsConfig.getUserAgent());
// Header: x-wap-profile
String xWapProfileTagName = MmsConfig.getUaProfTagName();
String xWapProfileUrl = MmsConfig.getUaProfUrl();
if (xWapProfileUrl != null) {
Log.i(TAG, "HTTP: xWapProfileUrl=" + xWapProfileUrl
+ ";xWapProfileTagName=" + xWapProfileTagName);
connection.setRequestProperty(xWapProfileTagName, xWapProfileUrl);
}
// Add extra headers specified by mms_config.xml's httpparams
addExtraHeaders(context, connection, subId);
// Different stuff for GET and POST
if (HTTP_POST_METHOD == method) {
if (pdu == null || pdu.length < 1) {
Log.e(TAG, "HTTP: empty pdu");
throw new IllegalArgumentException("HTTP: empty pdu");
}
connection.setDoOutput(true);
connection.setRequestMethod(METHOD_POST);
connection.setRequestProperty(HEADER_CONTENT_TYPE,
HEADER_VALUE_CONTENT_TYPE_WITHOUT_CHARSET);
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
logHttpHeaders(connection.getRequestProperties());
}
connection.setFixedLengthStreamingMode(pdu.length);
// Sending request body
out = new BufferedOutputStream(connection.getOutputStream());
inputStreamByte = new ByteArrayInputStream(pdu);
int len = 0;
// 计算上传进度
Integer progress = 0;
byte[] bufferOut = new byte[4096];
int recode=0;
if (SendReqURI!=null&&event!=null){//判断是否是发送
event.setUri(SendReqURI);
event.setSet(MmsProgresEvent.SET_TOTAL);
while ((len = inputStreamByte.read(bufferOut)) != -1) {
progress += len;
event.setFileSize(pdu.length);
Log.v("liwangjianghttpConnection","Http progress = "+progress);
event.setProgress(progress);//设置值
eventBus.post(event);
SystemClock.sleep(100);
out.write(bufferOut, 0, len);
recode++;
}
recode=0;
}else {
out.write(bufferOut);
}
//发送过程
inputStreamByte.close();
out.flush();
out.close();
} else if (HTTP_GET_METHOD == method) {
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
logHttpHeaders(connection.getRequestProperties());
}
connection.setRequestMethod(METHOD_GET);
}
synchronized (HttpUtils.class) {
mConnection = connection;
}
//------------------------------------------在中间停了一段时间-------------------------
int responseCode = connection.getResponseCode();
if (SendReqURI!=null) {//判断是否是发送
//发送状态码
event.setSet(MmsProgresEvent.SET_STATE);
event.setState(responseCode);//状态
event.setFileSize(pdu.length);
eventBus.post(event);
}
final String responseMessage = connection.getResponseMessage();
Log.d(TAG, "HTTP: " + responseCode + " responseMessage " + responseMessage);
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
logHttpHeaders(connection.getHeaderFields());
}
if (responseCode / 100 != 2) {
throw new IOException("HTTP error: responseCode:"+ responseCode + responseMessage);
}
return updateSSM(connection);
} catch (MalformedURLException e) {
handleHttpConnectionException(e, urlString);
} catch (ProtocolException e) {
handleHttpConnectionException(e, urlString);
} catch (SocketException e) {
handleHttpConnectionException(e, urlString);
} catch (IOException e) {
handleHttpConnectionException(e, urlString);
} catch (MmsException e) {
handleHttpConnectionException(e, urlString);
} finally {
if (connection != null) {
connection.disconnect();
}
cancelTimeoutAlarm(context);
}
return null;
}
private static byte[] updateSSM(HttpURLConnection connection) throws IOException {
final byte[] buf= new byte[4096];
final InputStream in = new BufferedInputStream(connection.getInputStream());
final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
int count = 0;
while ((count = in.read(buf)) > 0) {
byteOut.write(buf, 0, count);
}
in.close();
final byte[] responseBody = byteOut.toByteArray();
Log.d(TAG, "HTTP: response size=" + (responseBody != null ? responseBody.length : 0));
return responseBody;
}
private static void checkMethod(int method) throws MmsException {
if (HTTP_POST_METHOD != method && HTTP_GET_METHOD != method) {
throw new MmsException("Invalid method " + method);
}
}
private static void handleHttpConnectionException(Exception exception, String url)
throws IOException {
// Inner exception should be logged to make life easier.
Log.e(TAG, "Url: " + url + "\n" + exception.getMessage());
IOException e = new IOException(exception.getMessage());
e.initCause(exception);
throw e;
}
private static void addExtraHeaders(Context context,
HttpURLConnection connection, int subId) {
final String extraHttpParams = MmsConfig.getHttpParams();
if (!TextUtils.isEmpty(extraHttpParams)) {
// Parse the parameter list
String paramList[] = extraHttpParams.split("\\|");
for (String paramPair : paramList) {
String splitPair[] = paramPair.split(":", 2);
if (splitPair.length == 2) {
final String name = splitPair[0].trim();
final String value = resolveMacro(context, splitPair[1].trim(), subId);
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(value)) {
// Add the header if the param is valid
connection.setRequestProperty(name, value);
}
}
}
}
}
private static String resolveMacro(Context context, String value, int subId) {
if (TextUtils.isEmpty(value)) {
return value;
}
final Matcher matcher = MACRO_P.matcher(value);
int nextStart = 0;
StringBuilder replaced = null;
while (matcher.find()) {
if (replaced == null) {
replaced = new StringBuilder();
}
final int matchedStart = matcher.start();
if (matchedStart > nextStart) {
replaced.append(value.substring(nextStart, matchedStart));
}
final String macro = matcher.group(1);
final String macroValue = getHttpParamMacro(context, macro, subId);
if (macroValue != null) {
replaced.append(macroValue);
}
nextStart = matcher.end();
}
if (replaced != null && nextStart < value.length()) {
replaced.append(value.substring(nextStart));
}
return replaced == null ? value : replaced.toString();
}
/**
* Return the HTTP param macro value. Example: LINE1 returns the phone number,
* etc.
*
* @param macro
* The macro name
* @param mmsConfig
* The carrier configuration values
* @return The value of the defined macro
*/
private static String getHttpParamMacro(Context context, final String macro, int subId) {
if (MACRO_LINE1.equals(macro)) {
return getSelfNumber(context, subId);
} else if (MACRO_LINE1NOCOUNTRYCODE.equals(macro)) {
return getLine1NoCountryCode(context, subId);
} else if (MACRO_NAI.equals(macro)) {
return getEncodedNai(context, subId);
}
return null;
}
private static String getLine1NoCountryCode(Context context, int subId) {
final TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return getNationalNumber(telephonyManager, subId,
TelephonyManagerWrapper.getLine1Number(telephonyManager, subId));
}
public static String getNationalNumber(TelephonyManager telephonyManager,
int subId, String phoneText) {
final String country = getSimOrDefaultLocaleCountry(telephonyManager, subId);
final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
final Phonenumber.PhoneNumber parsed = getParsedNumber(phoneNumberUtil, phoneText, country);
if (parsed == null) {
return phoneText;
}
return phoneNumberUtil.format(parsed,
PhoneNumberUtil.PhoneNumberFormat.NATIONAL).replaceAll("\\D", "");
}
private static Phonenumber.PhoneNumber getParsedNumber(PhoneNumberUtil phoneNumberUtil,
String phoneText, String country) {
try {
final Phonenumber.PhoneNumber phoneNumber =
phoneNumberUtil.parse(phoneText, country);
if (phoneNumberUtil.isValidNumber(phoneNumber)) {
return phoneNumber;
} else {
Log.e(TAG, "getParsedNumber: not a valid phone number"
+ " for country " + country);
return null;
}
} catch (final NumberParseException e) {
Log.e(TAG, "getParsedNumber: Not able to parse phone number", e);
return null;
}
}
private static String getSimOrDefaultLocaleCountry(TelephonyManager telephonyManager,
int subId) {
String country = getSimCountry(telephonyManager, subId);
if (TextUtils.isEmpty(country)) {
country = Locale.getDefault().getCountry();
}
return country;
}
// Get country/region from SIM ID
private static String getSimCountry(TelephonyManager telephonyManager, int subId) {
final String country = TelephonyManagerWrapper.getSimCountryIso(telephonyManager, subId);
if (TextUtils.isEmpty(country)) {
return null;
}
return country.toUpperCase();
}
private static String getEncodedNai(Context context, int subId) {
String nai = TelephonyManagerWrapper.getNai(context,
SubscriptionManagerWrapper.getSlotId(subId));
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
Log.v(TAG, "getNai: nai=" + nai);
}
if (!TextUtils.isEmpty(nai)) {
byte[] encoded = null;
try {
encoded = Base64.encode(nai.getBytes("UTF-8"), Base64.NO_WRAP);
} catch (UnsupportedEncodingException e) {
encoded = Base64.encode(nai.getBytes(), Base64.NO_WRAP);
}
try {
nai = new String(encoded, "UTF-8");
} catch (UnsupportedEncodingException e) {
nai = new String(encoded);
}
}
return nai;
}
/**
* Get the device phone number
*
* @return the phone number text
*/
private static String getSelfNumber(Context context, int subId) {
final TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return TelephonyManagerWrapper.getLine1Number(telephonyManager, subId);
}
private static void logHttpHeaders(Map<String, List<String>> headers) {
final StringBuilder sb = new StringBuilder();
if (headers != null) {
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
final String key = entry.getKey();
final List<String> values = entry.getValue();
if (values != null) {
for (String value : values) {
sb.append(key).append('=').append(value).append('\n');
}
}
}
Log.v(TAG, "HTTP: headers\n" + sb.toString());
}
}
/**
* 重写用于下载图片使用
*
* @param token The token to identify the sending progress.
* @param url The URL used in a GET request. Null when the method is
* HTTP_POST_METHOD.
* @param pdu The data to be POST. Null when the method is HTTP_GET_METHOD.
* @param method HTTP_POST_METHOD or HTTP_GET_METHOD.
* @return A byte array which contains the response data.
* If an HTTP error code is returned, an IOException will be thrown.
* @throws IOException if any error occurred on network interface or
* an HTTP error code(>=400) returned from the server.
*/
protected static byte[] httpConnection(Context context,
String urlString, int method, boolean isProxySet,
String proxyHost, int proxyPort, int subId, Uri downloadUri) throws IOException {
Log.v("liwangjianghttpConnection","----httpConnection---- pdu= method = "+method+" isProxySet = "+isProxySet);
if (urlString == null) {
throw new IllegalArgumentException("URL must not be null");
}
String[] mId=downloadUri.toString().split("/");
HttpURLConnection connection = null;
try{
startAlarmForTimeout(context);
checkMethod(method);
Proxy proxy = Proxy.NO_PROXY;
if (isProxySet) {
proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(proxyHost, proxyPort));
}
final URL url = new URL(urlString);
// Now get the connection
connection = (HttpURLConnection) url.openConnection(proxy);
connection.setDoInput(true);
connection.setConnectTimeout(HTTP_TIMEOUT);
connection.setReadTimeout(MmsConfig.getHttpSocketTimeout());
// ------- COMMON HEADERS ---------
// Header: Accept
connection.setRequestProperty(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);
// Header: Accept-Language
connection.setRequestProperty(HDR_KEY_ACCEPT_LANGUAGE,
HDR_VALUE_ACCEPT_LANGUAGE);
// Header: User-Agent
Log.i(TAG, "HTTP: User-Agent=" + MmsConfig.getUserAgent());
connection.setRequestProperty(HEADER_USER_AGENT, MmsConfig.getUserAgent());
// Header: x-wap-profile
String xWapProfileTagName = MmsConfig.getUaProfTagName();
String xWapProfileUrl = MmsConfig.getUaProfUrl();
if (xWapProfileUrl != null) {
Log.i(TAG, "HTTP: xWapProfileUrl=" + xWapProfileUrl
+ ";xWapProfileTagName=" + xWapProfileTagName);
connection.setRequestProperty(xWapProfileTagName, xWapProfileUrl);
}
// Add extra headers specified by mms_config.xml's httpparams
addExtraHeaders(context, connection, subId);
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
logHttpHeaders(connection.getRequestProperties());
}
connection.setRequestMethod(METHOD_GET);
synchronized (HttpUtils.class) {
mConnection = connection;
}
//------------------------------------------在中间停了一段时间-------------------------
int responseCode = connection.getResponseCode();
final String responseMessage = connection.getResponseMessage();
Log.d(TAG, "HTTP: " + responseCode + " responseMessage " + responseMessage);
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
logHttpHeaders(connection.getHeaderFields());
}
if (responseCode / 100 != 2) {
throw new IOException("HTTP error: responseCode:"+ responseCode + responseMessage);
}
//下载图片
MmsDownloadEvent event=null;
EventBus eventBus=null;
eventBus=EventBus.getDefault();
event = new MmsDownloadEvent();
event.setFileSize(100);//设置文件大小
event.setSet(MmsDownloadEvent.SET_FILE);
event.setmId(Integer.valueOf(mId[mId.length-1]));
Log.v("Integer.valueOf(mId[mId.length-1]","Integer.valueOf(mId[mId.length-1] = "+Integer.valueOf(mId[mId.length-1]));
eventBus.post(event);
Log.v("downloadinfo","Integer.valueOf(mId[mId.length-1]) = "+Integer.valueOf(mId[mId.length-1]));
event.setFileSize(connection.getContentLength());
final byte[] buf= new byte[1024];
final InputStream in = new BufferedInputStream(connection.getInputStream());
final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
int progress=0;
int count = 0;
while ((count = in.read(buf)) > 0) {
progress += count;
Log.v("liwangjianghttpConnection","Http progress = "+progress);
event.setProgres(progress);//设置值
SystemClock.sleep(10);
event.setSet(MmsDownloadEvent.SET_PROGRES);
eventBus.post(event);
byteOut.write(buf, 0, count);
}
event.setState(responseCode);
event.setSet(MmsDownloadEvent.SET_STATE);
eventBus.post(event);
in.close();
final byte[] responseBody = byteOut.toByteArray();
Log.d(TAG, "HTTP: response size=" + (responseBody != null ? responseBody.length : 0));
return responseBody;
} catch (MalformedURLException e) {
handleHttpConnectionException(e, urlString);
} catch (ProtocolException e) {
handleHttpConnectionException(e, urlString);
} catch (SocketException e) {
handleHttpConnectionException(e, urlString);
} catch (IOException e) {
handleHttpConnectionException(e, urlString);
} catch (MmsException e) {
handleHttpConnectionException(e, urlString);
} finally {
if (connection != null) {
connection.disconnect();
}
cancelTimeoutAlarm(context);
}
return null;
}
private static String redactUrlForNonVerbose(String urlString) {
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
// Don't redact for VERBOSE level logging
return urlString;
}
if (TextUtils.isEmpty(urlString)) {
return urlString;
}
String protocol = "http";
String host = "";
try {
final URL url = new URL(urlString);
protocol = url.getProtocol();
host = url.getHost();
} catch (MalformedURLException e) {
// Ignore
}
// Print "http://host[length]"
final StringBuilder sb = new StringBuilder();
sb.append(protocol)
.append("://")
.append(host)
.append("[")
.append(urlString.length())
.append("]");
return sb.toString();
}
}