mirror of
https://github.com/cwinfo/envayasms.git
synced 2025-04-16 13:08:20 +00:00
651 lines
22 KiB
Java
Executable File
651 lines
22 KiB
Java
Executable File
package org.envaya.kalsms;
|
|
|
|
import android.app.Activity;
|
|
import android.app.AlarmManager;
|
|
import android.app.Application;
|
|
import android.app.PendingIntent;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.os.SystemClock;
|
|
import android.preference.PreferenceManager;
|
|
import android.telephony.SmsManager;
|
|
import android.text.Html;
|
|
import android.text.SpannableStringBuilder;
|
|
import android.util.Log;
|
|
import java.text.DateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import org.apache.http.client.HttpClient;
|
|
import org.apache.http.conn.params.ConnManagerParams;
|
|
import org.apache.http.conn.scheme.PlainSocketFactory;
|
|
import org.apache.http.conn.scheme.Scheme;
|
|
import org.apache.http.conn.scheme.SchemeRegistry;
|
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
|
import org.apache.http.impl.client.DefaultHttpClient;
|
|
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
|
|
import org.apache.http.message.BasicNameValuePair;
|
|
import org.apache.http.params.BasicHttpParams;
|
|
import org.apache.http.params.HttpConnectionParams;
|
|
import org.apache.http.params.HttpParams;
|
|
import org.apache.http.params.HttpProtocolParams;
|
|
import org.envaya.kalsms.receiver.OutgoingMessagePoller;
|
|
import org.envaya.kalsms.task.HttpTask;
|
|
import org.envaya.kalsms.task.PollerTask;
|
|
import org.json.JSONArray;
|
|
import org.json.JSONException;
|
|
|
|
public final class App extends Application {
|
|
|
|
public static final String ACTION_OUTGOING = "outgoing";
|
|
public static final String ACTION_INCOMING = "incoming";
|
|
public static final String ACTION_SEND_STATUS = "send_status";
|
|
|
|
public static final String STATUS_QUEUED = "queued";
|
|
public static final String STATUS_FAILED = "failed";
|
|
public static final String STATUS_SENT = "sent";
|
|
|
|
public static final String MESSAGE_TYPE_MMS = "mms";
|
|
public static final String MESSAGE_TYPE_SMS = "sms";
|
|
|
|
public static final String LOG_NAME = "KALSMS";
|
|
|
|
// intent to signal to Main activity (if open) that log has changed
|
|
public static final String LOG_INTENT = "org.envaya.kalsms.LOG";
|
|
|
|
public static final String QUERY_EXPANSION_PACKS_INTENT = "org.envaya.kalsms.QUERY_EXPANSION_PACKS";
|
|
public static final String QUERY_EXPANSION_PACKS_EXTRA_PACKAGES = "packages";
|
|
|
|
// Interface for sending outgoing messages to expansion packs
|
|
public static final String OUTGOING_SMS_INTENT_SUFFIX = ".OUTGOING_SMS";
|
|
public static final String OUTGOING_SMS_EXTRA_TO = "to";
|
|
public static final String OUTGOING_SMS_EXTRA_BODY = "body";
|
|
public static final int OUTGOING_SMS_UNHANDLED = Activity.RESULT_FIRST_USER;
|
|
|
|
// intent for MessageStatusNotifier to receive status updates for outgoing SMS
|
|
// (even if sent by an expansion pack)
|
|
public static final String MESSAGE_STATUS_INTENT = "org.envaya.kalsms.MESSAGE_STATUS";
|
|
|
|
public static final int MAX_DISPLAYED_LOG = 4000;
|
|
public static final int LOG_TIMESTAMP_INTERVAL = 60000;
|
|
|
|
// Each QueuedMessage is identified within our internal Map by its Uri.
|
|
// Currently QueuedMessage instances are only available within KalSMS,
|
|
// (but they could be made available to other applications later via a ContentProvider)
|
|
public static final Uri CONTENT_URI = Uri.parse("content://org.envaya.kalsms");
|
|
public static final Uri INCOMING_URI = Uri.withAppendedPath(CONTENT_URI, "incoming");
|
|
public static final Uri OUTGOING_URI = Uri.withAppendedPath(CONTENT_URI, "outgoing");
|
|
|
|
// max per-app outgoing SMS rate used by com.android.internal.telephony.SMSDispatcher
|
|
// with a slightly longer check period to account for variance in the time difference
|
|
// between when we prepare messages and when SMSDispatcher receives them
|
|
public static int OUTGOING_SMS_CHECK_PERIOD = 3605000; // one hour plus 5 sec (in ms)
|
|
public static int OUTGOING_SMS_MAX_COUNT = 100;
|
|
|
|
private Map<Uri, IncomingMessage> incomingMessages = new HashMap<Uri, IncomingMessage>();
|
|
private Map<Uri, OutgoingMessage> outgoingMessages = new HashMap<Uri, OutgoingMessage>();
|
|
|
|
private SharedPreferences settings;
|
|
private MmsObserver mmsObserver;
|
|
private SpannableStringBuilder displayedLog = new SpannableStringBuilder();
|
|
private long lastLogTime;
|
|
|
|
// list of package names (e.g. org.envaya.kalsms, or org.envaya.kalsms.packXX)
|
|
// for this package and all expansion packs
|
|
private List<String> outgoingMessagePackages = new ArrayList<String>();
|
|
|
|
// count to provide round-robin selection of expansion packs
|
|
private int outgoingMessageCount = -1;
|
|
|
|
// map of package name => sorted list of timestamps of outgoing messages
|
|
private HashMap<String, ArrayList<Long>> outgoingTimestamps
|
|
= new HashMap<String, ArrayList<Long>>();
|
|
|
|
private MmsUtils mmsUtils;
|
|
|
|
@Override
|
|
public void onCreate()
|
|
{
|
|
super.onCreate();
|
|
|
|
settings = PreferenceManager.getDefaultSharedPreferences(this);
|
|
mmsUtils = new MmsUtils(this);
|
|
|
|
outgoingMessagePackages.add(getPackageName());
|
|
|
|
updateExpansionPacks();
|
|
|
|
log(Html.fromHtml(
|
|
isEnabled() ? "<b>SMS gateway running.</b>" : "<b>SMS gateway disabled.</b>"));
|
|
|
|
log("Server URL is: " + getDisplayString(getServerUrl()));
|
|
log("Your phone number is: " + getDisplayString(getPhoneNumber()));
|
|
|
|
if (isTestMode())
|
|
{
|
|
log("Test mode is ON");
|
|
log("Test phone numbers:");
|
|
|
|
for (String sender : getTestPhoneNumbers())
|
|
{
|
|
log(" " + sender);
|
|
}
|
|
}
|
|
|
|
mmsObserver = new MmsObserver(this);
|
|
mmsObserver.register();
|
|
|
|
setOutgoingMessageAlarm();
|
|
}
|
|
|
|
public synchronized String chooseOutgoingSmsPackage()
|
|
{
|
|
outgoingMessageCount++;
|
|
|
|
int numPackages = outgoingMessagePackages.size();
|
|
|
|
// round robin selection of packages that are under max sending rate
|
|
for (int i = 0; i < numPackages; i++)
|
|
{
|
|
int packageIndex = (outgoingMessageCount + i) % numPackages;
|
|
String packageName = outgoingMessagePackages.get(packageIndex);
|
|
|
|
// implement rate-limiting algorithm from
|
|
// com.android.internal.telephony.SMSDispatcher.SmsCounter
|
|
|
|
if (!outgoingTimestamps.containsKey(packageName)) {
|
|
outgoingTimestamps.put(packageName, new ArrayList<Long>());
|
|
}
|
|
|
|
ArrayList<Long> sent = outgoingTimestamps.get(packageName);
|
|
|
|
Long ct = System.currentTimeMillis();
|
|
|
|
//log(packageName + " SMS send size=" + sent.size());
|
|
|
|
// remove old timestamps
|
|
while (sent.size() > 0 && (ct - sent.get(0)) > OUTGOING_SMS_CHECK_PERIOD )
|
|
{
|
|
sent.remove(0);
|
|
}
|
|
|
|
if ( (sent.size() + 1) <= OUTGOING_SMS_MAX_COUNT)
|
|
{
|
|
sent.add(ct);
|
|
return packageName;
|
|
}
|
|
}
|
|
|
|
log("Can't send outgoing SMS: maximum limit of "
|
|
+ getOutgoingMessageLimit() + " in 1 hour reached");
|
|
log("To increase this limit, install an expansion pack.");
|
|
|
|
return null;
|
|
}
|
|
|
|
private synchronized void setExpansionPacks(List<String> packages)
|
|
{
|
|
int prevLimit = getOutgoingMessageLimit();
|
|
|
|
if (packages == null)
|
|
{
|
|
packages = new ArrayList<String>();
|
|
}
|
|
|
|
packages.add(getPackageName());
|
|
|
|
outgoingMessagePackages = packages;
|
|
|
|
int newLimit = getOutgoingMessageLimit();
|
|
|
|
if (prevLimit != newLimit)
|
|
{
|
|
log("Outgoing SMS limit: " + newLimit + " messages/hour");
|
|
}
|
|
}
|
|
|
|
public int getOutgoingMessageLimit()
|
|
{
|
|
return outgoingMessagePackages.size() * OUTGOING_SMS_MAX_COUNT;
|
|
}
|
|
|
|
public void updateExpansionPacks()
|
|
{
|
|
ArrayList<String> packages = new ArrayList<String>();
|
|
Bundle extras = new Bundle();
|
|
extras.putStringArrayList(App.QUERY_EXPANSION_PACKS_EXTRA_PACKAGES, packages);
|
|
|
|
sendOrderedBroadcast(
|
|
new Intent(App.QUERY_EXPANSION_PACKS_INTENT),
|
|
"android.permission.SEND_SMS",
|
|
new BroadcastReceiver() {
|
|
@Override
|
|
public void onReceive(Context context, Intent resultIntent) {
|
|
|
|
setExpansionPacks(this.getResultExtras(false)
|
|
.getStringArrayList(App.QUERY_EXPANSION_PACKS_EXTRA_PACKAGES));
|
|
|
|
}
|
|
},
|
|
null,
|
|
Activity.RESULT_OK,
|
|
null,
|
|
extras);
|
|
}
|
|
|
|
public void checkOutgoingMessages()
|
|
{
|
|
String serverUrl = getServerUrl();
|
|
if (serverUrl.length() > 0) {
|
|
log("Checking for outgoing messages");
|
|
new PollerTask(this).execute();
|
|
} else {
|
|
log("Can't check outgoing messages; server URL not set");
|
|
}
|
|
}
|
|
|
|
public void setOutgoingMessageAlarm() {
|
|
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
|
|
0,
|
|
new Intent(this, OutgoingMessagePoller.class),
|
|
0);
|
|
|
|
alarm.cancel(pendingIntent);
|
|
|
|
int pollSeconds = getOutgoingPollSeconds();
|
|
|
|
if (isEnabled())
|
|
{
|
|
if (pollSeconds > 0) {
|
|
alarm.setRepeating(
|
|
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
|
SystemClock.elapsedRealtime(),
|
|
pollSeconds * 1000,
|
|
pendingIntent);
|
|
log("Checking for outgoing messages every " + pollSeconds + " sec");
|
|
} else {
|
|
log("Not checking for outgoing messages.");
|
|
}
|
|
}
|
|
}
|
|
|
|
public String getDisplayString(String str) {
|
|
if (str.length() == 0) {
|
|
return "(not set)";
|
|
} else {
|
|
return str;
|
|
}
|
|
}
|
|
|
|
public String getServerUrl() {
|
|
return settings.getString("server_url", "");
|
|
}
|
|
|
|
public String getPhoneNumber() {
|
|
return settings.getString("phone_number", "");
|
|
}
|
|
|
|
public int getOutgoingPollSeconds() {
|
|
return Integer.parseInt(settings.getString("outgoing_interval", "0"));
|
|
}
|
|
|
|
public boolean isEnabled()
|
|
{
|
|
return settings.getBoolean("enabled", false);
|
|
}
|
|
|
|
public boolean isTestMode()
|
|
{
|
|
return settings.getBoolean("test_mode", false);
|
|
}
|
|
|
|
public boolean getKeepInInbox()
|
|
{
|
|
return settings.getBoolean("keep_in_inbox", false);
|
|
}
|
|
|
|
public String getPassword() {
|
|
return settings.getString("password", "");
|
|
}
|
|
|
|
private void notifyStatus(OutgoingMessage sms, String status, String errorMessage) {
|
|
String serverId = sms.getServerId();
|
|
|
|
String logMessage;
|
|
if (status.equals(App.STATUS_SENT)) {
|
|
logMessage = "sent successfully";
|
|
} else if (status.equals(App.STATUS_FAILED)) {
|
|
logMessage = "could not be sent (" + errorMessage + ")";
|
|
} else {
|
|
logMessage = "queued";
|
|
}
|
|
String smsDesc = sms.getLogName();
|
|
|
|
if (serverId != null) {
|
|
log("Notifying server " + smsDesc + " " + logMessage);
|
|
|
|
new HttpTask(this,
|
|
new BasicNameValuePair("id", serverId),
|
|
new BasicNameValuePair("status", status),
|
|
new BasicNameValuePair("error", errorMessage),
|
|
new BasicNameValuePair("action", App.ACTION_SEND_STATUS)
|
|
).execute();
|
|
} else {
|
|
log(smsDesc + " " + logMessage);
|
|
}
|
|
}
|
|
|
|
public synchronized void retryStuckMessages() {
|
|
retryStuckOutgoingMessages();
|
|
retryStuckIncomingMessages();
|
|
}
|
|
|
|
public synchronized int getStuckMessageCount() {
|
|
return outgoingMessages.size() + incomingMessages.size();
|
|
}
|
|
|
|
public synchronized void retryStuckOutgoingMessages() {
|
|
for (OutgoingMessage sms : outgoingMessages.values()) {
|
|
sms.retryNow();
|
|
}
|
|
}
|
|
|
|
public synchronized void retryStuckIncomingMessages() {
|
|
for (IncomingMessage sms : incomingMessages.values()) {
|
|
sms.retryNow();
|
|
}
|
|
}
|
|
|
|
public synchronized void setIncomingMessageStatus(IncomingMessage message, boolean success) {
|
|
Uri uri = message.getUri();
|
|
if (success)
|
|
{
|
|
incomingMessages.remove(uri);
|
|
|
|
if (message instanceof IncomingMms)
|
|
{
|
|
IncomingMms mms = (IncomingMms)message;
|
|
if (!getKeepInInbox())
|
|
{
|
|
log("Deleting MMS " + mms.getId() + " from inbox...");
|
|
mmsUtils.deleteFromInbox(mms);
|
|
}
|
|
}
|
|
}
|
|
else if (!message.scheduleRetry())
|
|
{
|
|
incomingMessages.remove(uri);
|
|
}
|
|
}
|
|
|
|
public synchronized void notifyOutgoingMessageStatus(Uri uri, int resultCode) {
|
|
OutgoingMessage sms = outgoingMessages.get(uri);
|
|
|
|
if (sms == null) {
|
|
return;
|
|
}
|
|
|
|
switch (resultCode) {
|
|
case Activity.RESULT_OK:
|
|
this.notifyStatus(sms, App.STATUS_SENT, "");
|
|
break;
|
|
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
|
|
this.notifyStatus(sms, App.STATUS_FAILED, "generic failure");
|
|
break;
|
|
case SmsManager.RESULT_ERROR_RADIO_OFF:
|
|
this.notifyStatus(sms, App.STATUS_FAILED, "radio off");
|
|
break;
|
|
case SmsManager.RESULT_ERROR_NO_SERVICE:
|
|
this.notifyStatus(sms, App.STATUS_FAILED, "no service");
|
|
break;
|
|
case SmsManager.RESULT_ERROR_NULL_PDU:
|
|
this.notifyStatus(sms, App.STATUS_FAILED, "null PDU");
|
|
break;
|
|
default:
|
|
this.notifyStatus(sms, App.STATUS_FAILED, "unknown error");
|
|
break;
|
|
}
|
|
|
|
switch (resultCode) {
|
|
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
|
|
case SmsManager.RESULT_ERROR_RADIO_OFF:
|
|
case SmsManager.RESULT_ERROR_NO_SERVICE:
|
|
if (!sms.scheduleRetry()) {
|
|
outgoingMessages.remove(uri);
|
|
}
|
|
break;
|
|
default:
|
|
outgoingMessages.remove(uri);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public synchronized void sendOutgoingMessage(OutgoingMessage sms) {
|
|
|
|
if (isTestMode() && !isTestPhoneNumber(sms.getTo()))
|
|
{
|
|
// this is mostly to prevent accidentally sending real messages to
|
|
// random people while testing...
|
|
|
|
log("Ignoring outgoing SMS to " + sms.getTo());
|
|
return;
|
|
}
|
|
|
|
Uri uri = sms.getUri();
|
|
if (outgoingMessages.containsKey(uri)) {
|
|
log("Duplicate outgoing " + sms.getLogName() + ", skipping");
|
|
return;
|
|
}
|
|
|
|
outgoingMessages.put(uri, sms);
|
|
|
|
log("Sending " + sms.getLogName() + " to " + sms.getTo());
|
|
sms.trySend();
|
|
}
|
|
|
|
public synchronized void forwardToServer(IncomingMessage message) {
|
|
Uri uri = message.getUri();
|
|
|
|
if (incomingMessages.containsKey(uri)) {
|
|
log("Duplicate incoming "+message.getDisplayType()+", skipping");
|
|
return;
|
|
}
|
|
|
|
incomingMessages.put(uri, message);
|
|
|
|
log("Received "+message.getDisplayType()+" from " + message.getFrom());
|
|
|
|
message.tryForwardToServer();
|
|
}
|
|
|
|
public synchronized void retryIncomingMessage(Uri uri) {
|
|
IncomingMessage message = incomingMessages.get(uri);
|
|
if (message != null) {
|
|
message.retryNow();
|
|
}
|
|
}
|
|
|
|
public synchronized void retryOutgoingMessage(Uri uri) {
|
|
OutgoingMessage sms = outgoingMessages.get(uri);
|
|
if (sms != null) {
|
|
sms.retryNow();
|
|
}
|
|
}
|
|
|
|
public void debug(String msg) {
|
|
Log.d(LOG_NAME, msg);
|
|
}
|
|
|
|
public synchronized void log(CharSequence msg)
|
|
{
|
|
Log.d(LOG_NAME, msg.toString());
|
|
|
|
// prevent displayed log from growing too big
|
|
int length = displayedLog.length();
|
|
if (length > MAX_DISPLAYED_LOG)
|
|
{
|
|
int startPos = length - MAX_DISPLAYED_LOG * 3 / 4;
|
|
|
|
for (int cur = startPos; cur < startPos + 100 && cur < length; cur++)
|
|
{
|
|
if (displayedLog.charAt(cur) == '\n')
|
|
{
|
|
startPos = cur;
|
|
break;
|
|
}
|
|
}
|
|
|
|
displayedLog.replace(0, startPos, "[Older log messages not shown]\n");
|
|
}
|
|
|
|
// display a timestamp in the log occasionally
|
|
long logTime = SystemClock.elapsedRealtime();
|
|
if (logTime - lastLogTime > LOG_TIMESTAMP_INTERVAL)
|
|
{
|
|
Date date = new Date();
|
|
displayedLog.append("[" + DateFormat.getTimeInstance().format(date) + "]\n");
|
|
lastLogTime = logTime;
|
|
}
|
|
|
|
displayedLog.append(msg);
|
|
displayedLog.append("\n");
|
|
|
|
Intent broadcast = new Intent(App.LOG_INTENT);
|
|
sendBroadcast(broadcast);
|
|
}
|
|
|
|
public synchronized CharSequence getDisplayedLog()
|
|
{
|
|
return displayedLog;
|
|
}
|
|
|
|
public void logError(Throwable ex) {
|
|
logError("ERROR", ex);
|
|
}
|
|
|
|
public void logError(String msg, Throwable ex) {
|
|
logError(msg, ex, false);
|
|
}
|
|
|
|
public void logError(String msg, Throwable ex, boolean detail) {
|
|
log(msg + ": " + ex.getClass().getName() + ": " + ex.getMessage());
|
|
|
|
if (detail) {
|
|
for (StackTraceElement elem : ex.getStackTrace()) {
|
|
log(elem.getClassName() + ":" + elem.getMethodName() + ":" + elem.getLineNumber());
|
|
}
|
|
Throwable innerEx = ex.getCause();
|
|
if (innerEx != null) {
|
|
logError("Inner exception:", innerEx, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public MmsUtils getMmsUtils()
|
|
{
|
|
return mmsUtils;
|
|
}
|
|
|
|
private List<String> testPhoneNumbers;
|
|
|
|
public List<String> getTestPhoneNumbers()
|
|
{
|
|
if (testPhoneNumbers == null)
|
|
{
|
|
testPhoneNumbers = new ArrayList<String>();
|
|
String phoneNumbersJson = settings.getString("test_phone_numbers", "");
|
|
|
|
if (phoneNumbersJson.length() > 0)
|
|
{
|
|
try
|
|
{
|
|
JSONArray arr = new JSONArray(phoneNumbersJson);
|
|
int numSenders = arr.length();
|
|
for (int i = 0; i < numSenders; i++)
|
|
{
|
|
testPhoneNumbers.add(arr.getString(i));
|
|
}
|
|
}
|
|
catch (JSONException ex)
|
|
{
|
|
logError("Error parsing test phone numbers", ex);
|
|
}
|
|
}
|
|
}
|
|
return testPhoneNumbers;
|
|
}
|
|
|
|
public void addTestPhoneNumber(String phoneNumber)
|
|
{
|
|
List<String> phoneNumbers = getTestPhoneNumbers();
|
|
log("Added test phone number: " + phoneNumber);
|
|
phoneNumbers.add(phoneNumber);
|
|
saveTestPhoneNumbers(phoneNumbers);
|
|
}
|
|
|
|
public void removeTestPhoneNumber(String phoneNumber)
|
|
{
|
|
List<String> phoneNumbers = getTestPhoneNumbers();
|
|
phoneNumbers.remove(phoneNumber);
|
|
log("Removed test phone number: " + phoneNumber);
|
|
saveTestPhoneNumbers(phoneNumbers);
|
|
}
|
|
|
|
private void saveTestPhoneNumbers(List<String> phoneNumbers)
|
|
{
|
|
settings.edit().putString("test_phone_numbers",
|
|
new JSONArray(phoneNumbers).toString()
|
|
).commit();
|
|
}
|
|
|
|
public boolean isTestPhoneNumber(String phoneNumber)
|
|
{
|
|
for (String testNumber : getTestPhoneNumbers())
|
|
{
|
|
// handle inexactness due to various different ways of formatting numbers
|
|
if (testNumber.contains(phoneNumber) || phoneNumber.contains(testNumber))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private HttpClient httpClient;
|
|
|
|
public synchronized HttpClient getHttpClient()
|
|
{
|
|
if (httpClient == null)
|
|
{
|
|
// via http://thinkandroid.wordpress.com/2009/12/31/creating-an-http-client-example/
|
|
// also http://hc.apache.org/httpclient-3.x/threading.html
|
|
|
|
HttpParams httpParams = new BasicHttpParams();
|
|
HttpConnectionParams.setConnectionTimeout(httpParams, 8000);
|
|
HttpConnectionParams.setSoTimeout(httpParams, 8000);
|
|
HttpProtocolParams.setContentCharset(httpParams, "utf-8");
|
|
|
|
SchemeRegistry registry = new SchemeRegistry();
|
|
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
|
|
|
|
final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
|
|
sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
|
|
|
|
registry.register(new Scheme("https", sslSocketFactory, 443));
|
|
|
|
ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(httpParams, registry);
|
|
|
|
httpClient = new DefaultHttpClient(manager, httpParams);
|
|
}
|
|
return httpClient;
|
|
}
|
|
}
|